Skip to content

Commit

Permalink
SerializedView now handles the serialization instead of Serialization…
Browse files Browse the repository at this point in the history
…Result, this makes it a little more useful when combined with a standard ViewResult
  • Loading branch information
Nick Berardi committed Apr 30, 2010
1 parent aab8bba commit 84704be
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 197 deletions.
1 change: 1 addition & 0 deletions Source/ManagedFusion.Web.csproj
Expand Up @@ -67,6 +67,7 @@
<Compile Include="If.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Switch.cs" />
<Compile Include="Web\Mvc\AutoSerializedView.cs" />
<Compile Include="Web\Extensions\HttpResponse.cs" />
<Compile Include="Web\HeaderQValue.cs" />
<Compile Include="Web\HeaderQValueList.cs" />
Expand Down
12 changes: 12 additions & 0 deletions Source/Web/Mvc/AutoSerializedView.cs
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ManagedFusion.Web.Mvc;

namespace ManagedFusion.Web.Mvc
{
public class AutoSerializedView : SerializedView
{
}
}
2 changes: 1 addition & 1 deletion Source/Web/Mvc/CsvResult.cs
Expand Up @@ -6,7 +6,7 @@

namespace ManagedFusion.Web.Mvc
{
public class CsvResult : SerializedResult
public class CsvResult : SerializedView
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonResult"/> class.
Expand Down
8 changes: 4 additions & 4 deletions Source/Web/Mvc/ISerializableActionResult.cs
Expand Up @@ -9,14 +9,14 @@ namespace ManagedFusion.Web.Mvc
public interface ISerializableActionResult
{
object Model { get; }

int StatusCode { get; set; }

string StatusDescription { get; set; }
}

public interface ISerializableErrorResult : ISerializableActionResult
{
string Error { get; set; }

int StatusCode { get; set; }

string StatusDescription { get; set; }
}
}
12 changes: 7 additions & 5 deletions Source/Web/Mvc/JavaScriptCallbackResult.cs
Expand Up @@ -5,6 +5,7 @@
using System.Web.Mvc;

using ManagedFusion.Serialization;
using System.IO;

namespace ManagedFusion.Web.Mvc
{
Expand Down Expand Up @@ -50,17 +51,18 @@ protected internal override string GetContent()
}

/// <summary>
/// Executes the result.
///
/// </summary>
/// <param name="context">The context.</param>
public override void ExecuteResult(ControllerContext context)
/// <param name="viewContext"></param>
/// <param name="writer"></param>
public override void Render(ViewContext viewContext, TextWriter writer)
{
Callback = context.HttpContext.Request.QueryString["callback"];
Callback = viewContext.HttpContext.Request.QueryString["callback"];

if (String.IsNullOrEmpty(Callback))
Callback = "callback";

base.ExecuteResult(context);
base.Render(viewContext, writer);
}
}
}
2 changes: 1 addition & 1 deletion Source/Web/Mvc/JsonResult.cs
Expand Up @@ -8,7 +8,7 @@

namespace ManagedFusion.Web.Mvc
{
public class JsonResult : SerializedResult
public class JsonResult : SerializedView
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonResult"/> class.
Expand Down
228 changes: 116 additions & 112 deletions Source/Web/Mvc/SerializedResult.cs
Expand Up @@ -15,125 +15,111 @@ namespace ManagedFusion.Web.Mvc
/// <summary>
///
/// </summary>
public abstract class SerializedResult : ActionResult, IView
public class SerializedResult : ActionResult, ISerializableActionResult
{
public SerializedResult(object model)
: this(model, new AutoSerializedView()) { }

/// <summary>
/// Initializes a new instance of the <see cref="ServiceResult"/> class.
/// </summary>
public SerializedResult()
public SerializedResult(object model, SerializedView view)
: this()
{
ContentEncoding = Encoding.UTF8;
ContentType = "text/xml";

SerializePublicMembers = true;
FollowFrameworkIgnoreAttributes = true;
ModelSerializer = view;
Model = model;
}

SerializedHeader = new Dictionary<string, object>();
protected SerializedResult()
{
StatusCode = 200;
StatusDescription = "OK";
}

/// <summary>
/// Gets or sets the content encoding.
/// Gets or sets the model serializer.
/// </summary>
/// <value>The content encoding.</value>
public Encoding ContentEncoding
public virtual SerializedView ModelSerializer
{
get;
set;
private set;
}

/// <summary>
/// Gets or sets the type of the content.
/// Gets or sets the data.
/// </summary>
/// <value>The type of the content.</value>
public string ContentType
/// <value>The data.</value>
public virtual object Model
{
get;
set;
private set;
}

/// <summary>
/// Gets or sets a value indicating whether [serialize public members].
///
/// </summary>
/// <value>
/// <see langword="true"/> if [serialize public members]; otherwise, <see langword="false"/>.
/// </value>
public bool SerializePublicMembers
{
get;
set;
}
public int StatusCode { get; set; }

/// <summary>
///
/// </summary>
public bool FollowFrameworkIgnoreAttributes
{
get;
set;
}
public string StatusDescription { get; set; }

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

return type;
}

/// <summary>
/// Builds the response.
/// Called when [action executing].
/// </summary>
/// <param name="content">The content.</param>
/// <returns></returns>
protected IDictionary<string, object> BuildResponse(object serializableObject, IDictionary<string, object> serializedContent)
/// <param name="filterContext">The filter context.</param>
public static ResponseType GetResponseType(ControllerContext filterContext)
{
// create body of the response
IDictionary<string, object> response = new Dictionary<string, object>();
response.Add("timestamp", DateTime.UtcNow);
string type = NormalizeType(filterContext.HttpContext.Request.QueryString["type"]);
ResponseType responseType = ResponseType.Html;

// add serialization headers to the response
foreach (var header in SerializedHeader)
response.Add(header.Key, header.Value);
// check to see if we should try to parse it to an enum
if (!String.IsNullOrEmpty(type))
responseType = ManagedFusion.Utility.ParseEnum<ResponseType>(type);

// check for regular collection
if (serializableObject is ICollection)
// if the response type is still the default HTML check the Accept header
// if the requestion is an XMLHttpRequest
if (responseType == ResponseType.Html && filterContext.HttpContext.Request.AcceptTypes != null)
{
response.Add("count", ((ICollection)serializableObject).Count);
foreach (string accept in filterContext.HttpContext.Request.AcceptTypes)
{
switch (accept.ToLower())
{
case "application/json":
case "application/x-json": responseType = ResponseType.Json; break;

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);
case "application/javascript":
case "application/x-javascript":
case "text/javascript": responseType = ResponseType.JavaScript; break;

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

/// <summary>
/// Gets the content.
/// </summary>
protected internal abstract string GetContent();
case "text/csv": responseType = ResponseType.Csv; break;
}

/// <summary>
///
/// </summary>
protected internal abstract string ContentFileExtension { get; }
if (responseType != ResponseType.Html)
break;
}
}

/// <summary>
/// Gets or sets the data.
/// </summary>
/// <value>The data.</value>
public object Model
{
get;
set;
return responseType;
}

/// <summary>
Expand All @@ -142,56 +128,74 @@ public object Model
/// <param name="context">The context.</param>
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (ModelSerializer == null || ModelSerializer is AutoSerializedView)
UpdateModelSerializer(context);

string action = context.RouteData.GetRequiredString("action");
HttpRequestBase request = context.HttpContext.Request;
HttpResponseBase response = context.HttpContext.Response;
response.ClearHeaders();
response.ClearContent();

if (!String.IsNullOrEmpty(ContentType))
response.ContentType = ContentType;
WriteResponse(context);
}

if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
/// <summary>
///
/// </summary>
/// <param name="context"></param>
private void UpdateModelSerializer(ControllerContext context)
{
SerializedView view = ModelSerializer as SerializedView;

response.Cache.SetExpires(DateTime.Today.AddDays(-1D));
response.AppendHeader("X-Robots-Tag", "noindex, follow, noarchive, nosnippet");
response.AppendHeader("Content-Disposition", String.Format("inline; filename={0}.{1}; creation-date={2:r}", action, ContentFileExtension, DateTime.UtcNow));
if (view == null)
view = new AutoSerializedView();

if (!request.IsSecureConnection)
switch (GetResponseType(context))
{
response.Cache.SetCacheability(HttpCacheability.NoCache);
response.AppendHeader("Pragma", "no-cache");
response.AppendHeader("Cache-Control", "private, no-cache, must-revalidate, no-store, pre-check=0, post-check=0, max-stale=0");
case ResponseType.JavaScript:
ModelSerializer = new JavaScriptCallbackResult();
break;

case ResponseType.Json:
ModelSerializer = new JsonResult();
break;

case ResponseType.Xml:
ModelSerializer = new XmlResult();
break;

case ResponseType.Csv:
ModelSerializer = new CsvResult();
break;

case ResponseType.Html:
default:
break;
}

if (Model != null)
if (ModelSerializer is SerializedView && view != null)
{
string content = GetContent();
var resultX = (ModelSerializer as SerializedView);

if (content != null)
{
response.AppendHeader("Content-Length", content.Length.ToString());
response.Write(content);
}
}
resultX.FollowFrameworkIgnoreAttributes = view.FollowFrameworkIgnoreAttributes;
resultX.SerializePublicMembers = view.SerializePublicMembers;

response.End();
foreach (var header in view.SerializedHeader)
resultX.SerializedHeader.Add(header.Key, header.Value);
}
}

#region IView Members

public void Render(ViewContext viewContext, TextWriter writer)
/// <summary>
///
/// </summary>
/// <param name="context"></param>
private void WriteResponse(ControllerContext context)
{
Model = viewContext.ViewData.Model;
ExecuteResult(viewContext);
}
if (context == null)
throw new ArgumentNullException("context");

HttpResponseBase response = context.HttpContext.Response;

ModelSerializer.StatusCode = StatusCode;
ModelSerializer.StatusDescription = StatusDescription;

#endregion
if (Model != null)
ModelSerializer.Render(new ViewContext(context, ModelSerializer, new ViewDataDictionary(Model), new TempDataDictionary(), response.Output), response.Output);
}
}
}

0 comments on commit 84704be

Please sign in to comment.