我正在使用属性路由创建一个新的webapi,以创建嵌套路由,如下所示:
// PUT: api/Channels/5/Messages
[ResponseType(typeof(void))]
[Route("api/channels/{id}/messages")]
public async Task<IHttpActionResult> PostChannelMessage(int id, Message message)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != message.ChannelId)
{
return BadRequest();
}
db.Messages.Add(message);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = message.Id }, message);
}
但是,我想返回一个不嵌套的路由,即:
/api/Messages/{id}
它定义在消息控制器上。然而,上面的CreatedAtRoute调用并不是解析这个路由,而是抛出。我是否做错了什么,还是它不支持路由到不同的api控制器?n.b.我试图选择的路径不是属性路由,而是默认的路由。
例外是:
消息:“发生了错误。”ExceptionMessage:"UrlHelper.Link不能返回null。“ExceptionType:"System.InvalidOperationException“StackTrace:”at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() cancellationToken) at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() -从以前抛出异常的位置开始的堆栈跟踪-在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task任务中抛出异常)--在System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext()“的System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()上。
如果它不支持这一点,那么返回201的标准方法是什么?我可以以重构安全的方式进行吗?
发布于 2014-05-01 22:20:01
哦,天哪,这可能是回答我自己问题的新记录。
return CreatedAtRoute("DefaultApi", new { controller = "messages", id = message.Id }, message);
就能做到这一点。即显式指定控制器。我看到异常与UrlHelper相关,并阅读它的文档.
发布于 2015-04-10 12:48:24
晚到派对了,但另一个答案是。如果要路由的操作也使用属性路由,则可以给路由一个名称并将其传递给CreatedAtRoute方法。这是通过在Name
上设置Route
属性来完成的。按照您的文章示例,请考虑以下操作。
// GET: api/Messages/5
[Route("api/messages/{id}", Name="GetMessage")]
public async Task<IHttpActionResult> GetMessage(int id)
{
// get the message
}
注意,路由属性[Route("api/messages/{id}", Name="GetMessage")]
上的[Route("api/messages/{id}", Name="GetMessage")]
属性设置为"GetMessage"
。通过这样做,我们可以从CreatedAtRoute
操作调用PostChannelMessage
方法,并传入路由名,如下所示:
return CreatedAtRoute("GetMessage", new { id = message.Id }, message);
这是我遇到的一个场景,我在这里搜索,所以我想我会张贴这个替代答案,以防它帮助其他人。
发布于 2017-08-08 16:47:43
只需添加上面的答案: on属性路由:
我被参数名捕获,花了一个小时才意识到参数需要正确命名,否则Url Helper将返回null。
也就是说,如果你有一种行动方法,比如:
[Route("api/messages/{id}", Name="GetAction")]
public IHttpActionResult GetEntity(int mySpecialUniqueId)
{
// do some work.
}
那么回报应该是:
return CreatedAtRoute("GetAction", new { mySpecialUniqueId = entity.Id }, entity);
在更简单的例子中,Id属性不断地抛出我,所以我想在这个答案中更多地扩展它,以帮助节省其他人在这个小问题上的时间。
有关更多细节,请参见这个更复杂的示例:
https://stackoverflow.com/questions/23417559
复制相似问题