WebApi ActionName 删除路由不起作用
WebApi ActionName delete route not working
我的项目包含多个 WebApi 控制器,每个控制器通常提供三个操作:get(guid)、post(data) 和 delete(guid),
WebApiconfig
中针对此要求描述了默认路由。 (姓名:ControllerAndId
)
现在我必须实现一个控制器,它必须处理不同的 post 操作。对于此要求,我尝试使用 ActionNames
映射另一条路线。 (姓名:ControllerAndActionAndId
)
因为我已经映射了 ControllerAndActionAndId
路由,所以无法调用 "normal" 控制器的删除路由(示例:Contactscontroller
)。
所有路由除了删除路线外都在工作。
StatusCode: 404, ReasonPhrase: 'Not Found'
通常有一个 ApiController 的例子:
public class ContactsController : ApiController
{
public IEnumerable<Contact> Get()
{
return GetContacts();
}
public HttpResponseMessage Post(Contact contact)
{
SaveContact(contact);
return Request.CreateResponse<Guid>(_code, contact.Id);
}
public void Delete(Guid id)
{
DeleteContact(id);
}
}
具有 ActionName-Route 的控制器:
public class AttachmentsController : ApiController
{
[HttpGet]
public Attachment Get(Guid attachmentId)
{
return GetAttachment(attachmentId);
}
[HttpPost]
[ActionName("save")]
public HttpResponseMessage Save(AttachmentSaveData saveData)
{
SaveAttachment(saveData);
}
[HttpPost]
[ActionName("remove")]
public HttpResponseMessage Remove(AttachmentDeleteData deleteData)
{
DeleteAttachment(deleteData);
}
}
WebApiConfig:
// Web API routes
config.MapHttpAttributeRoutes();
// Controller with ID
// To handle routes like `/api/VTRouting/route/1`
config.Routes.MapHttpRoute(
name: "ControllerAndActionAndId",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new
{
id = RouteParameter.Optional,
action = RouteParameter.Optional
}
);
// Controller with ID
// To handle routes like `/api/VTRouting/1`
config.Routes.MapHttpRoute(
name: "ControllerAndId",
routeTemplate: "api/{controller}/{id}",
defaults: new
{
id = RouteParameter.Optional
}
);
ClientAction 删除函数:
private void Delete(string uri, int id)
{
using (HttpClient _client = new HttpClient())
{
_client.BaseAddress = BaseAddress;
string _url = string.Format("{0}/{1}", uri, id);
var _response = _client.DeleteAsync(_url).Result;
if (!_response.IsSuccessStatusCode)
{
throw new Exception();
}
}
}
我目前还不知道如何解决这个问题。
如果您使用 Web API,您需要在操作中添加 HTTP 动词。
例如,您的代码必须如下所示:
public class ContactsController : ApiController
{
[HttpGet]
public IEnumerable<Contact> Get()
{
return GetContacts();
}
[HttpPost]
public HttpResponseMessage Post(Contact contact)
{
SaveContact(contact);
return Request.CreateResponse<Guid>(_code, contact.Id);
}
[HttpDelete]
public void Delete(Guid id)
{
DeleteContact(id);
}
}
注意删除操作。
- 如果您在操作上使用 HttpDelete 动词,则必须从您的客户端发送删除请求
httpClient.DeleteAsync(...)
。
- 如果您在操作中使用 HttpPost 动词,则必须从您的客户端
httpClient.PostAsync(...)
发送 post 请求。
AttachmentsController 类似于 ContactsController。
我非常关注控制器的动作和路线。
但是在客户端很容易找到解决方案:
private void Delete<T>(string uri, T value)
{
using (HttpClient _client = new HttpClient())
{
_client.BaseAddress = BaseAddress;
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string _url = string.Format("{0}/{1}", uri, value);
var _response = _client.DeleteAsync(_url).Result;
}
}
此解决方案只需要 WebApiConfig 中的一个路由:
config.Routes.MapHttpRoute(
name: "ControllerAndId",
routeTemplate: "api/{controller}/{id}",
defaults: new
{
id = RouteParameter.Optional
}
);
太简单了..非常感谢!
我的项目包含多个 WebApi 控制器,每个控制器通常提供三个操作:get(guid)、post(data) 和 delete(guid),
WebApiconfig
中针对此要求描述了默认路由。 (姓名:ControllerAndId
)
现在我必须实现一个控制器,它必须处理不同的 post 操作。对于此要求,我尝试使用 ActionNames
映射另一条路线。 (姓名:ControllerAndActionAndId
)
因为我已经映射了 ControllerAndActionAndId
路由,所以无法调用 "normal" 控制器的删除路由(示例:Contactscontroller
)。
所有路由除了删除路线外都在工作。
StatusCode: 404, ReasonPhrase: 'Not Found'
通常有一个 ApiController 的例子:
public class ContactsController : ApiController
{
public IEnumerable<Contact> Get()
{
return GetContacts();
}
public HttpResponseMessage Post(Contact contact)
{
SaveContact(contact);
return Request.CreateResponse<Guid>(_code, contact.Id);
}
public void Delete(Guid id)
{
DeleteContact(id);
}
}
具有 ActionName-Route 的控制器:
public class AttachmentsController : ApiController
{
[HttpGet]
public Attachment Get(Guid attachmentId)
{
return GetAttachment(attachmentId);
}
[HttpPost]
[ActionName("save")]
public HttpResponseMessage Save(AttachmentSaveData saveData)
{
SaveAttachment(saveData);
}
[HttpPost]
[ActionName("remove")]
public HttpResponseMessage Remove(AttachmentDeleteData deleteData)
{
DeleteAttachment(deleteData);
}
}
WebApiConfig:
// Web API routes
config.MapHttpAttributeRoutes();
// Controller with ID
// To handle routes like `/api/VTRouting/route/1`
config.Routes.MapHttpRoute(
name: "ControllerAndActionAndId",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new
{
id = RouteParameter.Optional,
action = RouteParameter.Optional
}
);
// Controller with ID
// To handle routes like `/api/VTRouting/1`
config.Routes.MapHttpRoute(
name: "ControllerAndId",
routeTemplate: "api/{controller}/{id}",
defaults: new
{
id = RouteParameter.Optional
}
);
ClientAction 删除函数:
private void Delete(string uri, int id)
{
using (HttpClient _client = new HttpClient())
{
_client.BaseAddress = BaseAddress;
string _url = string.Format("{0}/{1}", uri, id);
var _response = _client.DeleteAsync(_url).Result;
if (!_response.IsSuccessStatusCode)
{
throw new Exception();
}
}
}
我目前还不知道如何解决这个问题。
如果您使用 Web API,您需要在操作中添加 HTTP 动词。
例如,您的代码必须如下所示:
public class ContactsController : ApiController
{
[HttpGet]
public IEnumerable<Contact> Get()
{
return GetContacts();
}
[HttpPost]
public HttpResponseMessage Post(Contact contact)
{
SaveContact(contact);
return Request.CreateResponse<Guid>(_code, contact.Id);
}
[HttpDelete]
public void Delete(Guid id)
{
DeleteContact(id);
}
}
注意删除操作。
- 如果您在操作上使用 HttpDelete 动词,则必须从您的客户端发送删除请求
httpClient.DeleteAsync(...)
。 - 如果您在操作中使用 HttpPost 动词,则必须从您的客户端
httpClient.PostAsync(...)
发送 post 请求。
AttachmentsController 类似于 ContactsController。
我非常关注控制器的动作和路线。 但是在客户端很容易找到解决方案:
private void Delete<T>(string uri, T value)
{
using (HttpClient _client = new HttpClient())
{
_client.BaseAddress = BaseAddress;
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string _url = string.Format("{0}/{1}", uri, value);
var _response = _client.DeleteAsync(_url).Result;
}
}
此解决方案只需要 WebApiConfig 中的一个路由:
config.Routes.MapHttpRoute(
name: "ControllerAndId",
routeTemplate: "api/{controller}/{id}",
defaults: new
{
id = RouteParameter.Optional
}
);
太简单了..非常感谢!