3

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.

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

I updated answer according your comment with file_name
1

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

Comments

1

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>

5 Comments

when there is not '/' in the file name, i can't reach the action too.
@ehsantoghian can you provide some more details about the error. like complete error message or stack trace.
The complete error is: { "message": "No HTTP resource was found that matches the request URI 'http://localhost:58893/api/files/deleteattachment/file.jpg'.", "messageDetail": "No action was found on the controller 'Files' that matches the request."
@ehsantoghian the problem is in filename "file.jpg" the (.) in the file name causes the issue reffer this link, more similar questions are available. Also check this one
i fixed the dot (.) in the file name, but for the brevity didn't mentioned that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.