I'm working on my first MVC site and this routing business is giving me a headache... I posted a question on this yesterday but after more reading and googling I still have a fundamental misunderstanding.
I'm building a website that will allow amateur football leagues and their teams to register and track fixtures/results and news. News items can be posted at a 'league' or 'team' level.
Following guideance from Jacon Nielsen, I'd like my URLs to that:
- reflect the site structure
- are hackable to allow users to move to higher levels of the information
Having URLs like this would be great because they would give an indication to the user of the path they followed from the homepage of my site, to a league's home page (mysite.com/leagueName/), into a team's homepage (mysite.com/leagueName/teamName/) and
into that team's news page (or gallery, or fixtures or whatever).
Here's my problem - I don't have a clue how to map this in my routing table.
I see myself creating a News controller, a Gallery controller and a Fixtures controller.
Taking news as an example, I might have the following methods:
GetNewsForLeague(string leagueName)
GetNewsForTeam(string teamName)
<div>Now I'm in a situation where my controller (news) is at the end of my route and there are optional parameters before it. </div><div>
</div><div>I know this shouldn't be so difficult to achieve - after all, I keep hearing Gu, Haak, Hanselman et al saying this is one of the major advantages of MVC! :-) Does anyone have an idea about how I'd be better approaching this?</div><div>
</div><div>I don't want to compromise on having a clean URL, for example: mysite.com/News/leagueName/teamName
does not look good to me because it does not reflect the hierarchy of the site.</div><div>
</div><div>Any help would be very much appreciated!</div>
If you want your league head first from the site root, you will have some problems to accomodate login/about/index routes/views since they are already configured.
Do you like something like:
mysite.com/News/leagueName
mysite.com/News/leagueName/teamName
?
( and, in asp.net webforms routing I think you will accomodate like so the login/about/index routes)
Thanks for the response. As I mentioned in the original post, I'd prefer not to have to compromise on the URL unless I absolutely have to. To me, having
News at the beginning isn't good because, as a user drills down into the site, the URL won't be just appending sections on like a breadcrumb, but will be shuffling around too - causing confusion.
Consider the user's path through my site, down into the league they want to see and the team they support:
At any stage, the user can hack-off the last segment of the URL and get back to the page they expect to be on. Now, consider having News at the beginning:
I hate messy code more than I hate messy URLs - so if there's not a good way to do it without hacking too much then I'll consider other options... but this must be a fundamental requirement... no?
I did consider that we might have to add another controller as you have done with "leagues" - now the URL reads well and refects the hierarchy of the site much more closely.
One issue that I'm seeing with this is that I might end up with loads of action methods in the League controller that we've introduced. So consider we have the following pages:
Am I correct in saying that, using the solution above, I'd need to have all of the action methods in the LeaguesController?
This is where I'm getting torn. From the point of view of the URL I like this solution but from the point of view of the controller, I can see that the code would be much cleaner if I follow an Information Expert GRASP pattern, having:
I'm sure you'd agree that I would be better in the long-run having clean code and compromising on the URL than the other way around... but do I really
have to compromise?
Can you see a way of using your solution above without bundling everything into the LeaguesController?
Apologies if I've missed something really fundamental - like I say this is my first MVC project and I'm still working out what is/isn't feasible...
So the solution we have right now has a couple of problems:
1. Vast majority of action methods will be in one controller - LeagueController. In my view this is not great.
2. We can't reliably tell the difference between a team's homepage (mysite.com/DivisionOne/Cardiff) and the news page for a league (mysite.com/DivisionOne/News), as we're just looking for strings.
I'm sure we could use a regex to match for the word 'News' since this will remain constant and that would solve point 2.
However, I still don't like having most of the action methods in the LeagueController.
I take it the only way you know of to have controllers such as:
That sounds like an interesting solution - thanks! I think I will try that method.
If I can have the controllers in the Information Expert pattern (News/Fixtures/Gallery), and still have the URL I imagined, then that sounds like the best solution to me. I can probably even go back to the orignial URL without the 'Leagues' section we introduced.
I have to say, for the record, that I would have imagined this would be possible without building the routes dynamically from the database... however I'm guessing I'm not the first person to come across this scenario.
french_duke
Member
196 Points
147 Posts
Routing misunderstanding
Feb 07, 2011 12:51 PM|LINK
Hi folks
I'm working on my first MVC site and this routing business is giving me a headache... I posted a question on this yesterday but after more reading and googling I still have a fundamental misunderstanding.
I'm building a website that will allow amateur football leagues and their teams to register and track fixtures/results and news. News items can be posted at a 'league' or 'team' level.
Following guideance from Jacon Nielsen, I'd like my URLs to that:
- reflect the site structure
- are hackable to allow users to move to higher levels of the information
So, the news page would be:
League:
mysite.com/leagueName/News
eg:
mysite.com/PreimierLeague/News
mysite.com/DivisionOne/News
Team:
mysite.com/leagueName/teamName/News
eg:
mysite.com/PremierLeague/ManUtd/News
mysite.com/DivisionOne/Cardiff/News
Having URLs like this would be great because they would give an indication to the user of the path they followed from the homepage of my site, to a league's home page (mysite.com/leagueName/), into a team's homepage (mysite.com/leagueName/teamName/) and into that team's news page (or gallery, or fixtures or whatever).
Here's my problem - I don't have a clue how to map this in my routing table.
I see myself creating a News controller, a Gallery controller and a Fixtures controller.
Taking news as an example, I might have the following methods:
- GetNewsForLeague(string leagueName)
- GetNewsForTeam(string teamName)
<div>Now I'm in a situation where my controller (news) is at the end of my route and there are optional parameters before it. </div><div></div><div>I know this shouldn't be so difficult to achieve - after all, I keep hearing Gu, Haak, Hanselman et al saying this is one of the major advantages of MVC! :-) Does anyone have an idea about how I'd be better approaching this?</div><div>
</div><div>I don't want to compromise on having a clean URL, for example: mysite.com/News/leagueName/teamName does not look good to me because it does not reflect the hierarchy of the site.</div><div>
</div><div>Any help would be very much appreciated!</div>
MVC Controller routing
ignatandrei
All-Star
137649 Points
22143 Posts
Moderator
MVP
Re: Routing misunderstanding
Feb 07, 2011 01:01 PM|LINK
If you want your league head first from the site root, you will have some problems to accomodate login/about/index routes/views since they are already configured.
Do you like something like:
mysite.com/News/leagueName
mysite.com/News/leagueName/teamName
?
( and, in asp.net webforms routing I think you will accomodate like so the login/about/index routes)
french_duke
Member
196 Points
147 Posts
Re: Routing misunderstanding
Feb 07, 2011 01:17 PM|LINK
Thanks for the response. As I mentioned in the original post, I'd prefer not to have to compromise on the URL unless I absolutely have to. To me, having News at the beginning isn't good because, as a user drills down into the site, the URL won't be just appending sections on like a breadcrumb, but will be shuffling around too - causing confusion.
Consider the user's path through my site, down into the league they want to see and the team they support:
mysite.com (site home)
mysite.com/DivisionOne (league home)
mysite.com/DivisionOne/Cardiff (team home)
mysite.com/DivisionOne/Cardiff/News (team news)
At any stage, the user can hack-off the last segment of the URL and get back to the page they expect to be on. Now, consider having News at the beginning:
mysite.com (site home)
mysite.com/DivisionOne (league home)
mysite.com/DivisionOne/Cardiff (team home)
mysite.com/News/DivisionOne/Cardiff (team news)
To me, the first way is much nicer.
I hate messy code more than I hate messy URLs - so if there's not a good way to do it without hacking too much then I'll consider other options... but this must be a fundamental requirement... no?
ignatandrei
All-Star
137649 Points
22143 Posts
Moderator
MVP
Re: Routing misunderstanding
Feb 07, 2011 01:50 PM|LINK
Ok.
Add a Leagues controller , a News action with 2 parameters leaguename and teamname ( handle the case when teamname is null / empty )
Then try this route:
routes.MapRoute(
"Leagues", // Route name
"leagues/{leaguename}/{teamname}/{action}", // URL with parameters
new { controller = "Leagues", action = "News", leaguename = UrlParameter.Optional , teamname= UrlParameter.Optional} // Parameter defaults
);
Then browse to
mysite.com/Leagues/DivisionOne/Cardiff/News
If that works, please decide how you will handle
1. the default of the site /
2. the login
3. the about
( you can accomodate those by handling routename parameter from News action to : empty, login, about )
After you decide this, you can remove "Leagues" from Leagues route.
french_duke
Member
196 Points
147 Posts
Re: Routing misunderstanding
Feb 07, 2011 02:05 PM|LINK
Thanks again - starting to look much better now!
I did consider that we might have to add another controller as you have done with "leagues" - now the URL reads well and refects the hierarchy of the site much more closely.
One issue that I'm seeing with this is that I might end up with loads of action methods in the League controller that we've introduced. So consider we have the following pages:
mysite.com/Leagues/DivisionOne/News
mysite.com/Leagues/DivisionOne/Cardiff/News
mysite.com/Leagues/DivisionOne/Cardiff/Gallery
mysite.com/Leagues/DivisionOne/Cardiff/Fixtures
mysite.com/Leagues/DivisionOne/Cardiff/Players
etc...
Am I correct in saying that, using the solution above, I'd need to have all of the action methods in the LeaguesController?
This is where I'm getting torn. From the point of view of the URL I like this solution but from the point of view of the controller, I can see that the code would be much cleaner if I follow an Information Expert GRASP pattern, having:
NewsController
GalleryController
FixturesController
PlayersController
I'm sure you'd agree that I would be better in the long-run having clean code and compromising on the URL than the other way around... but do I really have to compromise?
Can you see a way of using your solution above without bundling everything into the LeaguesController?
Apologies if I've missed something really fundamental - like I say this is my first MVC project and I'm still working out what is/isn't feasible...
Thanks
ignatandrei
All-Star
137649 Points
22143 Posts
Moderator
MVP
Re: Routing misunderstanding
Feb 07, 2011 02:22 PM|LINK
trying to match :
"leagues/{leaguename}/{teamname}/{action}", // URL with parameters
new { controller = "Leagues", action = "News", leaguename = UrlParameter.Optional , teamname= UrlParameter.Optional} // Parameter defaults
to
(I let mysite.com/Leagues/DivisionOne/News for the last(
1. mysite.com/Leagues/DivisionOne/Cardiff/News
then controller = "Leagues", leaguename=DivisionOne, teamname=Cardiff, action = "News"
2. mysite.com/Leagues/DivisionOne/Cardiff/Gallery
then controller = "Leagues", leaguename=DivisionOne, teamname=Cardiff, action = "Gallery"
3. mysite.com/Leagues/DivisionOne/Cardiff/Fixtures
then controller = "Leagues", leaguename=DivisionOne, teamname=Cardiff, action = "Fixtures"
Ok, now the real problem:
0. mysite.com/Leagues/DivisionOne/News
then controller = "Leagues", leaguename=DivisionOne, teamname=News, action = "" - so default News.
So in news action of Leagues controller , if teamname == News, you will display news for leaguename, not teamname.
HTH
french_duke
Member
196 Points
147 Posts
Re: Routing misunderstanding
Feb 07, 2011 02:32 PM|LINK
Okay - I see what you're saying.
So the solution we have right now has a couple of problems:
1. Vast majority of action methods will be in one controller - LeagueController. In my view this is not great.
2. We can't reliably tell the difference between a team's homepage (mysite.com/DivisionOne/Cardiff) and the news page for a league (mysite.com/DivisionOne/News), as we're just looking for strings.
I'm sure we could use a regex to match for the word 'News' since this will remain constant and that would solve point 2.
However, I still don't like having most of the action methods in the LeagueController.
I take it the only way you know of to have controllers such as:
NewsController
GalleryController
FixturesController
is to go back to having the crontroller name as the first segment in the URL?
Thanks
ignatandrei
All-Star
137649 Points
22143 Posts
Moderator
MVP
Re: Routing misunderstanding
Feb 07, 2011 02:41 PM|LINK
So you want same NewsController for both routes:
mysite.com/Leagues/DivisionOne/Cardiff/News
mysite.com/Leagues/DivisionOne/News
And , in my opinion , is something hard to do in MVC .
The only easy way that I think of is to register routes from the database , i.e. you have in the database a fixed amount of leagues / teams(10/20?)
In the registerroutes you will query the database and register each league
Leagues/DivisionOne/Cardiff/News
Leagues/DivisionOne/News
...
to the apropiate controller /action.
french_duke
Member
196 Points
147 Posts
Re: Routing misunderstanding
Feb 07, 2011 02:52 PM|LINK
That sounds like an interesting solution - thanks! I think I will try that method.
If I can have the controllers in the Information Expert pattern (News/Fixtures/Gallery), and still have the URL I imagined, then that sounds like the best solution to me. I can probably even go back to the orignial URL without the 'Leagues' section we introduced.
Thanks for your time!
french_duke
Member
196 Points
147 Posts
Re: Routing misunderstanding
Feb 07, 2011 02:53 PM|LINK
I have to say, for the record, that I would have imagined this would be possible without building the routes dynamically from the database... however I'm guessing I'm not the first person to come across this scenario.