I already have tried this, but I don't think it's my case. This doesn't work neither.
I'm using ASP.NET Core 2 Web API. I just created a dummy model binder (what it does doesn't matter for now):
public class SanitizeModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
return Task.CompletedTask;
}
}
Now, I have a model. This one:
public class UserRegistrationInfo
{
public string Email { get; set; }
[ModelBinder(BinderType = typeof(SanitizeModelBinder))]
public string Password { get; set; }
}
And an action method:
[AllowAnonymous]
[HttpPost("register")]
public async Task<IActionResult> RegisterAsync([FromBody] UserRegistrationInfo registrationInfo)
{
var validationResult = validateEmailPassword(registrationInfo.Email, registrationInfo.Password);
if (validationResult != null)
{
return validationResult;
}
var user = await _authenticationService.RegisterAsync(registrationInfo.Email, registrationInfo.Password);
if (user == null)
{
return StatusCode(StatusCodes.Status500InternalServerError, "Couldn't save the user.");
}
else
{
return Ok(user);
}
}
If I make a post request from the client, my custom model binder isn't fired and the execution continues in the action method.
Things I have tried:
Applying the ModelBinder
attribute to the whole model object:
[ModelBinder(BinderType = typeof(SanitizeModelBinder))]
public class UserRegistrationInfo
{
public string Email { get; set; }
public string Password { get; set; }
}
This works, but for the whole object, and I don't want that. I want the default model binder to do its job and then, apply my custom model binder to certain properties only.
I read here that it's the FromBody
's fault, so I removed it from the action method. It doesn't work neither.
I tried to change the attribute ModelBinder
for BindProperty
here:
public class UserRegistrationInfo
{
public string Email { get; set; }
[BindProperty(BinderType = typeof(SanitizeModelBinder))]
public string Password { get; set; }
}
But it doesn't work.
It's quite disapointing that something that should be simple is turning to be quite cumbersome, and the information scattered on several blogs and github issues isn't helping at all. So please, if you can help me, it would be really appreciated.
[FromBody]
? By doing this, you're really switching from a JSON body to anapplication/x-www-form-urlencoded
body so are you also changing the format of the body when you remove this? – Cradle[FromBody]
and set a breakpoint inside the action method. The action method gets executed, but not the custom model binder. – UndressEmail
andPassword
have a value? I'm wondering if that change actually just means nothing gets bound at all as you're sending JSON whereapplication/x-www-form-urlencoded
is expected (assuming you are working with JSON). – Cradle[FromBody]
and I inspect theregistrationInfo
parameter, it's filled. – Undress[ApiController]
attribute? – Cradle[Authorize]
,[ApiController]
and[Route("api/[controller]")]
. – UndressJsonConverter
and not a customIModelBinder
. You haven't really removed[FromBody]
when you say you have, because[ApiController]
infers it. – Cradle[ApiController]
would infer it. I'm going to investigate theJsonConverter
approach, but in any case, I think this should be a job for a custom model binder. – Undress