我在WebApiConfig
文件中配置了以下路由配置,以通过实际方法(操作)名称以及默认调用模式来调用web api控制器方法。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
//By specifying action name
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Default calling pattern
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "DefaultAction", id = RouteParameter.Optional }
);
}
}
以下是控制器
public class TestController
{
List<int> _lst;
[ActionName("DefaultAction")]
public HttpResponseMessage Get()
{
_lst = new List<int>() { 1, 2, 3, 4, 5 };
return ToJson(_lst);
}
[ActionName("DefaultAction")]
public HttpResponseMessage Post(int id)
{
_lst.Add(id);
return ToJson(1);
}
[ActionName("DefaultAction")]
public HttpResponseMessage Put(int id)
{
//doing sothing
return ToJson(1);
}
[ActionName("DefaultAction")]
public HttpResponseMessage Delete(int id)
{
//doing sothing
return ToJson(1);
}
public HttpResponseMessage Save(int id)
{
//doing sothing
return ToJson(1);
}
private HttpResponseMessage ToJson(dynamic obj)
{
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");
return response;
}
}
使用以下网址调用webapi控制器Post
或“获取”方法可以正常工作。
POST - &gt; http://localhost:56114/api/Test/
GET - &gt; http://localhost:56114/api/Test/
使用以下网址调用webapi控制器Save
方法也可以正常工作。
POST - &gt; http://localhost:56114/api/Test/Save/1
但是当我通过下面的给定url调用api控制器的PUT或DELETE方法时,它不会调用任何(PUT / DELETE)方法
PUT - &gt; http://localhost:56114/api/Test/3
DELETE - &gt; http://localhost:56114/api/Test/4
它提供以下错误消息
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:56114/api/Test/3'.",
"MessageDetail": "No action was found on the controller 'Test' that matches the name '3'."
}
任何人都可以帮助我解决为什么PUT和DELETE方法没有被默认的URL模式调用。
我想通过使用以下网址格式
来调用我上面的所有方法POST -> http://localhost:56114/api/Test/ -> should call Post
GET -> http://localhost:56114/api/Test/ -> should call Get
PUT -> http://localhost:56114/api/Test/3 -> should call Put
DELETE -> http://localhost:56114/api/Test/4 -> should call Delete
POST -> http://localhost:56114/api/Test/Save/1 -> should call Save
答案 0 :(得分:1)
看起来PUT和DELETE的请求路径与&#34; api / {controller} / {action} / {id}&#34;的路由模板匹配。即使请求路径可以匹配任何已定义的路由模板,也可以使用&#34; MapHttpRoute()&#34;注册的模板。首先要优先考虑。以下是路由解释PUT和DELETE请求路径的方法:
PUT:/ api / Test / 3 - &gt; / API /&LT;控制器&GT; /&lt;作用&GT;
DELETE:/ api / Test / 4 - &gt; / API /&LT;控制器&GT; /&lt;作用&GT;
使用可选的&#34; id&#34;在这种情况下已被忽略的值。
您可以通过切换路线的注册顺序来解决此问题,但这可能会影响您未在此处列出的其他路线。或者,您可以将目标操作显式添加到请求路径中:
PUT:/ api / Test / DefaultAction / 3 - &gt; / API /&LT;控制器&GT; /&lt;作用&GT; /&LT; ID&GT;
DELETE:/ api / Test / DefaultAction / 4 - &gt; / API /&LT;控制器&GT; /&lt;作用&GT; /&LT; ID&GT;
您对GET和POST的请求正在运行,因为路径与第二个路由模板匹配,并且可选&#34; action&#34;和&#34; id&#34;参数。使用&#34; id&#34;在PUT和DELETE命令中,请求路径匹配第一个路径模板。
我也不确定为什么&#34; Save&#34;在您的示例中成功调用了操作(除非您有一个名为&#34的控制器; SaveController&#34;您没有在此处显示)。根据您的路由逻辑,路径将被解释为:
/ api / Save / 1 - &gt; / API /&LT;控制器&GT; /&lt;作用&GT;
所以&#34; Save&#34;方法&#34; TestController&#34;实际上并没有被这个请求调用。
答案 1 :(得分:1)
转换为答案。
我认为你使用的ActionNameAtrribute
来自MVC,而不是web api,所以删除它,在这种情况下它不会做任何事情。
以下是我认为适合您的事情:
[HttpGet]
public HttpResponseMessage Get()
{
_lst = new List<int>() { 1, 2, 3, 4, 5 };
return ToJson(_lst);
}
[HttpPost]
public HttpResponseMessage Post(int id)
{
_lst.Add(id);
return ToJson(1);
}
[HttpPut]
public HttpResponseMessage Put(int id)
{
//doing sothing
return ToJson(1);
}
[HttpDelete]
public HttpResponseMessage Delete(int id)
{
//doing sothing
return ToJson(1);
}
[HttpPost, Route("~/api/tests/save/{id}")]
public HttpResponseMessage Save(int id)
{
//doing sothing
return ToJson(1);
}
webapiconfig.cs:
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
现在应该可以使用以下模式,请注意我已修改了您的第一个post
调用,因为参数id
已存在。
POST -> http://localhost:56114/api/Test/1 -> should call Post
GET -> http://localhost:56114/api/Test/ -> should call Get
PUT -> http://localhost:56114/api/Test/3 -> should call Put
DELETE -> http://localhost:56114/api/Test/4 -> should call Delete
POST -> http://localhost:56114/api/Test/Save/1 -> should call Save
您仍然会应用默认路由以及更具体的api/{controller}/{action}/{id}
路由。