Optional Parameters in Web Api Attribute Routing

I want to handle POST of the following API-Call:

/v1/location/deviceid/appid

Additional Parameter are coming from the Post-Body.

This all works fine for me. Now I wnat to extend my code by allowing "deviceid" and/or "appid" and/or BodyData to be null:

/v1/location/deviceid
/v1/location/appid
/v1/location/

These 3 URLs should responded by the same route.

My first approach (BodyData required):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData)
{
return repository.AddNewLocation(deviceid, appid, BodyData);
}

This does not work and returns a compile error:

"optional Parameters must be at the end"

Next try:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null)

Now my function AddNewLocation() get always an BodyData=null - even if the call send the Body.

Finally I set all 3 Parameter optional:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null)

Don´t work:

Optional parameter BodyData is not supported by FormatterParameterBinding.

Why do I want a solution with optional Parameters? My Controller handles just the "adding of a new Location" via a POST.

I want to send on wrong data my own exceptions or error messages. Even if the call has missing values. In this case I want to be able to decide to throw an exception or Setting Defaults by my code.

158903 次浏览

对于像 /v1/location/1234这样的传入请求,可以想象,Web API 很难自动计算出对应于“1234”的段的值是否与 appid相关,而不是与 deviceid相关。

我觉得你应该把你的路线模板改成 然后解析 deiveOrAppid以找出 id 的类型。

此外,您还需要使路由模板本身中的段成为可选的,否则这些段将被认为是必需的。请注意本例中的 ?字符。 For example: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

另一个信息: 如果你想使用 路线约束,假设你想强制参数具有 Int数据类型,那么你需要使用这样的语法:

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")]

?字符总是放在最后一个 }字符之前

有关更多信息,请参见: 可选 URI 参数和默认值

补充@Kiran Chala 的回答的另一个事实-

当我们使用 ?字符(对于 可为空的值类型)在动作 URI 中将任何参数(appid)标记为可选参数时,我们必须为方法签名中的参数提供默认值,如下所示:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid, int? appid = null)

好吧,我跌倒在这里与我的互联网研究,我继续我的方式,因为接受的解决方案不与 dotnet 核心3.1工作。 所以这里是我的解决方案,以下是本文档

[HttpPost]
[Route("{name}")]
[Route("{name}/parent/{parentId}")]
public async Task<IActionResult> PostSomething(string name, Guid? parentId = null)
{
return Ok(await Task.FromResult(new List<string>()));
}

通过这种方式,许多路由到这个单一的 API 函数