Skip to content

Commit

Permalink
made some changes to the service serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Berardi committed Oct 12, 2010
1 parent 0169968 commit 024183c
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 113 deletions.
2 changes: 2 additions & 0 deletions Source/ManagedFusion.Web.csproj
Expand Up @@ -122,6 +122,7 @@
<Compile Include="Web\Mvc\HttpGetOnlyAttribute.cs" />
<Compile Include="Web\Mvc\HttpPostOnlyAttribute.cs" />
<Compile Include="Web\Mvc\ISerializableActionResult.cs" />
<Compile Include="Web\Mvc\ISerializableExceptionResult.cs" />
<Compile Include="Web\Mvc\JavaScriptCallbackResult.cs" />
<Compile Include="Web\Mvc\JsonResult.cs" />
<Compile Include="Web\Mvc\LowercaseRoute.cs" />
Expand All @@ -131,6 +132,7 @@
<Compile Include="Web\Mvc\SerializedResult.cs" />
<Compile Include="Web\Mvc\SerializedView.cs" />
<Compile Include="Web\Mvc\ServiceAttribute.cs" />
<Compile Include="Web\Mvc\ServiceHelper.cs" />
<Compile Include="Web\Mvc\ServiceOnlyAttribute.cs" />
<Compile Include="Web\Mvc\UnsupportedMediaTypeResult.cs" />
<Compile Include="Web\Mvc\XmlResult.cs" />
Expand Down
3 changes: 0 additions & 3 deletions Source/Web/Mvc/AutoSerializedView.cs
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ManagedFusion.Web.Mvc;

namespace ManagedFusion.Web.Mvc
Expand Down
11 changes: 1 addition & 10 deletions Source/Web/Mvc/ISerializableActionResult.cs
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace ManagedFusion.Web.Mvc
{
Expand All @@ -14,9 +10,4 @@ public interface ISerializableActionResult

string StatusDescription { get; set; }
}

public interface ISerializableErrorResult : ISerializableActionResult
{
string Error { get; set; }
}
}
}
11 changes: 11 additions & 0 deletions Source/Web/Mvc/ISerializableExceptionResult.cs
@@ -0,0 +1,11 @@
using System;

namespace ManagedFusion.Web.Mvc
{
public interface ISerializableExceptionResult : ISerializableActionResult
{
string ExceptionMessage { get; set; }

Exception Exception { get; set; }
}
}
88 changes: 12 additions & 76 deletions Source/Web/Mvc/SerializedResult.cs
Expand Up @@ -65,80 +65,6 @@ public virtual object Model
/// </summary>
public string StatusDescription { get; set; }

/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static string NormalizeType(string type)
{
if (String.Equals(type, "javascript", StringComparison.InvariantCultureIgnoreCase))
return "javascript";
else if (String.Equals(type, "jsonp", StringComparison.InvariantCultureIgnoreCase))
return "javascript";

return type;
}

/// <summary>
/// Called when [action executing].
/// </summary>
/// <param name="filterContext">The filter context.</param>
public static ResponseType GetResponseType(ControllerContext filterContext)
{
string type = NormalizeType(filterContext.HttpContext.Request.QueryString["type"]);
ResponseType responseType = ResponseType.None;

// check to see if we should try to parse it to an enum
responseType = ManagedFusion.Utility.ParseEnum<ResponseType>(type);

var acceptTypes = filterContext.HttpContext.Request.AcceptTypes;

if (responseType == ResponseType.None && filterContext.HttpContext.Request.AcceptTypes != null)
{
if (acceptTypes.Any(x => x.StartsWith("text/html") || x.StartsWith("application/xhtml+xml")))
responseType = ResponseType.Html;

if (responseType == ResponseType.None)
{
foreach (string accept in acceptTypes)
{
var value = accept;
var seperatorIndex = value.IndexOf(';');

if (seperatorIndex > -1)
value = value.Substring(0, seperatorIndex);

switch (accept.ToLower())
{
case "application/xhtml+xml":
case "text/html": responseType = ResponseType.Html; break;

case "application/json":
case "application/x-json": responseType = ResponseType.Json; break;

case "application/javascript":
case "application/x-javascript":
case "text/javascript": responseType = ResponseType.JavaScript; break;

case "application/xml":
case "text/xml": responseType = ResponseType.Xml; break;

case "text/csv": responseType = ResponseType.Csv; break;
}

if (responseType != ResponseType.None)
break;
}
}
}

if (responseType == ResponseType.None)
responseType = ResponseType.Html;

return responseType;
}

/// <summary>
/// Executes the result.
/// </summary>
Expand All @@ -157,12 +83,22 @@ public override void ExecuteResult(ControllerContext context)
/// <param name="context"></param>
private void UpdateModelSerializer(ControllerContext context)
{
SerializedView view = ModelSerializer as SerializedView;
ResponseType responseType = ResponseType.None;
var routeData = context.RouteData.Values;

object tempObj;
if (routeData.TryGetValue("responseType", out tempObj) && tempObj is ResponseType)
responseType = (ResponseType)tempObj;

if (responseType == ResponseType.None)
responseType = ServiceHelper.GetResponseType(context);

var view = ModelSerializer as SerializedView;

if (view == null)
view = new AutoSerializedView();

switch (GetResponseType(context))
switch (responseType)
{
case ResponseType.JavaScript:
ModelSerializer = new JavaScriptCallbackResult();
Expand Down
25 changes: 12 additions & 13 deletions Source/Web/Mvc/SerializedView.cs
Expand Up @@ -17,6 +17,7 @@ public SerializedView()
FollowFrameworkIgnoreAttributes = true;

SerializedHeader = new Dictionary<string, object>();
SerializedRootName = null;

StatusCode = 200;
StatusDescription = "OK";
Expand Down Expand Up @@ -81,6 +82,11 @@ protected object Model
private set;
}

/// <summary>
///
/// </summary>
public string SerializedRootName { get; set; }

/// <summary>
///
/// </summary>
Expand Down Expand Up @@ -108,20 +114,14 @@ protected object Model

// check for regular collection
if (serializableObject is ICollection)
{
response.Add("count", ((ICollection)serializableObject).Count);

if (serializedContent.Count > 1)
response.Add("collection", serializedContent);
else
foreach (var value in serializedContent)
response.Add(value.Key, value.Value);
}
else if (serializedContent.Count > 1)
response.Add("object", serializedContent);
else
foreach (var value in serializedContent)
response.Add(value.Key, value.Value);
var rootName = SerializedRootName;

if (String.IsNullOrEmpty(rootName))
rootName = serializableObject is ICollection ? "collection" : "object";

response.Add(rootName, serializedContent);

return response;
}
Expand All @@ -145,7 +145,6 @@ public virtual void Render(ViewContext viewContext, TextWriter writer)
string action = viewContext.RouteData.GetRequiredString("action");
HttpRequestBase request = viewContext.HttpContext.Request;
HttpResponseBase response = viewContext.HttpContext.Response;
response.ClearHeaders();
response.ClearContent();

response.StatusCode = StatusCode;
Expand Down
26 changes: 15 additions & 11 deletions Source/Web/Mvc/ServiceAttribute.cs
Expand Up @@ -19,28 +19,31 @@ public class ServiceAttribute : ActionFilterAttribute
public ServiceAttribute()
{
Order = 0;
ErrorResult = null;
ExceptionResult = null;
DefaultResponseType = ResponseType.Html;
}

private Type _errorResult;
public Type ErrorResult
public ResponseType DefaultResponseType { get; set; }

private Type _exceptionResult;
public Type ExceptionResult
{
get
{
return _errorResult;
return _exceptionResult;
}
set
{
if (value != null && value.GetInterface("ISerializableErrorResult", false) == null)
throw new ArgumentException("ErrorResult must be a type with interface ISerializableActionResult.");
if (value != null && value.GetInterface("ISerializableExceptionResult", false) == null)
throw new ArgumentException("ErrorResult must impliment interface ISerializableExceptionResult.");

_errorResult = value;
_exceptionResult = value;
}
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var responseType = SerializedResult.GetResponseType(filterContext);
var responseType = ServiceHelper.GetResponseType(filterContext, DefaultResponseType);

if (filterContext.RouteData.Values.ContainsKey("responseType"))
filterContext.RouteData.Values.Remove("responseType");
Expand All @@ -55,10 +58,11 @@ public override void OnActionExecuting(ActionExecutingContext filterContext)
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext != null && filterContext.Exception != null && ErrorResult != null)
if (filterContext != null && filterContext.Exception != null && ExceptionResult != null)
{
ISerializableErrorResult result = Activator.CreateInstance(ErrorResult) as ISerializableErrorResult;
result.Error = filterContext.Exception.ToString();
var result = Activator.CreateInstance(ExceptionResult) as ISerializableExceptionResult;
result.ExceptionMessage = filterContext.Exception.Message;
result.Exception = filterContext.Exception;

if (filterContext.Exception is HttpException)
{
Expand Down
85 changes: 85 additions & 0 deletions Source/Web/Mvc/ServiceHelper.cs
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace ManagedFusion.Web.Mvc
{
public static class ServiceHelper
{
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static string NormalizeType(string type)
{
if (String.Equals(type, "javascript", StringComparison.InvariantCultureIgnoreCase))
return "javascript";
else if (String.Equals(type, "jsonp", StringComparison.InvariantCultureIgnoreCase))
return "javascript";

return type;
}

/// <summary>
/// Called when [action executing].
/// </summary>
/// <param name="filterContext">The filter context.</param>
public static ResponseType GetResponseType(ControllerContext filterContext, ResponseType defaultResponseType = ResponseType.Html)
{
string type = NormalizeType(filterContext.HttpContext.Request.QueryString["type"]);
ResponseType responseType = ResponseType.None;

// check to see if we should try to parse it to an enum
responseType = ManagedFusion.Utility.ParseEnum<ResponseType>(type);

var acceptTypes = filterContext.HttpContext.Request.AcceptTypes;

if (responseType == ResponseType.None && filterContext.HttpContext.Request.AcceptTypes != null)
{
if (acceptTypes.Any(x => x.StartsWith("text/html") || x.StartsWith("application/xhtml+xml")))
responseType = ResponseType.Html;

if (responseType == ResponseType.None)
{
foreach (string accept in acceptTypes)
{
var value = accept;
var seperatorIndex = value.IndexOf(';');

if (seperatorIndex > -1)
value = value.Substring(0, seperatorIndex);

switch (accept.ToLower())
{
case "application/xhtml+xml":
case "text/html": responseType = ResponseType.Html; break;

case "application/json":
case "application/x-json": responseType = ResponseType.Json; break;

case "application/javascript":
case "application/x-javascript":
case "text/javascript": responseType = ResponseType.JavaScript; break;

case "application/xml":
case "text/xml": responseType = ResponseType.Xml; break;

case "text/csv": responseType = ResponseType.Csv; break;
}

if (responseType != ResponseType.None)
break;
}
}
}

if (responseType == ResponseType.None)
responseType = defaultResponseType;

return responseType;
}
}
}

0 comments on commit 024183c

Please sign in to comment.