我有一个MVC Web Api RESTful服务。我没有使用API版本2.
我使用默认的GET / POST / PUT / DELETE创建了一个Controller。一切都很好,直到我决定为我的控制器添加更多功能。
长话短说,我最终为我的控制器准备了十几个路线模板(非常讨厌的WebApiConfig文件)。它工作正常,直到....我需要第二个控制器。然后混乱就开始了。
DocumentController的所有路由显然不适用于CompanyController,因为我之前配置的只是一堆糟糕的补丁,使我的第一个Controller工作。我在这里四天后仍然无法上班。我真的无法理解这整个路由的事情。如此复杂和不灵活(在我看来)。
以下是一些供您理解的代码。
public class DocumentController : ApiController
{
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK,"This is GET");
}
[HttpGet]
public HttpResponseMessage Metadata()
{
return Request.CreateResponse(HttpStatusCode.OK,"This is Metadata");
}
public HttpResponseMessage Get(int id)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is GET with ID");
}
public HttpResponseMessage Post([FromBody] DocumentDTO document)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is Post");
}
public HttpResponseMessage Put(int id, [FromBody] DocumentDTO document)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is PUT");
}
[HttpGet]
public HttpResponseMessage Tags(int id)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is GET TAGS");
}
[HttpPost]
public HttpResponseMessage Tags(int id, [FromBody] IEnumerable<TagDefinitionDTO> tagDefinitions)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is POST TAGS");
}
}
所以,我最初的梦想是实现以下目标
GET /document/
=&gt;所有文件
GET /document/3
=&gt;文件ID = 3
POST /document/
=&gt;创建文档
PUT /document/3
=&gt;编辑文件
GET /document/metadata
=&gt;退回所有DOC的一般配置
GET /document/6/tags
=&gt;获取文件ID = 6的所有标签
POST /document/6/tags
=&gt;为文件ID = 6创建标签
我甚至没有发布WebApi,因为它非常令人尴尬。就像我说的,我能够使用额外的方法,但它几乎是一对一的映射到我的控制器/动作。 AWFUL ......我知道。
当我添加第二个控制器......显然......不可能的任务。
现在,不要让你认为我没有做过一些研究(我已经使用过约束,默认等等,但是没有用...可怜)。一旦我让一个控制器工作,另一个打破。
我遇到各种各样的错误。从“多个GET方法”到“未找到资源”,“方法现在允许POST”。
我在这里,五天后进入圈子。这非常令人沮丧。
问题。
有没有人遇到过这些问题?路由协议SO是否限制每个控件只能进行4次操作?我应该在我的控制器中创建一个路径模板PER动作,这意味着如果我有10个控制器有10个动作,我应该添加100个路径模板吗?
答案 0 :(得分:1)
是的,您可以切换到使用属性路由。
然后在每个动作或控制器上,您只需放置路径模板。
或以下路线应该适合您
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi1",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"\d+" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: null,
constraints: new { id = @"\d+" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi3",
routeTemplate: "api/{controller}/{action}",
defaults: new {id = RouteParameter.Optional}
);
答案 1 :(得分:1)
根据Yishai的回答,我认为将您的路线更改为以下内容应适合您的情况:
config.Routes.MapHttpRoute(
name: "DefaultApi1",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "Default" },
constraints: new { id = @"\d*" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{action}",
defaults: null,
constraints: new { action = @"[a-zA-Z]+" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi3",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: null,
constraints: new { id = @"\d+", action = @"[a-zA-Z]+" }
);
然后在默认操作中放置一个ActionName属性。
public class DocumentController : ApiController
{
[ActionName("Default")]
[HttpGet]
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK,"This is GET");
}
[HttpGet]
public HttpResponseMessage Metadata()
{
return Request.CreateResponse(HttpStatusCode.OK,"This is Metadata");
}
[ActionName("Default")]
[HttpGet]
public HttpResponseMessage Get(int id)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is GET with ID");
}
[ActionName("Default")]
[HttpPost]
public HttpResponseMessage Post([FromBody] DocumentDTO document)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is Post");
}
[ActionName("Default")]
[HttpPut]
public HttpResponseMessage Put(int id, [FromBody] DocumentDTO document)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is PUT");
}
[HttpGet]
public HttpResponseMessage Tags(int id)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is GET TAGS");
}
[HttpPost]
public HttpResponseMessage Tags(int id, [FromBody] IEnumerable<TagDefinitionDTO> tagDefinitions)
{
return Request.CreateResponse(HttpStatusCode.OK, "This is POST TAGS");
}
}
如上所述,Web API 2是一种更好的方法。