0

For various reasons, I have switched from ASP.NET MVC's built in JSON serializer (the one that returns a System.Web.Mvc.JsonResult object (see edit below)) to Newtonsoft. I didn't realize until after I began testing that the former returns a JavaScript object literal, while Newtonsoft returns a JSON formatted string.

I like not having to parse JSON strings on the client side — having it already as an object literal is very convenient — but I want to stick with Newtonsoft for other technical reasons.

For example, instead of seeing this result on my client...

"{"Errors":["Please enter a valid email address."],"HasErrors":true}"

...I'd like to see this result:

{"Errors":["Please enter a valid email address."],"HasErrors":true} // no quotes

Is there a way to make Newtonsoft return JS object literals instead of strings?

EDIT

The way my question was framed wasn't the best. There's nothing wrong with the JsonResult type. In fact, the solution still uses it. The only problem was the default Controller.Json methods, which can be overridden to use Newtonsoft (Json.NET) instead of the built-in serializer.

7
  • I'm not that familiar with the .NET world - is Newtonsoft on the server? Because if so, you should never be able to return a JS literal at from the server. Not in a network request, anyway. Or is that embedded somewhere in the page when it renders? Commented Sep 20, 2016 at 23:32
  • Can't you edit your JS file with a JSON.Parse(response) ? Commented Sep 20, 2016 at 23:39
  • 1
    How are you creating your JSON responses and returning them from MVC using Json.Net? Commented Sep 20, 2016 at 23:43
  • @vlaz Yes, Newtonsoft is a small framework for .NET that handles everything "JSON". It sure seems like they're coming over as JS literals -- they even have a MIME type of application/json. But the way it's currently doing it with Newtonsoft, they're coming over as JSON strings with a MIME type of text/html. Commented Sep 20, 2016 at 23:48
  • 1
    Can you share the code you are using to plug in Json.NET? Is it similar to Using JSON.NET to return ActionResult or Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible?? Json.NET doesn't serialize objects by surrounding them with quotes so likely something is going wrong with how Json.NET is being plugged in. Commented Sep 21, 2016 at 0:13

2 Answers 2

1

Just write a custom JsonResult that uses Newtonsoft serializer:

Something along the lines:

public abstract class BaseController : Controller
{
    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding)
    {
        return new JsonNetResult
        {
            ContentType = contentType,
            ContentEncoding = contentEncoding,
            Data = data
        };
    }

    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new JsonNetResult
                    {
                        ContentType = contentType,
                        ContentEncoding = contentEncoding,
                        Data = data,
                        JsonRequestBehavior = behavior
                    };
    }
}

JsonNetResult.cs:

using System;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;

public class JsonNetResult : JsonResult
{   
    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public JsonNetResult()
    {
        Formatting = Formatting.None;
        SerializerSettings = new JsonSerializerSettings();
        JsonRequestBehavior = JsonRequestBehavior.DenyGet;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet
            && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(ContentType)
                                    ? ContentType
                                    : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        if (Data != null)
        {
            var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };

            var serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Data);

            writer.Flush();
        }
    }
}

Credit: https://gist.github.com/jpoehls/1424538

Sign up to request clarification or add additional context in comments.

1 Comment

This is perfect! I ended up implementing an even simpler version of this by using response.Write(JsonConvert.SerializeObject(this.Data)) instead of the JsonTextWriter and JsonSerializer. I'll never need to use any special JsonSerializerSettings or Formatting, and working with writers always strikes me as overly complicated.
0

Answer is here: How to force ASP.NET Web API to always return JSON?

Excerpt:

Clear all formatters and add Json formatter back.

GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter()); EDIT

I added it to Global.asax inside Application_Start().

1 Comment

I am not using Web API. The endpoints on my controller include ViewResults, Json strings, and file results as well, so I don't think this would work for me.

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.