根据 post 请求将路由和正文值绑定到同一模型
Bind route and body values to same model on post request
是否可以在 post 请求期间将 URL 路由和主体的值绑定到同一模型?
例如:
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost("{valueFromRoute}/post")]
public IActionResult Post(Model model)
{
return new JsonResult(model);
}
}
public class Model
{
[FromRoute]
public string ValueFromRoute { get; set; }
[FromBody]
public string ValueFromBody { get; set; }
}
我想按如下方式调用此端点:
但是使用此代码,只有 ValueFromRoute
被填充:
{
"valueFromRoute": "some-route-value",
"valueFromBody": null
}
我猜答案可能是 "no",并且必须使用两个单独的模型,例如:
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost("{valueFromRoute}/post")]
public IActionResult Post([FromRoute] RouteModel routeModel, [FromBody] BodyModel bodyModel)
{
return new JsonResult(new
{
ValueFromRoute = routeModel.ValueFromRoute,
ValueFromBody = bodyModel.ValueFromBody
});
}
}
public class RouteModel
{
public string ValueFromRoute { get; set; }
}
public class BodyModel
{
public string ValueFromBody { get; set; }
}
以与上面屏幕截图完全相同的方式调用它,按预期工作,将两个值填充到各自的对象上,并输出以下内容:
{
"valueFromRoute": "some-route-value",
"valueFromBody": "Some value from body"
}
所以我有一个潜在的解决方案,但它不是我的首选解决方案。理想情况下,如果可能的话,我想将路由和主体值绑定到同一个模型。
我在 GitHub 上找到了 this related question,这帮助我理解了正文必须反序列化为一个 class 对象,即使它只包含一个 属性,就像我上面的例子。
我上面示例的解决方案只是为要反序列化的主体创建一个新的 class,并将其添加到我的操作方法所期望的主模型中。
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost("{valueFromRoute}/post")]
public IActionResult Post(Model model)
{
return new JsonResult(model);
}
}
public class Model
{
[FromRoute]
public string ValueFromRoute { get; set; }
// Map body to simple class object rather than a primitive type
[FromBody]
public BodyModel BodyModel { get; set; }
}
public class BodyModel
{
public string ValueFromBody { get; set; }
}
是否可以在 post 请求期间将 URL 路由和主体的值绑定到同一模型?
例如:
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost("{valueFromRoute}/post")]
public IActionResult Post(Model model)
{
return new JsonResult(model);
}
}
public class Model
{
[FromRoute]
public string ValueFromRoute { get; set; }
[FromBody]
public string ValueFromBody { get; set; }
}
我想按如下方式调用此端点:
但是使用此代码,只有 ValueFromRoute
被填充:
{
"valueFromRoute": "some-route-value",
"valueFromBody": null
}
我猜答案可能是 "no",并且必须使用两个单独的模型,例如:
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost("{valueFromRoute}/post")]
public IActionResult Post([FromRoute] RouteModel routeModel, [FromBody] BodyModel bodyModel)
{
return new JsonResult(new
{
ValueFromRoute = routeModel.ValueFromRoute,
ValueFromBody = bodyModel.ValueFromBody
});
}
}
public class RouteModel
{
public string ValueFromRoute { get; set; }
}
public class BodyModel
{
public string ValueFromBody { get; set; }
}
以与上面屏幕截图完全相同的方式调用它,按预期工作,将两个值填充到各自的对象上,并输出以下内容:
{
"valueFromRoute": "some-route-value",
"valueFromBody": "Some value from body"
}
所以我有一个潜在的解决方案,但它不是我的首选解决方案。理想情况下,如果可能的话,我想将路由和主体值绑定到同一个模型。
我在 GitHub 上找到了 this related question,这帮助我理解了正文必须反序列化为一个 class 对象,即使它只包含一个 属性,就像我上面的例子。
我上面示例的解决方案只是为要反序列化的主体创建一个新的 class,并将其添加到我的操作方法所期望的主模型中。
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost("{valueFromRoute}/post")]
public IActionResult Post(Model model)
{
return new JsonResult(model);
}
}
public class Model
{
[FromRoute]
public string ValueFromRoute { get; set; }
// Map body to simple class object rather than a primitive type
[FromBody]
public BodyModel BodyModel { get; set; }
}
public class BodyModel
{
public string ValueFromBody { get; set; }
}