[英]Route attribute Name property
我有ProductsController和OwnersController:
public class ProductsController : ApiController
{
//constructor is here
// GET /api/products
public IHttpActionResult GetProducts()
{
return Ok(new ApiResponse());
}
// GET /api/products/{productCode}
[HttpGet, Route("api/products/{productCode}")]
public IHttpActionResult GetProductByCode(string productCode)
{
return Ok(new ApiResponse());
}
// POST /api/products
public IHttpActionResult PostProduct(Product product /*my class*/)
{
return CreatedAtRoute("DefaultApi", new { id = product.Id }, product);
}
}
它运作完美。 但是现在我创建了第二个控制器并执行相同的操作,但是尝试POST方法时出现错误。 另一种方法效果很好!
让我们先看一下代码:
public class OwnersController : ApiController
{
// constructor
// GET /api/owners/{label}
// GET /api/owners/{label}?skip=1&take=4
[Route("api/owners/{label}")]
public IHttpActionResult GetOwnersExamples(string label, int skip=0, int take=10)
{
return Ok(new ApiResponse());
}
// POST /api/owners/{productCode}
//[HttpPost]
[Route("api/owners/{productCode}"/*, Name = "CreateOwner"*/)]
public IHttpActionResult PostOwner(string productCode, Owner owner)
{
return CreatedAtRoute("DefaultApi", new { id = Owner.Id }, owner);
}
}
错误信息:
UrlHelper.Link不得返回null
我的RouteConfig :
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
据我了解的问题, CreateAtRoute
方法必须获取另一个RouteName
。 如您所见,我可以通过添加Route Name参数(现在进行注释)并用"CreateOwner"
替换"DefaultApi"
来解决该问题,但是它看起来像是一种黑客。 我相信还有另一种方法可以避免Name Property
。
PS看起来我的Web API只能看到第一个控制器(ProductsController)-如果删除明确的Route [Route("...")]
...,其他任何方法都将不起作用...
据我了解的问题,CreateAtRoute方法必须获取另一个RouteName。 如您所见,我可以通过添加Route Name参数(现在进行注释)并用“ CreateOwner”替换“ DefaultApi”来解决该问题,但是它看起来像是一种黑客。 我相信还有另一种避免名称属性的方法。
您的理解几乎是正确的。 但是,您不应为当前路由指定名称,而应为指向已创建资源的名称指定名称。 CreatedAtRoute
填充响应位置标头,该标头应包含新创建资源的可GET URI。
这是一个工作示例:
[HttpGet]
[Route("api/owners/{id}", Name = "GetOwnerById")]
public IHttpActionResult GetOwner(int id)
{
// Obtain the owner by id here
return Ok(new ApiResponse());
}
[HttpPost]
[Route("api/owners/{productCode}"/*, Name = "CreateOwner"*/)]
public IHttpActionResult PostOwner(string productCode, Owner owner)
{
return CreatedAtRoute("GetOwnerById", new { id = owner.Id }, owner);
}
(注意:要使此示例正常工作,您应该注释GetOwnersExamples
操作,否则多个操作将与您的GET请求匹配。)
您说它看起来很像黑客,但事实并非如此。 CreatedAtRoute
将路由名称作为参数,您应该提供它。 否则,将如何选择适当的操作并构建Location
标头?
我使用以下步骤解决问题:
[RoutePrefix]
-默认情况下让它们工作-完全适合简单的请求。 api/controller/{label}
和api/controller/{parameter}
路由的方法-它无法理解默认使用哪种方法。 (或使用显式uri: api/controller?label=1
) 所有这些操作使我可以删除多余的属性,并使方法更具可读性。
结果如下:
public IHttpActionResult PostOwner(OwnerWrapper modelWrapper)
{
string productCode = modelWrapper.Product.Code;
Owner owner = modelWrapper.Owners[0];
return CreatedAtRoute("DefaultApi", new { id = Owner.Id }, owner);
}
这只是测试用例,因此我们可以看到productCode
从未使用过,但是我真正的实现更加困难。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.