I am currently working with mvc4 and have a question around best practice.
I am passing back to my view, a number of links based on product information eg. product/1234 etc.
What is best practice, create the link using the routing engine in the controller and return the url as a property on the model object OR return the information to the view and generate the link there? I use automapper to map my DTO objects to model object, also considering creating the links during mapping.
What is the best practice with this?
You always create the link on the view.
The HTML helpers in the view can be used to ensure the link conforms to your routing rules.
You can see this in action in the many official ASP.NET MVC 4 Tutorials.
Why not in the controller or model?
The HTML helpers in the view are designed to create not just the URL, but also to wrap the URL in a fully formed anchor tag, etc. It isn't appropriate to have HTML in your model or controller as they shouldn't care how the data is displayed.
For example, the Html.ActionLink helper returns an a element.
Related
I would like to use the generic razor helper function Html.Partial to render views that have common html in them.
For instance, I have two views set up in Sitecore Payment Information.cshtml and Agent Payment Information.cshtml. These are rendered using the Sitecore rendering engine. Both of these views have very similar html in them that I would like to put in razor views not set in Sitecore and call them with #Html.Partial as appose to #Html.Sitecore().Rendering() as the latter forces me to set up a view and model in Sitecore which I am not sure is necessary.
My question is, is there anything that Sitecore does behind the scenes that makes it necessary to usethe #Html.Sitecore().Rendering() helper method instead of the #Html.Partial() helper method? Everything seems to work fine and I believe the entire view should get cached since the #Html.Partial call is nested inside either the Payment Information view or the Agent Payment information view set up in Sitecore.
Thanks in advance.
I have Html.Partial working in an MVC solution using Glass for ORM. There are two ways I've used this, one where the assumed model being passed to the partial is the same as the parent rendering and another where we create the model on the fly.
Assumes parent rendering model is passed:
#Html.Partial("~/Views/Components/MyPartialView.cshtml")
Instantiates a new model that is passed in:
#Html.Partial("~/Views/Components/Navigation/SecondaryNavigationRendering.cshtml", new SecondaryNavigation())
The parent view will need to have a mapped model in Sitecore. The secondary view does not have a mapped model in Sitecore but is typed to receive the model being passed (so in my first example that would be my IBasePage model, in my second it would be my SecondaryNavigation model).
Hope this helps.
I'm looking at developing an application that will include a CMS. I'm a seasoned web forms developer but only really just moving into MVC.
I have a couple of questions that I hope some of you guys can answer:
First, my current web forms CMS allows users to create a page, and then "drop" any number of user controls onto that page they have created. The way I do this is to create an entry in the DB together with the path and then use the LoadControl method.
I can see I can do this with partial views, but partial views have no code behind. If I've potentially got 100 controls that people can drop onto a page, does this mean that the ViewBag in the controller needs to cater for all 100 controls just in case they are used on the view? For example, a web forms user control will contain logic: rptItems.DataSource = blah; rptItems.DataBind()
With MVC, I'm assuming that logic will be in the view controller and the view would access it by the ViewBag? I'm a little confused at how to do this.
Secondly, how would you handle deep routing?
EG:
Store/Products/Category is fine, but what about Store/Products/Category/Delivery/UK ? Would I need to set up a route in global.asax for each route I need? In web forms, I just called the ReWritePath method and handled the routing myself using regular expressions.
Thanks for the time to read this, and hopefully answer some of my queries
For your second question, (ie, "deep routing"), you can handle this within your controller instead of adding real routes. Each part of the url is available via the RouteData.Values collection inside of your controller action. So, your route may look like
~/Store/Products/Category/{*params}
Assuming typical route configuration, this would call the Category(...) action method on ~/areas/store/controllers/storeController, which could then grap delivery and uk from the RouteData.Values collection.
There are a lot of other approaches to this - storing routes in a database and using associated metadata to find the correct controller and method - but I think this is the simplest. Also, it may be obvious, but if you really only need two parameters beyond 'Category' in your example, you could just use
public ActionResult Category(string category, string region)
{
...
}
and a route:
~/store/{controller}/{action}/{category}/{region}/{*params}
Delivery and UK would be mapped to the the category and region parameters, respectively. Anything beyond uk would still be available via the RouteData.Values collection. This assumes that you don't have more specific routes, like
~/store/{controller}/{action}/{category}/{region}/{foo}/{bar}/{long_url}/{etc}
that would be a better match. ({*params} might conflict with the second route; you'll have to investigate to see if it's a problem.)
For your first question:
You can dynamically generate the view source and return it as a string from the controller, eliminating the need to pass a lot of stuff via ViewBag. If a virtual page from your CMS database requires inclusion of partial views, you would add the references to those components when generating the page. (This may or may not address your problem - if not, please provide more information.)
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.
I'm porting an existing system to ASP.NET MVC2. In the current legacy app, the user can select from dozens of available fields to customize CRUD forms for different entities in the domain model, similar to the way ERP systems allow customization of core modules.
My question: I'm looking for a good pattern or example for this kind of behavior in ASP.NET MVC2. It seems to me it's rather like creating a ViewModel dynamically based upon user choices, or perhaps the right approach is data-driven view pages that aren't strongly-typed where I can reflect over the results client-side to determine field headings or something -- if that makes sense :). Or maybe I can drive AutoMapper or similar dynamically # runtime based on user choices?
The underlying domain model is EF4-based and I'm using a simple Repository pattern # present for the ViewModel.
TIA for any input! Michael
If I didn't find anything else that matched the needs and went on to do it custom, I would:
Use the ViewModel with all the fields / not just the ones the user picked.
Pass both the ViewModel and the view configuration to the view
Call some html helper that for each item in the configuration adds a field with the corresponding property in the model
The configuration could be passed as either part of a containing ViewModel or in a separate entry in ViewData
Depending on what you need, building/passing the view configuration could be put in an Action Filter. Alternatively the helper could pull it directly.
A different approach is if you need completely custom fields. I mean user defined fields. If that's the scenario, that's not typed at the controller level already, so I'd pass the list of fields/values to the view. The view can do a foreach on those adding the fields. Again that could be moved to a HtmlHelper.
Forms + ASP.NET MVC = Confusing for me:
What are the preferred ways to setup your controller action for form posts?
Do I need to specify an attribute that has [AcceptVerbs(HttpVerbs.Post)]?
Should the controller action take a "FormCollection" or should I use ModelBinders?
If I should use ModelBinders, how?
How do I setup the form in the view?
Should I use the Html helpers like Html.BeginForm/Html.EndForm or simply specify the form tag myself?
How do you specify the controller and action to be used in a form (with either the Html helpers or with a manual form tag)?
Can somebody please show me both a simple view with a form ~and~ its corresponding controller action?
I'm trying to write a form with a single textbox that I can submit to the Home/Create action and pass the string from the textbox to it.
ScottGu's handling form edit and post scenarios is exactly what you're looking for. There's also form posting scenarios and even though it was written for preview 5, it's still mostly valid.
The template's AccountController.LogOn and .Register methods along with the corresponding views should give you the simple introduction you need.