Как использовать Json.NET для JSON-моделирования в проекте MVC5?

Я просматривал интернет для ответа или примера, но пока не нашел его. Я просто хотел бы изменить по умолчанию JSON-сериализатор, который используется для десериализации JSON при привязке модели к библиотеке JSON.NET.

Я нашел эту запись SO, но не могу ее реализовать до сих пор, я даже не вижу пространства имен System.Net.Http.Formatters , и я не могу увидеть GlobalConfiguration .

Что мне не хватает?

ОБНОВИТЬ

У меня есть проект ASP.NET MVC, это был в основном проект MVC3. В настоящее время я нацелен на .NET 4.5 и использует ASP.NET MVC 5 и связанные с ним пакеты NuGet.

Я не вижу сборки System.Web.Http или любого подобного пространства имен. В этом контексте я хотел бы добавить JSON.NET, который будет использоваться как связующее устройство модели по умолчанию для запросов типа JSON.

    Наконец-то я нашел ответ. В основном мне не нужен материал MediaTypeFormatter , который не предназначен для использования в среде MVC, но в ASP.NET Web API, поэтому я не вижу этих ссылок и пространств имен (кстати, они включены в Microsoft.AspNet.WeApi NuGet).

    Решение заключается в использовании фабрики изготовителей настраиваемых значений. Вот код, необходимый.

      public class JsonNetValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { // first make sure we have a valid context if (controllerContext == null) throw new ArgumentNullException("controllerContext"); // now make sure we are dealing with a json request if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) return null; // get a generic stream reader (get reader for the http stream) var streamReader = new StreamReader(controllerContext.HttpContext.Request.InputStream); // convert stream reader to a JSON Text Reader var JSONReader = new JsonTextReader(streamReader); // tell JSON to read if (!JSONReader.Read()) return null; // make a new Json serializer var JSONSerializer = new JsonSerializer(); // add the dyamic object converter to our serializer JSONSerializer.Converters.Add(new ExpandoObjectConverter()); // use JSON.NET to deserialize object to a dynamic (expando) object Object JSONObject; // if we start with a "[", treat this as an array if (JSONReader.TokenType == JsonToken.StartArray) JSONObject = JSONSerializer.Deserialize>(JSONReader); else JSONObject = JSONSerializer.Deserialize(JSONReader); // create a backing store to hold all properties for this deserialization var backingStore = new Dictionary(StringComparer.OrdinalIgnoreCase); // add all properties to this backing store AddToBackingStore(backingStore, String.Empty, JSONObject); // return the object in a dictionary value provider so the MVC understands it return new DictionaryValueProvider(backingStore, CultureInfo.CurrentCulture); } private static void AddToBackingStore(Dictionary backingStore, string prefix, object value) { var d = value as IDictionary; if (d != null) { foreach (var entry in d) { AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value); } return; } var l = value as IList; if (l != null) { for (var i = 0; i < l.Count; i++) { AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]); } return; } // primitive backingStore[prefix] = value; } private static string MakeArrayKey(string prefix, int index) { return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; } private static string MakePropertyKey(string prefix, string propertyName) { return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName; } } 

    И вы можете использовать его в своем методе Application_Start :

     // remove default implementation ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType().FirstOrDefault()); // add our custom one ValueProviderFactories.Factories.Add(new JsonNetValueProviderFactory()); 

    Вот сообщение, которое указывало мне на правильное направление, а также это дало хорошее объяснение поставщикам стоимости и модельным машинам.

    У меня тоже была такая проблема. Я отправлял JSON в действие, но мои имена JsonProperty были проигнорированы. Таким образом, мои свойства модели всегда были пустыми.

     public class MyModel { [JsonProperty(PropertyName = "prop1")] public int Property1 { get; set; } [JsonProperty(PropertyName = "prop2")] public int Property2 { get; set; } [JsonProperty(PropertyName = "prop3")] public int Property3 { get; set; } public int Foo { get; set; } } 

    Я отправляю в действие с помощью этой пользовательской функции jquery:

     (function ($) { $.postJSON = function (url, data, dataType) { var o = { url: url, type: 'POST', contentType: 'application/json; charset=utf-8' }; if (data !== undefined) o.data = JSON.stringify(data); if (dataType !== undefined) o.dataType = dataType; return $.ajax(o); }; }(jQuery)); 

    И я называю это так:

     data = { prop1: 1, prop2: 2, prop3: 3, foo: 3, }; $.postJSON('/Controller/MyAction', data, 'json') .success(function (response) { ...do whatever with the JSON I got back }); 

    К сожалению, только foo когда-либо получал привязку (нечетно, так как случай не тот, но я думаю, что по умолчанию modelbinder не чувствителен к регистру)

     [HttpPost] public JsonNetResult MyAction(MyModel model) { ... } 

    Решение оказалось довольно простым

    Я только что внедрил универсальную версию связующего устройства для модели Dejan, которая работает очень хорошо для меня. Вероятно, он может использовать некоторые фиктивные проверки (например, убедиться, что запрос на самом деле является приложением / json), но сейчас он делает трюк.

     internal class JsonNetModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { controllerContext.HttpContext.Request.InputStream.Position = 0; var stream = controllerContext.RequestContext.HttpContext.Request.InputStream; var readStream = new StreamReader(stream, Encoding.UTF8); var json = readStream.ReadToEnd(); return JsonConvert.DeserializeObject(json, bindingContext.ModelType); } } 

    Когда я хочу использовать его для определенного действия, я просто скажу, что вместо этого хочу использовать свое обычное JSP-образное связующее:

     [HttpPost] public JsonNetResult MyAction([ModelBinder(typeof(JsonNetModelBinder))] MyModel model) { ... } 

    Теперь мои [JsonProperty (PropertyName = “”)] атрибуты больше не игнорируются в MyModel, и все связано правильно!

    В моем случае мне пришлось десериализовать сложные объекты, включая интерфейсы и динамически загружаемые типы и т. Д., Поэтому предоставление настраиваемого поставщика значений не работает, поскольку MVC все еще нуждается в попытках выяснить, как создавать экземпляры интерфейсов, а затем терпит неудачу.

    Поскольку мои объекты уже были должным образом аннотированы для работы с Json.NET, я выбрал другой маршрут: я применил настраиваемое связующее устройство и использовал Json.NET для явного десериализации данных тела запроса следующим образом:

     internal class CustomModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { // use Json.NET to deserialize the incoming Position controllerContext.HttpContext.Request.InputStream.Position = 0; // see: http://stackoverflow.com/a/3468653/331281 Stream stream = controllerContext.RequestContext.HttpContext.Request.InputStream; var readStream = new StreamReader(stream, Encoding.UTF8); string json = readStream.ReadToEnd(); return JsonConvert.DeserializeObject(json, ...); } } 

    Взаимодействие настраиваемой модели зарегистрировано в Global.asax.cs :

      ModelBinders.Binders.Add(typeof(MyClass), new CustomModelBinder(); 
    Interesting Posts

    Каково использование метода Pattern.quote?

    Как заблокировать исходящие вызовы и текстовые SMS

    Автоматическое удаление файлов старше заданных минут в Windows

    Установите Chromium для автоматического перевода всех языков

    Что такое Агрегаты и POD и как / почему они являются особенными?

    Последняя непустая ячейка (столбец) в данной строке; Excel VBA

    Windows: как отключить скрытый атрибут для всех файлов и каталогов на диске?

    Как добавить конфигурацию профиля среды для SBT

    Каков наилучший способ поймать исключение в Задаче?

    В чем разница между инкапсулированием частного члена как свойства и определением свойства без частного члена?

    Что делает akamaihd.net?

    IE 10 сбой при загрузке файла при использовании EMET

    Когда мы должны использовать ключевое слово extern alias в C #?

    Угловой 2 + Ионный 2: Обнаружение, если объект был изменен

    3TB жесткие диски SATA в старую систему Linux

    Давайте будем гением компьютера.