Anri
Anri

Reputation: 6265

Custom JSON Result in ASP.NET MVC

I created custom ActionResult (simplified):

public class FastJSONResult : ActionResult
{
    public string JsonData { get; private set; }

    public FastJSONResult(object data)
    {
        JsonData = JSON.Instance.ToJSON(data);
    }

    public override void ExecuteResult(ControllerContext context)
    {
        HttpResponseBase response = context.HttpContext.Response;
        response.ContentType = "application/json";
        response.Output.Write(JsonData);
    }
}

And use it from my WebApi controller:

public ActionResult GetReport()
{
   var report = new Report();
   return new FastJSONResult(report);
}

Now the problem is, despite the fact that in FastJSONResult constructor my object serializes perfectly, ExecuteResult never gets called and in response I end up with object like

{"JsonData":"{my json object as a string value}"}

What am I doing wrong?

Upvotes: 2

Views: 5690

Answers (1)

Anri
Anri

Reputation: 6265

Solved it with custom formatter (simplified to post less code)

public class FastJsonFormatter : MediaTypeFormatter
{
  private static JSONParameters _parameters = new JSONParameters()
  {
    public FastJsonFormatter()
    {
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
      SupportedEncodings.Add(new UTF8Encoding(false, true));
    }

    public override bool CanReadType(Type type)
    {
      return true;
    }

    public override bool CanWriteType(Type type)
    {
      return true;
    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        var task = Task<object>.Factory.StartNew(() => JSON.Instance.ToObject(new StreamReader(readStream).ReadToEnd(), type));
        return task;
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
      var task = Task.Factory.StartNew(() =>
      {
         var json = JSON.Instance.ToJSON(value, _parameters);
         using (var w = new StreamWriter(writeStream)) w.Write(json);  
      });
      return task;
    }
}

In WebApiConfig.Register method:

config.Formatters.Remove(config.Formatters.JsonFormatter);
config.Formatters.Add(new FastJsonFormatter());

And now I receive json object properly: Sample

Upvotes: 1

Related Questions