Установка в JSON сериализатор по умолчанию в ASP.NET в MVC


Я работаю над существующим приложением, которое было частично преобразовано в MVC. Всякий раз, когда контроллер отвечает JSON ActionResult, перечисления отправляются как числа, противоположные имени строки. Похоже, что сериализатор по умолчанию должен быть JSON.Net, который должен отправлять перечисления в качестве их имен, противоположных целочисленному представлению, но здесь это не так.

Мне не хватает паутины.настройка конфигурации, которая устанавливает это как сериализатор по умолчанию? Или есть еще один параметр, который необходимо изменить?

2 55

2 ответа:

In ASP.Net MVC4 сериализатор JavaScript по умолчанию, который используется в JsonResult класс еще JavaScriptSerializer (вы можете проверить его в код)

Я думаю, что вы перепутали его с ASP.Net веб.API где JSON.Net является сериализатором JS по умолчанию, но MVC4 не использует его.

так что вам нужно настроить JSON.Net для работы с MVC4 (в основном вам нужно создать свой собственный JsonNetResult), есть много статей о это:

если вы также хотите использовать JSON.Net для параметров действия контроллера, поэтому во время привязки модели вам нужно написать свой собственный ValueProviderFactory реализация.

и вам нужно зарегистрировать свою реализацию с:

ValueProviderFactories.Factories
    .Remove(ValueProviderFactories.Factories
                                  .OfType<JsonValueProviderFactory>().Single());
ValueProviderFactories.Factories.Add(new MyJsonValueProviderFactory());

вы можете использовать встроенный в JsonValueProviderFactory в качестве примера Или этой статьи:ASP.NET MVC 3-улучшенное использование JsonValueProviderFactory Json.Net

ASP.NET MVC 5 исправить:

Я не был готов переодеться Json.NET просто еще и в моем случае ошибка произошла во время запроса. Лучшим подходом в моем сценарии было изменение фактического JsonValueProviderFactory который применяет исправление к глобальному проекту и может быть выполнен путем редактирования global.cs файл как таковой.

JsonValueProviderConfig.Config(ValueProviderFactories.Factories);

добавить веб -.запись config:

<add key="aspnet:MaxJsonLength" value="20971520" />

а затем создать два следующих класса

public class JsonValueProviderConfig
{
    public static void Config(ValueProviderFactoryCollection factories)
    {
        var jsonProviderFactory = factories.OfType<JsonValueProviderFactory>().Single();
        factories.Remove(jsonProviderFactory);
        factories.Add(new CustomJsonValueProviderFactory());
    }
}

это в основном точная копия реализации по умолчанию, найденная в System.Web.Mvc но с добавлением конфигурируемой сети.config appsetting value aspnet:MaxJsonLength.

public class CustomJsonValueProviderFactory : ValueProviderFactory
{

    /// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
    /// <returns>A JSON value-provider object for the specified controller context.</returns>
    /// <param name="controllerContext">The controller context.</param>
    public override IValueProvider GetValueProvider(ControllerContext controllerContext)
    {
        if (controllerContext == null)
            throw new ArgumentNullException("controllerContext");

        object deserializedObject = CustomJsonValueProviderFactory.GetDeserializedObject(controllerContext);
        if (deserializedObject == null)
            return null;

        Dictionary<string, object> strs = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        CustomJsonValueProviderFactory.AddToBackingStore(new CustomJsonValueProviderFactory.EntryLimitedDictionary(strs), string.Empty, deserializedObject);

        return new DictionaryValueProvider<object>(strs, CultureInfo.CurrentCulture);
    }

    private static object GetDeserializedObject(ControllerContext controllerContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            return null;

        string fullStreamString = (new StreamReader(controllerContext.HttpContext.Request.InputStream)).ReadToEnd();
        if (string.IsNullOrEmpty(fullStreamString))
            return null;

        var serializer = new JavaScriptSerializer()
        {
            MaxJsonLength = CustomJsonValueProviderFactory.GetMaxJsonLength()
        };
        return serializer.DeserializeObject(fullStreamString);
    }

    private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
    {
        IDictionary<string, object> strs = value as IDictionary<string, object>;
        if (strs != null)
        {
            foreach (KeyValuePair<string, object> keyValuePair in strs)
                CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);

            return;
        }

        IList lists = value as IList;
        if (lists == null)
        {
            backingStore.Add(prefix, value);
            return;
        }

        for (int i = 0; i < lists.Count; i++)
        {
            CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakeArrayKey(prefix, i), lists[i]);
        }
    }

    private class EntryLimitedDictionary
    {
        private static int _maximumDepth;

        private readonly IDictionary<string, object> _innerDictionary;

        private int _itemCount;

        static EntryLimitedDictionary()
        {
            _maximumDepth = CustomJsonValueProviderFactory.GetMaximumDepth();
        }

        public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
        {
            this._innerDictionary = innerDictionary;
        }

        public void Add(string key, object value)
        {
            int num = this._itemCount + 1;
            this._itemCount = num;
            if (num > _maximumDepth)
            {
                throw new InvalidOperationException("The length of the string exceeds the value set on the maxJsonLength property.");
            }
            this._innerDictionary.Add(key, value);
        }
    }

    private static string MakeArrayKey(string prefix, int index)
    {
        return string.Concat(prefix, "[", index.ToString(CultureInfo.InvariantCulture), "]");
    }

    private static string MakePropertyKey(string prefix, string propertyName)
    {
        if (string.IsNullOrEmpty(prefix))
        {
            return propertyName;
        }
        return string.Concat(prefix, ".", propertyName);
    }

    private static int GetMaximumDepth()
    {
        int num;
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
            if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
            {
                return num;
            }
        }
        return 1000;
    }

    private static int GetMaxJsonLength()
    {
        int num;
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonLength");
            if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
            {
                return num;
            }
        }
        return 1000;
    }
}