Задайте NullValueHandling на ниво контролер

За момента бих искал да изключа нулеви стойности от моя api отговор, така че в моя файл startup.cs имам това.

services.AddMvc()
    .AddJsonOptions(options =>
    {
        // Setup json serializer
        options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    });

Но възможно ли е да се каже, че на 1 или повече контролери всъщност искам да включа NULL стойности??


person Gillardo    schedule 04.02.2016    source източник


Отговори (2)


Една опция е да създадете персонализиран Json тип резултат, както е описано в този въпрос: Използване на JSON.NET като JSON сериализатор по подразбиране в ASP.NET MVC 3 - възможно ли е?. След това можете да имате bool var на основния контролер и да го използвате, за да деактивирате null, когато използвате персонализиран Json резултат или дори директно да предадете опцията:

return Json(data, ignoreNulls: true); 
person csharpfolk    schedule 04.02.2016

Можете да получите JsonOutputFormatter от BindingContext.OutputFormatters вътре в кода на вашия контролер. Позволява ви динамично да променяте SerializerSettings.

Опитайте се да включите using Newtonsoft.Json; в кода на контролера и да направите следното вътре в действието на контролера:

var f = BindingContext.OutputFormatters.FirstOrDefault(
            formatter => formatter.GetType() ==
                         typeof (Microsoft.AspNet.Mvc.Formatters.JsonOutputFormatter))
        as Microsoft.AspNet.Mvc.Formatters.JsonOutputFormatter;
if (f != null) {
    //f.SerializerSettings.Formatting = Formatting.Indented;
    f.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
}

Включих Formatting = Formatting.Indented само за моите тестове, защото човек вижда резултатите веднага. Нямате нужда от това по причина.

АКТУАЛИЗИРАНО: Създадох демонстрационния проект с помощта на MVC уеб приложение без удостоверяване. След това добавих в HomeController следния метод

public object TestMethod()
{
    var testResult = new {
                         name = "Test",
                         value = 123,
                         nullableProperty = (string) null
                     };

    return testResult;
}

и промени URL адреса за стартиране на проекта на Home/TestMethod и стартира демонстрацията. Можех да видя

{"name":"Test","value":123,"nullableProperty":null}

Не е необходимо да добавяте допълнителни изрази за използване, за да използвате кода, който публикувах първоначално (трябва само да имате стандартните using Microsoft.AspNet.Mvc; и using System.Linq;), но кодът може да бъде по-четлив, ако имате using Microsoft.AspNet.Mvc.Formatters; и using Newtonsoft.Json;. Добавих изразите за използване за Microsoft.AspNet.Mvc.Formatters и Newtonsoft.Json и промених кода до следното

public object TestMethod()
{
    var testResult = new {
                         name = "Test",
                         value = 123,
                         nullableProperty = (string) null
                     };

    var f = BindingContext.OutputFormatters.FirstOrDefault(
                formatter => formatter.GetType() == typeof (JsonOutputFormatter)) as JsonOutputFormatter;
    if (f != null) {
        f.SerializerSettings.Formatting = Formatting.Indented;
        f.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
    }
    return testResult;
}

Изходните резултати сега изглеждат както следва

{
  "name": "Test",
  "value": 123
}

Стандартният код използва "Newtonsoft.Json" във версия 6.0.6. Можем да добавим "Newtonsoft.Json": "8.0.2" в зависимости, за да използваме най-новата версия на Newtonsoft.Json. Вижте проблема с разрешаването на косвени зависимости, за който докладвах в проблема и който все още е отворен .

Можете да изтеглите тестовия проект от тук.

person Oleg    schedule 04.02.2016
comment
Изглежда не мога да видя BindingContext от моя метод на контролер? това за ASPNET5 ли е? - person Gillardo; 05.02.2016
comment
@user2736022: Да по причина. Вътре във всяко действие на контролера имате this със свойства HttpContext, BindingContext и т.н. Можете просто да въведете this. вътре във вашия метод. След като напишете . intellysense ще ви покаже всички свойства на this включително BindingContext. C# ви позволява (препоръчва) да пишете BindingContext вместо this.BindingContext. - person Oleg; 05.02.2016
comment
Можете ли да проверите с пространството на имената, в което е? Казва, че моят контролер не съдържа дефиниция за BindingContext - person Gillardo; 05.02.2016
comment
@user2736022: BindingContext е собственост на Controller. Всеки MVC6 контролер трябва да бъде клас, който е using Microsoft.AspNet.Mvc;. Описах всички стъпки в АКТУАЛИЗИРАНА част от моя отговор и качих тук тестовият проект на Visual Studio 2015, който демонстрира кода. - person Oleg; 05.02.2016
comment
MVC Core използва повторно един и същ екземпляр на JsonOutputFormatter във всички контролери. Промяната на настройката на сериализатора вътре в контролера е почти идентична с модифицирането му при стартиране. - person Pranav; 05.02.2016
comment
@Pranav: И аз така мисля. Следователно трябва да се зададат настройките на променливите във всички контролери. Човек може да дефинира производен клас от Controller клас и да го използва във всички контролери. Искам да покажа начина, по който човек може да промени SerializerSettings динамично. Всички други кодове трябва да бъдат написани в съответствие с точните изисквания. - person Oleg; 05.02.2016
comment
Използвам rc2, това изглежда не съществува? rc1 има BindingContext, но не и rc2... - person Gillardo; 08.02.2016
comment
@user2736022: Можете да спестите много време, ако предоставите правилна информация първоначално. RC2 сега е в процес на преименуване. Много пакети, методи, вътрешни структури са преименувани. Аз лично не искам да го използвам сега, докато промените не приключат. Опитах предварителната версия на RC2 преди, но сега нямам работещ MVC Core проект, който дори може да бъде компилиран. Така че не мога да ви помогна с BindingContext. - person Oleg; 08.02.2016
comment
@user2736022: Не мога да компилирам никакъв код, който използва предварителен RC2, но изглежда, че човек може да получи OutputFormatters от HttpContext.RequestServices.GetRequiredService<IOptions<MvcOptions>>().Value.OutputFormatters вместо BindingContext преди. Така var f = HttpContext.RequestServices.GetRequiredService<IOptions<MvcOptions>>().Value.OutputFormatters.OfType<JsonOutputFormatter>().Single(); може да работи. - person Oleg; 08.02.2016
comment
Това не работи. ако промените примера си, за да имате 2 метода, първият включва нула/разстояние, а след това вторият го изключва. Достъп до първия метод, добре е, достъп до втория, добре е. Върнете се към първия и настройките са презаписани - person Gillardo; 08.02.2016
comment
@user2736022: Да по причина. Трябва да прочетете и предишните коментари. Вашите въпроси бяха как да получите достъп до SerializerSettings, за да можете да променяте там. Показах ви как да получите достъп до настройките и да ги променяте динамично. MVC съдържа един екземпляр от настройките, така че трябва да зададете (нулирате) свойствата във всяко действие на вашия контролер/контролер. - person Oleg; 08.02.2016