当发布字符串而不是数组时,模型绑定返回null

使用Netonsoft执行模型绑定时,我具有.Net Core 3 Api。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<KestrelServerOptions>(options => { options.AllowSynchronousIO = true; });
        services.Configure<IISServerOptions>(options => { options.AllowSynchronousIO = true; });
        services.AddOptions();
        services.AddMvcCore().SetCompatibilityVersion(CompatibilityVersion.Version_3_0).AddNewtonsoftJson();
        services.AddHealthChecks()
            .AddCheck<ApiHealthCheck>("api");

    }
    public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        app.UseHealthChecks("/health");
    }
}

在Api中,我期望一个类似的模型:

public class Family
{
    public Member Member1 { get; set; }
    public Member Member2 { get; set; }
}

public class Member
{
    public string FirstName { get; set; }
    public List<string> LastNames { get; set; }
}

现在,当我发布以下Json时,模型绑定为我提供了一个家庭对象,该对象具有从Json中获取的值:

{
    "member1": {
        "firstName": "john","lastNames": [
            "wick"
        ]
    },"member2": {
        "firstName": "Rich","lastNames": null
    }
}

但是,当我发布以下Json(姓氏值是字符串而不是数组)时:

{
    "member1": {
        "firstName": "john","lastNames": "wick"
    },"member2": {
        "firstName": "Rich"
    }
}

我希望获得一个成员为Member1的Family对象,而成员2仅具有名字。

但是我得到的是空值(在收到的模型中找不到家庭)。

这种行为应该发生吗?以及如何告诉Newtonsoft仅忽略姓氏而不是整个模型?

kxp1125 回答:当发布字符串而不是数组时,模型绑定返回null

您需要编写自己的自定义转换器以忽略它。解决方法是:

首先声明您的自定义Resolver类。

        class IgnoreNullList : DefaultContractResolver
        {
            protected override JsonContract CreateContract(Type objectType)
            {
                JsonContract contract = base.CreateContract(objectType);
                if (objectType == typeof(List<string>))
                {
                    contract.Converter = new MyNullIgnorer();
                }

                return contract;
            }
        }

    internal class MyNullIgnorer : JsonConverter
    {
        public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
        {

        }

        public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
        {

            if (reader.TokenType == JsonToken.StartArray)
            {
                JToken token = JToken.Load(reader);
                List<string> items = token.ToObject<List<string>>();
                return items;
            }

            return null;
        }

        public override bool CanConvert(Type objectType)
        {
            return true;
        }
    }

然后在代码中使用自定义转换器转换对象。


....

            var setting = new JsonSerializerSettings()
            {
                ContractResolver = new IgnoreNullList()
            };

var test = JsonConvert.DeserializeObject<Family>(yourJsonString,setting);

本文链接:https://www.f2er.com/3152024.html

大家都在问