Vahid Amiri
Vahid Amiri

Reputation: 11127

ASP.NET MVC Attribute routing

I decided to use attribute routing instead of the old way. Now I face a problem:

Here is my RouteConfig:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.LowercaseUrls = true;

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();
    }
}

and here is my HomeController:

public class HomeController : Controller
    {
        // some database stuff

        [Route("{page?}")]
        public ActionResult Index(int? page)
        {
            int pageNumber = page ?? 1;
            int pageCount = 1;
            return View(db.SelectPaged(pageNumber, pageCount));
        }

        [Route("about")]
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }
    }

and this is ArticleController:

[RoutePrefix("articles")]
    public class ArticlesController : Controller
    {
        private ClearDBEntities db = new ClearDBEntities();

        // GET: Articles
        [Route("")]
        public ActionResult Index()
        {
            var articles = db.Articles.Include(a => a.Admin);
            return View(articles.ToList());
        }

        // GET: Articles/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Article article = db.Articles.Find(id);
            if (article == null)
            {
                return HttpNotFound();
            }
            return View(article);
        }

Problem:

When I run the app it and I browse the default address (http://localhost:57922) it all works fine. It shows the index action from the homecontroller and about page also works fine and so does pagination.

But when i browse to (http://localhost:57922/article) it gives me:

Server Error in '/' Application.

Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.

The request has found the following matching controller types: 
ClearBlog.Controllers.ArticlesController
ClearBlog.Controllers.HomeController

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidOperationException: Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.

The request has found the following matching controller types: 
ClearBlog.Controllers.ArticlesController
ClearBlog.Controllers.HomeController

I don't understand how framework can get confused when I clearly stated that I want to browse a page with prefix of "articles".

What I want from app is to show index view when I browse to /article. and as for the home I want it to just keep showing index when no other parameter is provided in url. (just like what it does already)

How do I fix it?

Upvotes: 3

Views: 973

Answers (1)

CodeNotFound
CodeNotFound

Reputation: 23240

You have this error because this http://localhost:57922/articles match many routes, exactly two actions:

  • Index in ArticlesController: articles is used as a controller which match ArticlesController name with default action equals to Index.
  • Index in HomeController: articles is used as a page parameter from default controller named HomeController.

To solve this by using attribute routing you have to add a constraint in page parameter in Index action from HomeController like this :

[Route("{page:int?}")]
public ActionResult Index(int? page)
{
    //....
}

Doing so this route will not match /articles beacause articles will be used as string type and will no match the constraint in HomeController's Index.

Upvotes: 3

Related Questions