WebAPI ActionName routing half working

2019-07-22 17:44发布

I have been building a WebAPI, trying to route to the right methods with ActionName. It works with one of my methods I try to call, but the other one gets a 404 error.

My WebAPI Config file:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

My WebAPI Controller methods are formatted as such:

This first one is the working one:

[ActionName("postdb")]
public IEnumerable<string[]> postDB(string id)
{ ...

This second one does not:

[ActionName("getquery")]
public IEnumerable<string[]> getQuery(string tables)
{ ...

I'm calling both of them the same way from angular (Temp is a string that is being passed as the argument):

$http.post('api/Test/postdb/' + temp).then(function (response) { ...

and

$http.get('api/Test/getquery/' + temp).then(function (response) { ...

I have tried changing names of both actions, the first one works no matter the name, the second one doesn't work no matter the name. I have also tried reordering them, changing between GET and POST, and changing arguments.

Any suggestions?

2条回答
Evening l夕情丶
2楼-- · 2019-07-22 18:02

Not sure why you are using ActionName to setup routing?

You should probably be looking at Route attribute. eg.

[HttpPost]
[Route("postdb")]
// Action doesn't have to be called 'postdb'
public IEnumerable<string[]> postDB(string id)

ActionName is usually used for a different purpose (Purpose of ActionName)

Nevertheless, I think something odd is going on in your example - I'd think setting ActionName shouldn't have affected routing there. To debug I'd suggest to set up Failed Request Tracing to see at which point the request fails to reach the action.

These are the basic rules for Action selection in WebAPI (http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection)

  1. You can specify the HTTP method with an attribute: AcceptVerbs, HttpDelete, HttpGet, HttpHead, HttpOptions, HttpPatch, HttpPost, or HttpPut.

  2. Otherwise, if the name of the controller method starts with "Get", "Post", "Put", "Delete", "Head", "Options", or "Patch", then by convention the action supports that HTTP method.

  3. If none of the above, the method supports POST.

So, in your example postdb method may map to the POST method. But may be because it's in lower case ASP.NET didn't like that and applied Rule 3 - try with ActionName("PostDB") and [ActionName("GetQuery")] if you really want to use ActionName (for whatever reason) instead of Route.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-07-22 18:04

The name of the parameter tables in the second action

[ActionName("getquery")]
public IEnumerable<string[]> getQuery(string tables)
{ ...

does not match the name of the parameter id in the route:

config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
查看更多
登录 后发表回答