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

我想处理以下API调用的POST:

/v1/location/deviceid/appid

其他参数来自后身。

这一切都适合我。 现在我想通过允许“deviceid”和/或“appid”和/或BodyData为空来扩展我的代码:

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

这3个url应该以相同的路线回应。

我的第一个方法(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); } 

这不起作用 – >“可选参数必须在最后”。

接下来尝试:

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

现在我的函数AddNewLocation()总是得到一个BodyData = null – 即使调用发送正文。

最后我设置全部3个参数可选:

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

不要工作:“FormatterParameterBinding”不支持可选参数“BodyData”。

为什么我想要可选参数的解决scheme?

我的控制器通过POST处理“添加一个新的位置”。

我想发送错误的数据我自己的例外或错误消息。 即使呼叫有缺失值。 在这种情况下,我想能够决定抛出一个例外或设置默认值由我的代码。

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

我认为你应该改变你的路由模板是[Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")] ,然后parsingdeiveOrAppid来确定id的types。

此外,您需要使路线模板本身中的线段可选,否则将根据需要对线段进行考虑。 注意? 在这种情况下的字符。 例如: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

另一个信息:如果你想使用路由约束 ,想象你需要强制该参数具有int数据types,那么你需要使用这个语法:

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

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

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

把我的评论转换成一个答案来补充@Kiran Chala的答案,因为这对观众来说似乎有帮助 –

当我们在动作uri中使用时将参数标记为可选参数? 字符,那么我们必须为方法签名中的参数提供默认值,如下所示MyMethod(string name = "someDefaultValue", int? Id = null)