Как использовать 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(); 
  • Строка Parse Json в C #
  • Json.NET (Newtonsoft.Json) - Два «свойства» с таким же именем?
  • Не удалось загрузить файл или сборку «Newtonsoft.Json, Version = 4.5.0.0, Culture = neutral, PublicKeyToken = 30ad4fe6b2a6aeed»
  • Заставить JSON.NET включать миллисекунды при сериализации DateTime (даже если компонент ms равен нулю)
  • JSON.Net: принудительная сериализация всех частных полей и всех полей в подclassах
  • Как я могу зашифровать выбранные свойства при сериализации моих объектов?
  • Json.Net: Html Помощник не регенерирует
  • Десериализация дат с форматом dd / mm / yyyy с использованием Json.Net
  • Дезаминирование гетерогенного массива JSON в ковариантный список с использованием JSON.NET
  • Создайте строго типизированный объект c # из объекта json с ID как имя
  • Ошибка при запуске JSON.NET при сериализации Mongo ObjectId
  • Interesting Posts

    Убить призрак при подключении к freenode в xchat?

    Android и получение представления с литой идентификатором в виде строки

    Эквивалентная функция для «_getch ()« C »в Java?

    Как установить Internet Explorer в Linux?

    вызов метода родительского controllerа из директивы в AngularJS

    Зачем использовать начальные и конечные функции не-членов в C ++ 11?

    Как установить короткую ссылку symlink на Sublime Text 3 в терминале?

    Добавление и удаление анонимного обработчика событий

    Видео / Анимированный расширенный редактор кадров GIF?

    Удаление других каталогов пользователя из моего собственного

    Подмножество строк, содержащих значения NA (отсутствует) в выбранном столбце кадра данных

    Как сделать раскрывающийся список «Проверка данных» исключать пробелы?

    Считайте строки, где несколько значений отображаются вместе

    Два устройства не могут пинговать друг друга через WiFi

    Как установить приложение Cocoa в качестве браузера по умолчанию?

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