Home > other >  Changing JSON target when Web API parses object in method argument
Changing JSON target when Web API parses object in method argument

Time:12-29

I have an endpoint that I am migrating. The current format of the JSON being sent to the endpoint is:

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

Currently with a method signature like this...

public string GetTarget(Settings settings);

It appears that the Web API deserializer is looking for the JSON to be formatted as follows (with no top level variable name):

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

I have a legacy app that sends the JSON with the "settings" variable name and I cannot update it to send the unnested format. Is there any way to have Web API target the nested properties within "settings"?

CodePudding user response:

You can try to use custom model binding.Here is a demo:

Settings:

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

    }

action:

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

CustomBinder:

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;
        }
    }

result: enter image description here

CodePudding user response:

try this,it was tested using VS and Postman. It doesn't need any custom converter

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; }
}
  • Related