Reputation: 2368
When returning Json from a controller (MVC 4 RC) I would like to modify the Json to use camel-casing for the properties and to do this I tried setting the GlobalConfiguration.Formatters.JsonFormatter (not sure if this is correct...don't have the code in front of me), but this does not appear to affect the Json outputted by the Controller.Json method.
After looking around it appears that this approach would only affect Web API controllers, etc. Is this true? Also, is it possible to alter the Controller.Json() method to acheive this?
Upvotes: 5
Views: 2735
Reputation: 15890
Like @rouen suggests, created your own JsonDotNetResult.
This is the one I have in my project:
public class JsonNetResult : ActionResult
{
public Encoding ContentEncoding { get; set; }
public string ContentType { get; set; }
public object Data { get; set; }
public int StatusCode { get; set; }
public JsonSerializerSettings SerializerSettings { get; set; }
public JsonNetResult()
{
SerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
var response = context.HttpContext.Response;
response.StatusCode = StatusCode;
response.ContentType = string.IsNullOrEmpty(ContentType) ? "application/json" : ContentType;
if ((StatusCode >= 400) && (StatusCode <= 599))
response.TrySkipIisCustomErrors = true;
if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
if (Data == null)
return;
var formatting = Formatting.None;
#if DEBUG
formatting = Formatting.Indented;
#endif
var writer = new JsonTextWriter(response.Output) { Formatting = formatting };
var serializer = JsonSerializer.Create(SerializerSettings);
serializer.Serialize(writer, Data);
writer.Flush();
}
}
I then have my own baseController that I inherit from to give me JsonDotNet(object viewModel) type methods.
E.g.
protected JsonNetResult JsonNet(object data = null, int statusCode = (int)HttpStatusCode.OK, string contentType = null)
{
return new JsonNetResult
{
Data = data,
StatusCode = statusCode,
ContentType = contentType
};
}
protected JsonNetResult JsonNetForbidden()
{
return JsonNet(statusCode: (int)HttpStatusCode.Forbidden);
}
protected JsonNetResult JsonNetNotFound()
{
return JsonNet(statusCode: (int)HttpStatusCode.NotFound);
}
protected JsonNetResult JsonNetNoContent()
{
return JsonNet(statusCode: (int)HttpStatusCode.NoContent);
}
protected JsonNetResult JsonNetCreated(object data)
{
return JsonNet(data, (int)HttpStatusCode.Created);
}
protected JsonNetResult JsonNetReload()
{
return JsonNet(new { reload = true });
}
protected JsonNetResult JsonNetRedirect(string url = null, string contentType = null)
{
return JsonNet(new { redirectUrl = url }, contentType: contentType);
}
protected JsonNetResult JsonNetClientError(ErrorDictionary errors)
{
return JsonNet(new { Errors = errors }, (int)HttpStatusCode.BadRequest);
}
protected JsonNetResult JsonNetUnauthorized()
{
return JsonNet(null, (int)HttpStatusCode.Unauthorized);
}
protected JsonNetResult JsonNetFlashMessage(string message)
{
return JsonNet(new { flashMessage = message });
}
Upvotes: 7
Reputation: 5134
There is no way to alter behaviour of default JavaScriptSerializer afaik.
Personally, I use my own JsonDotNetResult (and shortcut method on my BaseController) for all json actions. Not only you can alter its settings in many ways, but the performance is MUCH better with JSON.NET - look here http://james.newtonking.com/archive/2008/10/27/json-net-3-5-beta-1-big-performance-improvements-compact-framework-support-and-more.aspx
Plus there are many little nice bonuses, like automatic resoulution of circular dependencies (always hit it in bigger projects) etc.
Invest your 5 minutes into own JsonDotNetResult, they will be very well spent.
Upvotes: 2
Reputation: 5832
According to asp.net MVC 3 sources (I don't have ones for the fourth version at hand, but it is very unlikely something was changed there) you can't do that.
Controller.Json
uses new JsonResult
, and JsonResult.ExecuteResult
uses new JavaScriptSerializer
directly.
Some time ago we were looking for some way to affect this behavior but found none.
Upvotes: 0