2013-06-21 3 views
41

Я бы хотел, чтобы JSON был «правильно» сериализован (camelCase) и возможность изменять форматы даты, если это необходимо.Правильная сериализация JSON в MVC 4

Для Web API это очень легко - в Global.asax я выполнить следующий код

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; 
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Этот код, на уровне трубопровода, обрабатывает сериализации, как я хотел.

Я хотел бы сделать то же самое в MVC 4 - должен ли JSON возвратиться из методов действий контроллера для правильной сериализации. С небольшим поисков я нашел следующий код, чтобы бросить в запуске приложения Global.asax:

HttpConfiguration config = GlobalConfiguration.Configuration; 
Int32 index = config.Formatters.IndexOf(config.Formatters.JsonFormatter); 
config.Formatters[index] = new JsonMediaTypeFormatter 
{ 
    SerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } 
}; 

кажется выполнить нормально, но когда я возвращаюсь JSON из контроллера все это PascalCased. Простой пример моего действия:

private JsonResult GetJsonTest() 
{ 
    var returnData = dataLayer.GetSomeObject(); 
    return Json(returnData, JsonRequestBehavior.AllowGet); 
} 

Я собираюсь сделать это неправильно? Любая идея, как это сделать на уровне трубопровода?

+0

Я не знал, что у json spec необходим верблюжой корпус .... – evanmcdonnal

+3

Как я понимаю, верблюд с обсаженной json более широко принят и не делает этого, может сломать каркасы. Кроме того, наши стандарты развития указывают на то, что я и делаю. – Mario

ответ

86

Я рекомендовал бы использовать что-то вроде ServiceStack или Json.NET для обработки вывода JSon в вашем приложении MVC. Однако вы можете легко написать класс и переопределить Json-метод, используя базовый класс. См. Мой пример ниже.

ПРИМЕЧАНИЕ. При этом вам не нужно ничего в файле Global.ascx.cs.

Пользовательские JsonDotNetResult класс:

public class JsonDotNetResult : JsonResult 
{ 
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings 
    { 
     ContractResolver = new CamelCasePropertyNamesContractResolver(), 
     Converters = new List<JsonConverter> { new StringEnumConverter() } 
    }; 

    public override void ExecuteResult(ControllerContext context) 
    { 
     if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && 
      string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
     { 
      throw new InvalidOperationException("GET request not allowed"); 
     } 

     var response = context.HttpContext.Response; 

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

     if (this.ContentEncoding != null) 
     { 
      response.ContentEncoding = this.ContentEncoding; 
     } 

     if (this.Data == null) 
     { 
      return; 
     } 

     response.Write(JsonConvert.SerializeObject(this.Data, Settings)); 
    } 
} 

Базовый класс контроллера:

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

Теперь на ваши действия контроллера вы можете просто вернуть что-то вроде этого.

return Json(myObject, JsonRequestBehavior.AllowGet); 

BAM. Теперь у вас есть Camelcase Объекты, возвращенные с Json :)

ПРИМЕЧАНИЕ. Существуют способы сделать это с помощью настроек Serializer для каждого объекта, который вы создаете с помощью Json. Но кто хотел бы напечатать это каждый раз, когда вы хотите вернуть Json?

6

Хотя Web API использует JSON.NET, MVC4 использует по умолчанию JavaScriptSerializer, и я не думаю, что он поддерживает изменение в сериализации Camel Case. Проверьте это: Setting the Default JSON Serializer in ASP.NET MVC

Мое предложение состоит в том, что вы создаете пользовательский JsonNetResult, как описано здесь Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible? и измените последнюю строку на:

var serializedObject = JsonConvert.SerializeObject(
     Data, 
     Formatting.Indented, , 
     new JsonSerializerSettings { MappingResolver = new CamelCaseMappingResolver() }); 
4
Note that below information is for Asp .Net core 

. Команда Net недавно объявила о том, что MVC теперь сериализует JSON с именами корпусов верблюдов по умолчанию.

С парой строк ниже Вы могли бы включить эту функцию:

services 
.AddMvc() 
.AddJsonOptions(options => 
options.SerializerSettings.ContractResolver = new DefaultContractResolver()); 

Я написал небольшой блог на том же что here.

+3

Да, но это для ядра aspnet – Thomas

+0

да, я обновил @Thomas – Neel