Reputation: 548
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.
Upvotes: 2
Views: 1304
Reputation: 385
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>
Upvotes: 1
Reputation: 3019
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
Upvotes: 2
Reputation: 26
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
Upvotes: 1