Do I need a new controller for this? - asp.net-mvc

i have a PropertyController, which I use to serve a bunch of pages. For example..
/Property
/Property/{id}
/Property/add
/property/edit/{id}
I now need to do a bunch of stuff based on a particular property I will need to do serve pages like this:
/Property/{id}/images/add
/Property/{id}/images/edit/{id}
/Property/{id}/rooms/add
/Property/{id}/rooms/edit/{id}
I think I need to build a new ImagesController and RoomsController, but do I need to but these in a folder structure? My RouteConfig is currently set to the default MapRoute rule ({controller}/{action}/{id}

You don't need to reflect your routing structure in your folders structure.
Check this one out:
ASP.Net MVC support for Nested Resources?.
Effectively your routing string is a regExpression to match whatever comes in from a requester. And if there's a match it's trying to bind all the variables in your expression to values from the HTTP request.
In regard to creating new controllers - a rule of thumb is to create a controller per resource / business entity. So in your case I would say yes to ImagesController, RoomsController and PropertyController.

Related

Using custom routes instead of /controller/action/{id}

I have to make vanity urls for an already existing site. The requirements are:
The existing controllers are a kind of hierarchical structure and can't go away or be overridden in any way. Examples: domain.com/Dog/vanity and domain.com/Cat/vanity.
Keep existing actions. Any existing actions must take priority so that the page for that action is not stomped on by the vanity url.
take future pages and actions into account so that the above requirement is met (a new vanity url is ignored and the action/view executed instead)
To date, I have tried various solutions with routing that allow me to have domain.com/vanity which is nice but the marketing guys don't like because of the different departments within the company. I've tried routing which will override the existing actions and treats them all as vanities (also not feasible). I've a solution in place that programmatically deals with the url that was requested and redirects to a page that actually exists but this is not scalable in any way.
So far, I know that the vanity portion can be treated as a parameter to the action so that I can fire off the default page in the route (Index) but this is, so far, doesn't preserve the structure.
TL;DR: I need to have a solution that allows for domain/controller/vanity structure while also allowing domain/controller/action
Using AttributeRouting for MVC4 you can accomplish a working solution until you ramp up the replacement project. It'll allow you to keep existing routes while adding new, custom ones with little impact.
[Route("my-vanity/is-cool/post/{id}")]
public ActionResult Index(int id)
{
}
The important part is to remember priority, so you write routes that don't overwrite/are overwritten by existing routes. You can steer this to some degree with properties on the attribute. Below is just an example that will put the added route last in priority for the entire site.
[Route("my-vanity/is-cool", SitePrecedence = -1)]
public ActionResult Index()
{
}
ASP.NET WebApi2 have built in support for attribute routing. With it you can define URL's in whatever way you like (instead of following the /controller/action pattern)
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

How is a # used by the MVC code of the controller and views

URL : http://www.myserver.com/movies/details/19
Can someone tell me how the number '19' in the URL is used by the MVC code for the controller and views
(I already know how it relates to a particular representation of the domain data)
If you look at the default route configuration, you'll see that it is built as "/{controller}/{action}/{id}". If you stick with that and use (int id) as your parameter for the action, that is the value passed into id.
Edit: And just in case you need to find that, you can look in the App_Start folder for the RouteConfig.cs file.
What the various pieces of the URL do depend on how your Routes and Controllers are set up. The asp.net website provides a series of tutorials designed to introduce you to the options:
http://www.asp.net/mvc/tutorials/controllers-and-routing

Preferred way to use config settings in asp.net mvc master page

My Problem: I have an MVC3 application where all views use a common master page. The master page has many links to other (internal) sites. I need to be able to change the domain of these links depending on the deployment environment (e.g. staging.blah.com, www.blah.com, dev.blah.com etc). This domain is stored in the web.config.
There are numerous ways of doing this, but I am looking for some sort of consensus as to the preferred method. Here are some options but I am open to any suggestions:
(1) reference appsettings from master page directly. This is the simplest and most common approach but I am not particularly keen on reading the web.config and concatenate the url throughout the master page code. In fact, I am not sure that I like the idea of the view accessing the web.config at all.
(2) stick the appsetting value in viewdata/viewbag using a custom action filter which reads the config. concatenate in the page as before.
(3) as (2), but inject appsetting value in via contructor injection rather than reading it within the filter.
(4) create a base class for all my strongly typed viewmodels and populate with the appsetting using a custom action filter.
(5) create an htmlhelper that takes in the path and internally reads the appsetting and concatenates.
(6) create a custom view base class, inject in appsetting value and make available as property or function that takes in path and concatenates.
Just to add that typically when the master page requires data, I like to use Html.Action, but this is not possible in the case of these URLs that are used throughout the master page.
Thoughts?
(5) create an htmlhelper that takes in the path and internally reads the appsetting and concatenates.
I would go with this one. Your custom HTML helper could look something like this:
<%= Html.ExternalActionLink(
"link text",
new { path = "/foo/bar.php" }
new { param1 = "value1", param2 = "value2" }
) %>
and could emit the following HTML:
link text
What I have done in the past is use viewdata/viewbag in my master page and populate its values in my base controller. The base controller in turn called another class to do the work of reading the values from the web.config.
This way the view is pretty clean (e.g. it does not contain code to read appsettings) and I don't need to create a base view model that matches all my views that use the master.
This approach has the disadvantage that uses a viewdata/viewbag but I decided that was OK in my case and extremely easy to implement.

Best way to create a dynamic Google Sitemap using ASP.NET MVC?

Is there a recommended approach for creating Google Sitemaps using ASP.NET MVC?
I'm new to MVC and this is the first time I've needed to create one and wondered how best to go about it.
I have a number of static links (About Us, FAQ's etc.) that I would like included within the sitemap, but then need the rest of it to be dynamically generated from articles that have been posted on the site.
Any advice/direction on how to create this would be much appreciated.
1 - The first thing you'll need is to create a representation of your entire website a list of nodes which have children, parents and so forth. The easiest way to do this without rolling your own solution is to use the MVCSiteMapProject. It allows you so use MVCish terms like your action and controller names to define nodes which will automatically have the correct urls using your routing definitions.
2 - Now because the MVCSiteMap inherits from the default XmlSiteMap (may not have the exact name right ) you can use another add in to generate a google sitemap from the nodes you've defined in the MVCSiteMapProject.
There a bunch of ways to do #2 so its up to you to decide the technique.
You could create a generic handler the same as web forms, but I'd be inclined to use a controller action and a custom route.
Some simple steps to follow might be:
Create an action in your Home Controller (or create a new one), call it SiteMap.
Have the action return a View with your page data as the model.
Create a View called SiteMap that contains the Google XML, then iterate through your page data to generate the dynamic content.
Add a custom route to your Global.asax file that points to "/sitemap.xml" or whatever and pre-populate your the controller and action parameters with that of your new action.
If you're unsure of custom routes, just copy the default one and paste it above. The routes are handled first come first serve. Make sure you give it a new name.
Rich
for dynamic sitemap, i found this is the best solution : http://ben.onfabrik.com/posts/generating-dynamic-xml-sitemaps-in-aspnet-mvc
it use a controller to generate the xml file.

ASP.NET MVC One Way Route

Is it possible to define a route in the RouteCollection of Asp.net MVC, so that it just does the "URL rewriting" part and ignore the URL generation with Html.Actionlink(...)?
In fact I want to add a keyword between controller and action (controller/..keyword.../action) for certain very special requests. The generated URLs on the pages, however, should remain using the default routes. (controller/action)
Yes you can do what you are asking. You would just create your own route that inherited from the current one and override GetVirtualPath to always return null. This way no Action lookup would be done, but the URL would still function as a routing mapping to your action/controller.
Also by the way, what is happening isn't URL Rewriting, because you using the Routes to define endpoints in to your application. Or in other words an API. So no rewriting is taking place. Think of the relationship between routes and your action/controller as more of a publically defined namespace for the web. Just like a namespace you are defining a specific spot in your application where your action/controller can be found.

Resources