简体   繁体   中英

Web api routing fails in asp.net MVC 5

I have a asp.net MVC 5 project with lots of controllers and web apis. The problem is when i want to access one of the api methods, i get No HTTP resource was found that matches the request URI ... error.

I tried every solution in similar posts but i wasn't lucky. This is my RouteConfig file:

public static void Register(HttpConfiguration config)
{
    // Routing configs
    config.MapHttpAttributeRoutes();

    // Files api routs
    config.Routes.MapHttpRoute(
        name: "filesApi_1",
        routeTemplate: "api/{controller}/{action}/{file}",
        defaults: new object[]
        {
            new { controller = "Files", action ="SaveAttachment"}
        }
     );

config.Routes.MapHttpRoute(
    name: "filesApi_2",
    routeTemplate: "api/{controller}/{action}/{fileName}",
    defaults:
        new { controller = "Files", action = "DeleteAttachment" }
    );
}

When i go to htt://localhost:xxxx/api/Files/DeleteAttachment/file_name, i get the error.

My Global.asax.cs is:

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

        Mapper.Initialize(c=> c.AddProfile<MappingProfile>());
    }

The controller is:

public class FilesController : ApiController
{
    public void SaveAttachment(HttpPostedFileBase file){}
    public void DeleteAttachment(string fileName){}
}

It is very strange that if i add attribute routing for web api actions, they work as expected. For example:

[Route("api/Files/DeleteAttachment/{fileName}")]
public void DeleteAttachment(string fileName){}

I don't want write Route for every action because i have lots of actions and it make the code fragile. How can i fix routing in the route table? Thanks.

You have to check the file name. If the file url is coming or the value in filename contain '/' it will split the route and create a new url as

htt://localhost:xxxx/api/Files/DeleteAttachment/file_name_before_slash/file_name_after_slash

It will not match your URL.

Check value in file name part of your code.

------------------- Edit 1 ------------------------------------

The problem may be in filename "file.jpg". The dot (.) in the file name causes the issue refer to this link , more similar questions are available. Also check this one .

try

 <configuration>
     <system.web>
         <httpRuntime relaxedUrlToFileSystemMapping="true"/>

          <!-- ... your other settings ... -->
     </system.web>
 </configuration>

Tag your Api controller methods with attributes [HttpGet] or [HttpPost] so the routing mechanism will know when to use each.

public class FilesController : ApiController
{
    [HttpPost]
    public void SaveAttachment(HttpPostedFileBase file){}
    [HttpGet]
    public void DeleteAttachment(string fileName){}
}


----------------------------------------------------------------------------------
And the second issue may be with your default routing values:

config.Routes.MapHttpRoute(
    name: "filesApi_2",
    routeTemplate: "api/{controller}/{action}/{fileName}",
    defaults:
        new { controller = "Files", action = "DeleteAttachment" }
    );

There is fileName parameter missing in default route, so change it to:

config.Routes.MapHttpRoute(
    name: "filesApi_2",
    routeTemplate: "api/{controller}/{action}/{fileName}",
    defaults:
        new { controller = "Files", action = "DeleteAttachment", fileName = "" }
    );

or

config.Routes.MapHttpRoute(
    name: "filesApi_2",
    routeTemplate: "api/{controller}/{action}/{fileName}",
    defaults:
        new { controller = "Files", action = "DeleteAttachment", fileName = RouteParameter.Optional }
    );


----------------------------------------------------------------------------------
Ok, if it is still not working than it is due to file_name containing . . Web api routing doesn't like dot characters in last parameter.

Change your URL from http://localhost:58893/api/files/deleteattachment/file.jpg
to
http://localhost:58893/api/files/deleteattachment/file.jpg/
and you should be able to invoke requested method

Convention routing follows template based routing that you configure in webApiConfig but Attribute routing is a lot more flexible. I agree that you may not want to write [Route] attribute over every method but later provides a lot of flexibility.

In one of my project, I could use the same controller to have different route APIs serving similar functionality and as asked by UI development team. Refer this article

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM