Initial support for JsonResult + Action result mutation from object to Json

This commit is contained in:
Yishai Galatzer 2014-02-03 19:54:14 -08:00
parent c91a814ffa
commit 4b4034788c
4 changed files with 168 additions and 6 deletions

View File

@ -1,10 +1,13 @@
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Mvc;
using System.Text;
namespace MvcSample
{
public class Home2Controller
{
private User _user = new User() { Name = "User Name", Address = "Home Address" };
public Home2Controller(IActionResultHelper actionResultHelper)
{
Result = actionResultHelper;
@ -36,5 +39,18 @@ namespace MvcSample
{
Context.Response.WriteAsync("Hello World raw");
}
public IActionResult UserJson()
{
return new JsonResult(new User() { Name = "User Name", Address = "Home Address" })
{
Encoding = Encoding.UTF8
};
}
public User User()
{
return _user;
}
}
}

View File

@ -6,11 +6,46 @@ namespace Microsoft.AspNet.Mvc
{
public IActionResult CreateActionResult(Type declaredReturnType, object actionReturnValue, RequestContext requestContext)
{
return new ContentResult
// optimize common path
IActionResult actionResult = actionReturnValue as IActionResult;
if (actionResult != null)
{
ContentType = "text/plain",
Content = Convert.ToString(actionReturnValue),
};
return actionResult;
}
if (declaredReturnType == null)
{
throw new InvalidOperationException("Declared type must be passed");
}
if (typeof(IActionResult).IsAssignableFrom(declaredReturnType) && actionReturnValue == null)
{
throw new InvalidOperationException("Cannot return null from an action method declaring IActionResult or HttpResponseMessage");
}
if (declaredReturnType.IsGenericParameter)
{
// This can happen if somebody declares an action method as:
// public T Get<T>() { }
throw new InvalidOperationException("HttpActionDescriptor_NoConverterForGenericParamterTypeExists");
}
if (declaredReturnType.IsAssignableFrom(typeof(void)))
{
return new NoContentResult();
}
if (actionReturnValue is string)
{
return new ContentResult
{
ContentType = "text/plain",
Content = (string)actionReturnValue,
};
}
return new JsonResult(actionReturnValue);
}
}
}

View File

@ -0,0 +1,112 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Newtonsoft.Json;
namespace Microsoft.AspNet.Mvc
{
public class JsonResult : IActionResult
{
private readonly object _returnValue;
private JsonSerializerSettings _jsonSerializerSettings;
private Encoding _encoding;
public JsonResult(object returnValue)
{
if (returnValue == null)
{
throw new ArgumentNullException("returnValue");
}
Encoding = Encoding.UTF8;
_returnValue = returnValue;
}
public JsonSerializerSettings SerializerSettings
{
get { return _jsonSerializerSettings; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
_jsonSerializerSettings = value;
}
}
/// <summary>
/// Gets or sets a value indicating whether to indent elements when writing data.
/// </summary>
public bool Indent { get; set; }
public Encoding Encoding
{
get { return _encoding; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
_encoding = value;
}
}
public virtual JsonSerializerSettings CreateSerializerSettings()
{
return new JsonSerializerSettings()
{
MissingMemberHandling = MissingMemberHandling.Ignore,
// Do not change this setting
// Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types.
TypeNameHandling = TypeNameHandling.None
};
}
public virtual JsonSerializer CreateJsonSerializer()
{
JsonSerializer jsonSerializer = JsonSerializer.Create(SerializerSettings);
return jsonSerializer;
}
public virtual JsonWriter CreateJsonWriter(Stream writeStream, Encoding effectiveEncoding)
{
JsonWriter jsonWriter = new JsonTextWriter(new StreamWriter(writeStream, effectiveEncoding));
if (Indent)
{
jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented;
}
return jsonWriter;
}
public async Task ExecuteResultAsync(RequestContext context)
{
HttpResponse response = context.HttpContext.Response;
Stream writeStream = response.Body;
response.ContentType = "application/json";
using (JsonWriter jsonWriter = CreateJsonWriter(writeStream, Encoding))
{
jsonWriter.CloseOutput = false;
JsonSerializer jsonSerializer = CreateJsonSerializer();
jsonSerializer.Serialize(jsonWriter, _returnValue);
jsonWriter.Flush();
}
}
}
}

View File

@ -47,8 +47,7 @@ namespace Microsoft.AspNet.Mvc
object actionReturnValue = method.Invoke(controller, null);
// If it's not already an IActionResult then call into the factory
var actionResult = actionReturnValue as IActionResult ?? _actionResultFactory.CreateActionResult(method.ReturnType, actionReturnValue, _requestContext);
var actionResult = _actionResultFactory.CreateActionResult(method.ReturnType, actionReturnValue, _requestContext);
return actionResult.ExecuteResultAsync(_requestContext);
}