Исключить нулевые значения при потоковой передаче в json с помощью JsonResult в MVC - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть Json, показанный ниже.

Это на самом деле гораздо более сложный объект в реальности, но этот отрывок демонстрирует мой вопрос.

Я смотрю на уменьшение размера Jsonответ генерируется.В настоящее время это генерируется с использованием стандартного JsonResult в MVC,

Есть ли способ заставить JSonResult не передавать потоковые свойства со значением 0?Если это возможно, это сильно уменьшило бы мой отклик на json!Это, в свою очередь, ускорит синтаксический анализ.

 {
    "firstValue": 0.2000,
    "secondValue": 30.80,
    "thirdValue": 0.0,
    "fourthValue": 30.80,
    "fifthValue": 0.0
}

Таким образом, я на самом деле получу ответный ответ только ниже:

 {
    "firstValue": 0.2000,
    "secondValue": 30.80,
    "fourthValue": 30.80,
}

Я видел ответы, указывающие на использованиеApp_Start в моем веб-интерфейсе, но я использую Kestrel, у которого нет запуска приложения - он размещен на Service Fabric

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new[]
    {
        new ServiceInstanceListener(
            serviceContext =>
                new KestrelCommunicationListener(
                    serviceContext,
                    (url, listener) =>
                    {
                        ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                        return new WebHostBuilder()
                            .UseKestrel(options => { options.Listen(IPAddress.Any, 8081); })
                            .ConfigureServices(
                                services => services
                                    .AddSingleton(serviceContext)
                                    .AddSingleton(new ConfigSettings(serviceContext))
                                    .AddSingleton(new HttpClient())
                                    .AddSingleton(new FabricClient()))
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                            .UseStartup<Startup>()
                            .UseSerilog(_log, true)
                            .UseUrls(url)
                            .Build();
                    }))
    };
}

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Как и предполагалось Kit , вы можете использовать поведение DefaultValueHandling.

Кроме того, вы всегда можете настроить свой собственный ContractResolver для решения таких вопросов. Вот версия использования custom ContractResolver для игнорирования значения по умолчанию:

public class IgnoreZeroContractResolver : DefaultContractResolver
{
    public IgnoreZeroContractResolver( ){ }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        property.ShouldSerialize = instance => {
            var shouldSerialize = true;  // indicate should we serialize this property

            var type = instance.GetType();
            var pi = type.GetProperty(property.PropertyName);  
            var pv = pi.GetValue(instance);
            var pvType = pv.GetType();

            // if current value equals the default values , ignore this property 
            if (pv.GetType().IsValueType){
                var defaultValue = Activator.CreateInstance(pvType);  
                if (pv.Equals(defaultValue)) { shouldSerialize = false; } 
            }
            return shouldSerialize;
        };

        return property;
    }

}

И теперь вы можете установить свое восстановление как ContractResolver:

public void ConfigureServices(IServiceCollection services)
{

    // ...
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddJsonOptions(o =>{
           o.SerializerSettings.ContractResolver =new IgnoreZeroContractResolver();
        });

    // ...

}

Контрольный пример:

var x = new {
    FirstValue =0.2000,
    SecondValue= 30.80,
    ThirdValue= 0.0,
    FourthValue= 30.80,
    FifthValue= 0.0,        // double 0
    SixValue= 0             // int 0
};
return new JsonResult(x);

и ответ будет:

{"FirstValue":0.2,"SecondValue":30.8,"FourthValue":30.8}
0 голосов
/ 19 ноября 2018

Это супер просто.Просто укажите значение для DefaultValueHandling со значением Игнорировать .

Как указано в описании в этой ссылке:

Игнорировать элементы, гдезначение элемента такое же, как значение элемента по умолчанию при сериализации объектов, поэтому оно не записывается в JSON.Эта опция игнорирует все значения по умолчанию (например, null для объектов и типов, допускающих значения NULL; 0 для целых чисел, десятичных чисел и чисел с плавающей запятой; и false для логических значений).Значение по умолчанию, которое игнорируется, можно изменить, поместив атрибут DefaultValueAttribute в это свойство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...