FireShock
FireShock

Reputation: 1122

Bind multiple parameters from route and body to a model in ASP.NET Core

I provide an ID in the route (".../api/mobile/registers/192" - 192 is ID) and the rest of params in the body of a PUT-request. How to bing them to a model with all the parameters? The problem is that the ID does not map, it is always 0:

[HttpPut("registers/{id}")]
public async Task ModifyPaymentRegister(PaymentRegisterModifyRequestVm model)
{
    var result = await financeService.ModifyPaymentRegisterAsync(model, CurrentUserId.Value);
    ...
}
    [BindProperties(SupportsGet = true)]
    public class PaymentRegisterModifyRequestVm
    {
        /// <summary>
        /// Идентификатор реестра
        /// </summary>
        [FromRoute]
        public int Id { get; set; }

        /// <summary>
        /// Описание реестра
        /// </summary>
        [FromBody]
        public string Description { get; set; }

        /// <summary>
        /// Тип модификации реестра
        /// </summary>
        [FromBody]
        public PaymentModifyType ModifyType { get; set; }
    }

Upvotes: 6

Views: 7032

Answers (3)

fattikus
fattikus

Reputation: 542

well what you are trying to achieve, by using the same model, seems to be impossible:

look at msft docs: Msft Docs

the answers above all gave you an alternative solution. This is the solution you were really looking for though:

ASP.NET Core MVC Mixed Route/FromBody Model Binding & Validation

Posting this so that if anyone hops onto this issue finds the real answer/implementation to achieve this. not a workaround

Upvotes: 2

Wellington J&#250;nior
Wellington J&#250;nior

Reputation: 279

You have to pass the id as a parameter too.

public async Task ModifyPaymentRegister(int id, PaymentRegisterModifyRequestVm model)

By default, aspnet hides the use of notations, so the second parameter is like [FromBody] PaymentRegisterModifyRequestVm model)

Try this:

[HttpPut("registers/{id}")]
public async Task ModifyPaymentRegister(int id, PaymentRegisterModifyRequestVm model)
{
    var result = await financeService.ModifyPaymentRegisterAsync(model, CurrentUserId.Value);
    ...
}

Upvotes: 1

Hamed Moghadasi
Hamed Moghadasi

Reputation: 1673

The short answer is that you cannot pass an object from route to an action method. for passing data from route to method, the route parameter name must be exactly as same as the method parameter. If you wanna pass multiple parameters you should act like below:

[HttpGet("api/v1/Users/{name}/{surname}")]
public string GetUser(string name,string surname)
{
    return "Hello " + name + " " + surname;
}

this code work with the below URLs:

  • localhost:3001/api/v1/Users/Hamed/Moghadasi
  • localhost:3001/api/v1/Users?name=Hamed&surname=Moghadasi

BUT, I would like to say that the right way to send complex data objects to an API is using request body. so you can simply put your data in the request body and easily get it in the method by using [FromBody], your code should be like below:

[HttpPut("registers")]
public async Task ModifyPaymentRegister([FromBody]PaymentRegisterModifyRequestVm model)

for going deeper you can follow this link. good luck.

Upvotes: 3

Related Questions