【发布时间】:2016-06-07 09:25:19
【问题描述】:
WebAPI 2 智能地处理操作方法上的 Async 后缀。例如,如果我创建一个默认的 WebAPI 项目,它将路由到正确的操作,而不管后缀如何。即:
http://host/api/controller/action - SUCCEEDS
http://host/api/controller/actionAsync - SUCCEEDS
但是,如果我使用 MVC 5 创建等效控制器,则行为会有所不同:
http://host/controller/actionAsync - SUCCEEDS
http://host/controller/action - FAILS - 404
当 Async 后缀不存在时,它会以 404 失败,这一事实令人惊讶。尽管如此,我尝试添加一个路由来处理它,但它仍然失败:
routes.MapRoute(
name: "DefaultAsync",
url: "{controller}/{action}Async/{id}",
defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
这是我用来测试的 MVC 和 WebAPI 控制器(基于具有默认路由的新 MVC/WebAPI 项目):
public class SampleDto { public string Name; public int Age; }
public class SampleMvcController : Controller
{
public Task<JsonResult> GetJsonAsync()
{
// Illustration Only. This is not a good usage of an Async method,
// in reality I'm calling out to an Async service.
return Task.FromResult(
Json(new SampleDto { Name="Foo", Age = 42}, JsonRequestBehavior.AllowGet));
}
}
public class SampleWebApiController : ApiController
{
public Task<SampleDto> GetJsonAsync()
{
return Task.FromResult(new SampleDto {Name="Bar", Age=24});
}
}
由于我正在使一堆方法异步,我不想指定操作名称。 routing documentation 建议它可以拾取可以分隔段的文字,但我还没有运气。
更新:
问题是 MVC 检索到的 Action 包含 Async 后缀,但控制器上不存在相应的操作(或操作名称)。与动作匹配的片段MyAction 不会将MyActionAsync 识别为匹配项。
回想起来,这就是该路线行不通的原因。它尝试将操作标识为以 Async 结尾,但从匹配中使用的操作中去掉 Async 后缀,这不是我想要做的。如果我只想创建一个 MyAction 方法(这是异步但不遵循 Async 命名约定)并将其映射到相应的 MyAction 方法,这将很有用。
【问题讨论】:
-
您是否将您发布的路线放在默认路线之前?
-
@NightOwl888 - 是的,之前订购过。我已更新帖子以更好地描述实际问题。
-
所以,我认为你最初所说的,你的 xxxAsync 操作成功是不正确的?您的更新与您最初所说的直接矛盾。
-
@NightOwl888 - 不,它是正确的。当 URL 包含
<action>Async而不是当 URL 仅包含<action>时,它会成功(即返回 200)。我的目标是让 MVC 看到方法<action>Async对应于从 URL 检索到的<action>所以我不需要(a)用动作名称装饰无数方法,或者(b)违反异步命名约定。
标签: asp.net-mvc asp.net-web-api asp.net-mvc-5 asp.net-mvc-routing asp.net-web-api2