Search code examples
c#.netjsonasp.net-corecustom-model-binder

how to read un-named object from BindingContext


I need to implement Custom model binding and so trying to implement IModelBinder for .Net Core 2.1 API application.

Model class -

  [ModelBinder(BinderType = typeof(PersonBinder))]
  public class Person
  {
     public name {get;set;}
     public address {get;set;}
  }

API method -

 [HttpPost]
 [Route("process")]
 public async Task<ActionResult<int>> ProcessAsync([ModelBinder(typeof(PersonBinder))]Person person)
 {
     ...
 }

Bind Model method -

public Task BindModelAsync(ModelBindingContext bindingContext)
{
    var modelName = bindingContext.ModelName; //modelName is empty string
    ...
}

Postman request that i use for testing has JSON object in the body and the simplest form of it looks like this -

{
    "name": "name1"
    "address": "address1" 
}

Please note that this request comes from the existing legacy client which i have no control of and the JSON object that will be coming as a body in POST will have no name.

In QuickWatch in VisualStudio i also see that bindingContext.ValueProvider.Count is 1 and bindingContext.ModelMetadata has Parameter of person and Type of Person and bindingContext.FieldName is person. And surprisingly bindingProvider.Result is Failed and bindingContext.ModelName is always String.Empty

Can anyone please help me get the ModelName from BindingContext. And if there is no way to get ModelName in this situation then how can i read the Person object from BindingContext?


Solution

  • I have figured out the best way to read posted parameters and since i did not get any response to this question, i will post how i did it, if it can be helpful to anyone else

            public Task BindModelAsync(ModelBindingContext bindingContext)
            {
                var request = bindingContext.HttpContext.Request;
    
                using (var reader = new StreamReader(request.Body, Encoding.UTF8))
                {
                    var bodyString = reader.ReadToEnd();
                    var person = bodyString.DeSerialize<Person>(); //this is custom logic to de-serialize to object from JSON string
    
                    //write your model binding logic here...
    
                    bindingContext.Result = ModelBindingResult.Success(person);
                }
    
                return Task.CompletedTask;
            }