ASP.NET MVC Json DateTime Serialization conversion

2020-02-10 08:55发布

问题:

Using Json() method on ASP.NET MVC Controller is giving me trouble - every DateTime thrown in this method is converted to UTC using server time.

Now, is there an easy way to tell ASP.NET MVC Json Serializer to stop auto-converting DateTime to UTC? As it is noted on this question reasigning each of your variable with DateTime.SpecifyKind(date, DateTimeKind.Utc) does the trick, but obviously I can't do this manually on every DateTime variable.

So is it possible to set something in Web.config and have JSON serializer treat EVERY date as if it's UTC?

回答1:

Dammit, it seems that lately I'm destined to answer my own questions here at StackOverflow. Sigh, here is the solution:

  1. Install ServiceStack.Text using NuGet - you'll get faster JSON serialization for free (you're welcome)
  2. Once ServiceStack.Text is installed, just override Json method in your base Controller (you do have one, right?):

    protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new ServiceStackJsonResult
        {
            Data = data,
            ContentType = contentType,
            ContentEncoding = contentEncoding
        };
    }
    
    public class ServiceStackJsonResult : JsonResult
    {
        public override void ExecuteResult(ControllerContext context)
        {
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
    
            if (ContentEncoding != null)
            {
                response.ContentEncoding = ContentEncoding;
            }
    
            if (Data != null)
            {
                response.Write(JsonSerializer.SerializeToString(Data));
            }
        }
    }  
    
  3. It seems that this serializer by default does "the right thing" - it doesn't mess with your DateTime objects if their DateTime.Kind is Unspecified. However, I did few additional config tweaks in Global.asax (and it's good to know how to do that before you start using library):

    protected void Application_Start()
    {
        JsConfig.DateHandler = JsonDateHandler.ISO8601;
        JsConfig.TreatEnumAsInteger = true;
    
        // rest of the method...
    }
    

This link helped