Web Api 中的 MVC 5 属性路由 space
MVC5 Attribute Routing in WebApi space
我正在使用 MVC 控制器在 Web Api 中创建动态 JavaScript 文件(我对那部分不满意,但我试图保持与以前版本的兼容性) ] 项目...
客户正在消费 URL 比如:
~/api/assessments/{id:int}.js?locale={locale?}
我创建了一个 MVC JavaScriptController
并添加了如下方法:
[Route("~/api/data/{id:int}.js")]
public async Task<PartialViewResult> GetData(int id, string locale)
{
try
{
Response.ContentType = "application/javascript";
ViewBag.Locale = locale ?? "en";
var model = await this._dataService.GetData(id.ToString());
return PartialView(model);
}
catch (Exception ex)
{
this._logger.Error("Task<PartialViewResult> GetData(int, string)", ex);
return PartialView("JavaScriptError", SelectException(ex));
}
}
然而,当我尝试调用此调用时,我收到 404:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://.../api/data/29.js?locale=en'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'data'.
</MessageDetail>
</Error>
我认为 WebApi“~/api”前缀正在走 MVC 5 路线,尽管我认为它可能是完全不同的东西。如何在指定的 URL 处呈现此 MVC 视图?
你在路线登记时打电话给MapHttpAttributeRoutes()
吗?
见http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#why
您不需要在路由中包含查询字符串参数或相对路径:
[Route("api/data/{id:int}.js")]
protected async Task<PartialViewResult> GetData(int id, string locale)
{
try
{
Response.ContentType = "application/javascript";
ViewBag.Locale = locale ?? "en";
var model = await this._dataService.GetData(id.ToString());
return PartialView(model);
}
catch (Exception ex)
{
this._logger.Error("Task<PartialViewResult> GetData(int, string)", ex);
return PartialView("JavaScriptError", SelectException(ex));
}
}
因为只有 API 的特定部分实际上是模板化的("file" 的名称),所以您只需要将其作为路线的一部分。
但是,您仍然会 运行 遇到以下问题:.NET 会尝试将对 .js 的请求视为对文件的请求。
为此,您可能需要启用 relaxed filesystem mapping:
<httpRuntime relaxedUrlToFileSystemMapping="true" />
但是,您确实需要了解 security implications 启用此功能。如果您没有正确设置 NTFS 权限,您将面临潜在的攻击,远程用户可以访问您文件系统上的文件。
好吧,看来我是对的; WebApi 路由机制基于 MVC 属性路由。最终,我不得不在 WebApiConfig.cs
文件中注释掉以下行:
//config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new {id = RouteParameter.Optional});
之后,MVC 路由按预期工作。
我正在使用 MVC 控制器在 Web Api 中创建动态 JavaScript 文件(我对那部分不满意,但我试图保持与以前版本的兼容性) ] 项目...
客户正在消费 URL 比如:
~/api/assessments/{id:int}.js?locale={locale?}
我创建了一个 MVC JavaScriptController
并添加了如下方法:
[Route("~/api/data/{id:int}.js")]
public async Task<PartialViewResult> GetData(int id, string locale)
{
try
{
Response.ContentType = "application/javascript";
ViewBag.Locale = locale ?? "en";
var model = await this._dataService.GetData(id.ToString());
return PartialView(model);
}
catch (Exception ex)
{
this._logger.Error("Task<PartialViewResult> GetData(int, string)", ex);
return PartialView("JavaScriptError", SelectException(ex));
}
}
然而,当我尝试调用此调用时,我收到 404:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://.../api/data/29.js?locale=en'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'data'.
</MessageDetail>
</Error>
我认为 WebApi“~/api”前缀正在走 MVC 5 路线,尽管我认为它可能是完全不同的东西。如何在指定的 URL 处呈现此 MVC 视图?
你在路线登记时打电话给MapHttpAttributeRoutes()
吗?
见http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#why
您不需要在路由中包含查询字符串参数或相对路径:
[Route("api/data/{id:int}.js")]
protected async Task<PartialViewResult> GetData(int id, string locale)
{
try
{
Response.ContentType = "application/javascript";
ViewBag.Locale = locale ?? "en";
var model = await this._dataService.GetData(id.ToString());
return PartialView(model);
}
catch (Exception ex)
{
this._logger.Error("Task<PartialViewResult> GetData(int, string)", ex);
return PartialView("JavaScriptError", SelectException(ex));
}
}
因为只有 API 的特定部分实际上是模板化的("file" 的名称),所以您只需要将其作为路线的一部分。
但是,您仍然会 运行 遇到以下问题:.NET 会尝试将对 .js 的请求视为对文件的请求。
为此,您可能需要启用 relaxed filesystem mapping:
<httpRuntime relaxedUrlToFileSystemMapping="true" />
但是,您确实需要了解 security implications 启用此功能。如果您没有正确设置 NTFS 权限,您将面临潜在的攻击,远程用户可以访问您文件系统上的文件。
好吧,看来我是对的; WebApi 路由机制基于 MVC 属性路由。最终,我不得不在 WebApiConfig.cs
文件中注释掉以下行:
//config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new {id = RouteParameter.Optional});
之后,MVC 路由按预期工作。