Подтвердить что ты не робот

Правильная сериализация JSON в MVC 4

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

Для 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);
}

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

4b9b3361

Ответ 1

Я бы рекомендовал использовать что-то вроде 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?

Ответ 2

В то время как веб-API использует JSON.NET, MVC4 использует по умолчанию JavaScriptSerializer, и я не думаю, что он поддерживает переход к сериализации Camel Case. Проверьте это: Установка Сеанса JSON по умолчанию в ASP.NET MVC

Мое предложение состоит в том, что вы создаете пользовательский JsonNetResult, как описано здесь Использование JSON.NET в качестве стандартного JSON-сериализатора в ASP.NET MVC 3 - возможно ли это? и измените последнюю строку на:

var serializedObject = JsonConvert.SerializeObject(
      Data,
      Formatting.Indented, ,
      new JsonSerializerSettings { MappingResolver = new CamelCaseMappingResolver() });

Ответ 3

Note that below information is for Asp .Net core
Команда

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

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

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

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