当 Web API 解析方法参数中的对象时更改 JSON 目标

Changing JSON target when Web API parses object in method argument

我有一个正在迁移的端点。发送到端点的 JSON 当前格式为:

{
    "settings":{
        "Target":30,
        "UserId":12345
    }
}

目前有这样的方法签名...

public string GetTarget(Settings settings);

Web API 反序列化程序似乎正在寻找 JSON 格式如下(没有顶级变量名称):

{
    "Target":30,
    "UserId":12345
}

我有一个旧版应用程序发送带有“设置”变量名称的 JSON,我无法更新它以发送未嵌套的格式。有没有办法让 Web API 以“设置”中的嵌套属性为目标?

您可以尝试使用自定义模型binding.Here 是一个演示:

设置:

public class Settings {
        public int Target { get; set; }
        public int UserId { get; set; }

    }

操作:

public string GetTarget([ModelBinder(BinderType = typeof(CustomBinder))] Settings settings)

自定义绑定器:

public class CustomBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var model = new Settings();
            using (var reader = new StreamReader(bindingContext.HttpContext.Request.Body))
            {
                var body = reader.ReadToEndAsync();

                var mydata = JsonConvert.DeserializeObject<JObject>(body.Result);
                model = JsonConvert.DeserializeObject<Settings>(mydata["settings"].ToString());
                

            }

            bindingContext.Result = ModelBindingResult.Success(model);
            return Task.CompletedTask;
        }
    }

结果:

试试这个,它是使用 VS 和 Postman 测试的。它不需要任何自定义转换器

using Newtonsoft.Json.Linq;
....

public string GetTarget([FromBody] JObject settingsObj)
{
Settings settings;
     
if (settingsObj["settings"] != null)  settings = settingsObj["settings"].ToObject<Settings>();
else settings = settingsObj.ToObject<Settings>();
    ......
}

public class Settings
{
    public int Target { get; set; }
    public int UserId { get; set; }
}