简体   繁体   English

Web Api 属性路由中的可选参数

[英]Optional Parameters in Web Api Attribute Routing

I want to handle POST of the following API-Call:我想处理以下 API 调用的 POST:

/v1/location/deviceid/appid

Additional Parameter are coming from the Post-Body.附加参数来自 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:现在我想通过允许“deviceid”和/或“appid”和/或 BodyData 为空来扩展我的代码:

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

These 3 URLs should responded by the same route.这 3 个 URL 应该由相同的路由响应。

My first approach (BodyData required):我的第一种方法(需要 BodyData):

[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.现在我的函数 AddNewLocation() 总是得到一个BodyData=null - 即使调用发送 Body。

Finally I set all 3 Parameter optional:最后,我将所有 3 个参数设置为可选:

[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 . FormatterParameterBinding不支持可选参数BodyData

Why do I want a solution with optional Parameters?为什么我需要带有可选参数的解决方案? My Controller handles just the "adding of a new Location" via a POST.我的控制器仅通过 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.在这种情况下,我希望能够决定通过我的代码抛出异常或设置默认值。

For an incoming request like /v1/location/1234 , as you can imagine it would be difficult for Web API to automatically figure out if the value of the segment corresponding to '1234' is related to appid and not to deviceid .对于像/v1/location/1234这样的传入请求,您可以想象,Web API 很难自动确定对应于 '1234' 的段的值是否与appid相关而不与deviceid

I think you should change your route template to be like [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")] and then parse the deiveOrAppid to figure out the type of id.我认为您应该将您的路线模板更改为[Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]然后解析deiveOrAppid以找出 id 的类型。

Also you need to make the segments in the route template itself optional otherwise the segments are considered as required.此外,您还需要将路线模板本身中的段设为可选,否则这些段被视为必需的。 Note the ?注意? character in this case.在这种情况下的字符。 For example: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]例如: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

Another info: If you want use a Route Constraint , imagine that you want force that parameter has int datatype, then you need use this syntax:另一个信息:如果您想使用Route Constraint ,请想象您希望强制该参数具有int数据类型,那么您需要使用以下语法:

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

The ? ? character is put always before the last } character字符总是放在最后一个}字符之前

For more information see: Optional URI Parameters and Default Values有关更多信息,请参阅: 可选 URI 参数和默认值

Converting my comment into an answer to complement @Kiran Chala's answer as it seems helpful for the audiences-将我的评论转换为答案以补充@Kiran Chala 的答案,因为它似乎对观众有帮助-

When we mark a parameter as optional in the action uri using ?当我们在动作 uri 中使用? character then we must provide default values to the parameters in the method signature as shown below:字符,那么我们必须为方法签名中的参数提供默认值,如下所示:

MyMethod(string name = "someDefaultValue", int? Id = null)

Ok, I fallen here with my internet research and I continue my way, because the accepted solution not working with dotnet core 3.1.好的,我在互联网研究中陷入了困境,我继续我的方式,因为公认的解决方案不适用于 dotnet core 3.1。 So here is my solution, following this doc所以这是我的解决方案,遵循这个文档

[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>()));
}

By this way many routes go to this single API function通过这种方式,许多路由都转到这个单一的 API 函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM