2

I'm trying to get this to work in my ASP.Net Web API 2 application. You will notice that this Controller inherits Controller. This is because I need to return a View instead of JSON.

[RoutePrefix("api/Manage")] public class ManageController : Controller { [Route("TestOne")] public async Task<ActionResult> MyTestOne(string value1, string value2) { return View(""); { } 

Here is the error I'm getting.

<error> <MessageDetail> No type was found that matches the controller named 'Manage'.</MessageDetail> </Error> 

I need to call the Manage Controller like so.

https://api.domain.com/api/Manage/TestOne?value1=foo&value2=bar

My RouteConfig is configured like so.

routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); 

NOTE: [RoutePrefix("api/Account")] works in my AccountController. This is an API Controller and inherits ApiBase.

Any help is much appreciated! Thanks!

12
  • You can just add [RoutePrefix("api/[controller]")] to allow the RouteConfig to do his own work. Commented Mar 20, 2019 at 20:22
  • Can you explain more why you need to return a View and how you are calling this Api action. It sounds weird. Commented Mar 20, 2019 at 20:25
  • 1
    Attribute routing will override the traditional router, so not sure why RouteConfig is provided here Commented Mar 20, 2019 at 20:28
  • @pmcilreavy I'm calling this from a URL in an email. Instead of returning Ok("Success"), I need to return a View with a message that can be read. The View then needs to be closed by JavaScript. Commented Mar 20, 2019 at 20:31
  • Try adding [FromQuery] in front of each string parameter, i.e. MyTestOne([FromQuery] string value1, [FromQuery] string value2). This will give a hint to asp.net to get these values from the querystring. Commented Mar 20, 2019 at 20:35

1 Answer 1

3

It happens because you have 2 route configuration, one for MVC controllers and one for Web API. And in your case Web API route configuration goes first. Global.asax.cs looks like this

//some configs WebApiConfig.Register(GlobalConfiguration.Configuration); //some configs RouteConfig.RegisterRoutes(RouteTable.Routes); 

And you must be having something like this in Web API route config

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

When you request /api/Manage/TestOne the Web API routing applies first. No attribute based route fits but the request perfectly matches to DefaultApi route. Manage matches to {controller} and TestOne goes to {id}. So the framework starts searching for api controller with name Manage like this

public class ManageController : ApiController 

But there is not such controller and indeed you have an error

{ "Message": "No HTTP resource was found that matches the request URI 'http://host/api/Manage/TestOne/?value1=foo&value2=bar'.", "MessageDetail": "No type was found that matches the controller named 'Manage'." } 

So I can suggest you few possible solutions.

Change route configuration order

//some configs RouteConfig.RegisterRoutes(RouteTable.Routes); //some configs WebApiConfig.Register(GlobalConfiguration.Configuration); 

And then your example will work as expected but it may create unexpected errors because I don't know all possibles routes in your application.

Remove DefaultApi route

If you completely rely on attribute based routing for Web API you can just remove this configuration with no negative effect for you application

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

Or just change prefix

If you change prefix from api to anything else it will work as well because it won't match DefaultApi route anymore

[RoutePrefix("view/Manage")] 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I ended up reformatting the URLs I was generating to work with my Default RouteConfig, but you are on the right track with your answer. I actually found this Stackoverflow that first alerted me to the existence of dueling configs. :) stackoverflow.com/questions/45120965/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.