当前位置: 动力学知识库 > 问答 > 编程问答 >

angularjs - Sending data from angular to c# api controller binds to wrong action

问题描述:

Question:

Why does my action Add gets hit instead of my delete action?

Error message:

"ExceptionMessage": "Multiple actions were found that match the

request: Add on type blog.Controllers.api.UsersController Delete on

type blog.Controllers.api.UsersController

My angular delete

$scope.delete = function (email) {

$http.post('/api/users/Delete', email).success(function() {

initData();

});

}

alternative tested

 //$http({

// url: '/api/users/Delete',

// method: 'POST',

// data: { 'userEmail': email }

// })

// .success(function(data, status, headers, config) {

// initData();

// }).

// error(function(data, status, headers, config) {

// $scope.showError = true;

// });

My MVC 5 api controller

 private readonly UserDataAccess _userDataAccess;

// GET: Users/Add

[HttpPost]

public HttpResponseMessage Add(User user)

{

_userDataAccess.AddUser(user);

return Request.CreateResponse(HttpStatusCode.OK);

}

// GET: Users/Delete - never gets hit

[HttpPost]

public HttpResponseMessage Delete([FromBody]string userEmail)

{

_userDataAccess.DelereUserByEmail(userEmail);

return Request.CreateResponse(HttpStatusCode.OK);

}

Please note I do not want to solve it using routing.

网友答案:

In WebApi you can only have one POST action per Routing. In order to have more than one for the controller class you will need to define new routings.

If you are using WebApi 2 you can benefit from the RoutingAttribute and define these new sub-routes

In your controller class use RoutePrefixAttributte:

[RoutePrefix('api/users')]
public class Users: ApiController{ ...

Followed by your 2 sub-routes:

[Route('add')]
[HttpPost]
public HttpResponseMessage Add(User user){..

[Route('delete')]
[HttpPost]
public HttpResponseMessage Delete([FromBody]string userEmail) {

About Routings

Web Api v1 defines resources globally in the global.asax on application_start event. Assuming you are using Visual Studio 2013 and based on Microsoft's default template your method may look like this:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

WebApi routing configuration occurs here WebApiConfig.Register while your MVC configuration occurs here RouteConfig.RegisterRoutes

Your WebApi routing configuration should look like this

public static class WebApiConfig{
        public static void Register(HttpConfiguration config){            
            config.Routes.MapHttpRoute(
                name: "apiSample",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = System.Web.Http.RouteParameter.Optional  }
            );

     ...

As mentioned previously WebApi v2 introduced the Route Attributes and those can be used along with your Controller class and can facilitate the routing configuration.

For example:

 public class BookController : ApiController{
     //where author is a letter(a-Z) with a minimum of 5 character and 10 max.      
    [Route("html/{id}/{newAuthor:alpha:length(5,10)}")]
    public Book Get(int id, string newAuthor){
        return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
    }

   [Route("json/{id}/{newAuthor:alpha:length(5,10)}/{title}")]
   public Book Get(int id, string newAuthor, string title){
       return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
   }
...

You may also refer this other POST with a similar question

How do I write REST service to support multiple Get Endpoints in .net MVC Web API

网友答案:
[HttpPost]
[Route('api/User/Delete/{userEmail}')]
public HttpResponseMessage Delete([FromBody]string userEmail)
{
}

You can manually configure the route as well

网友答案:

You can add the [HttpDelete] attribute on your delete method in your Api controller and then call it with $http.delete instead.

[HttpDelete]
public IHttpActionResult Delete(string email) {
    return StatusCode(HttpStatusCode.NoContent);
}

To quote the docs of HttpDeleteAttribute Class.

Represents an attribute that is used to restrict an action method so that the method handles only HTTP DELETE requests.

分享给朋友:
您可能感兴趣的文章:
随机阅读: