5

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?

3 Answers 3

7

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 });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Hi Charlino. Sorry for the late reply. I like the idea you've suggested and how it fits into the MVC framework. I will try it, hopefully over the weekend, and see how it works.
2

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.

1 Comment

+1 this is exactly what I do. I also find it handy for indenting when in debug.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.