MVC Best Practices | Do you build your links into the Url Helper? - asp.net-mvc

Just read a post about MVC best practices. Couple parts of the post described building helper methods to link to actions on the controllers. Here's a clip:
1) Create Extension methods of UrlHelper to generate your url from
Route
Avoid passing the controller, action
or route name as string, create
extension methods of UrlHelper which
encapsulates it, for example:
public static class UrlHelperExtension
{
public static string Home(this UrlHelper helper)
{
return helper.Content("~/");
}
public static string SignUp(this UrlHelper helper)
{
return helper.RouteUrl("Signup");
}
}
I can see how this would shorten links used in views... but I don't see how this is a "best practice". Perhaps I'm simply overlooking something. Should I be doing this to build my links? Are there benefits to this I'm just not seeing?
He even goes on to say that stylesheets, images, and javascript helpers should be made...

I probably wouldn't do this unless the route is referenced in multiple places. I can see the value in doing this, and I have implemented HtmlHelper extensions for adding style sheets and javascript includes to add the ability to use "versioned" links, but my common links are included as ActionLinks in a UserControl (menu) and for most other things I use either ActionLink or BeginForm/AjaxForm to reference the action. In some respects it feels like creating new methods for all but the most commonly reused links is adding complexity for very little value -- the kind of value that you would get from some simple manual testing of your UI, which you'd have to do anyway.

If you make a mistake when writing a URL as a string, it won't be caught until runtime. This way, attempting to refer to a route that hasn't been created as an extension method will create errors at compile-time, which you can quickly correct (even earlier, if you use Visual Studio). If you discover a mistake in the way you formulated a route, you only have to fix it in one place.
Although, instead of cluttering your UrlHelpers with extension methods, it might be better to have a static class called something like CommonUrls that holds static readonly properties (or static methods, if you prefer).
EDIT: I just realized that you would need to pass an instance of your UrlHelper to the CommonUrls class. Silly me. In that case, extension methods probably are the right tool for the job.

That's one person's opinion of what a best practice is. There are a few cases where it might be nice. If you have people working with the views while the URL structure is still being worked out you won't have to update the views once the URLs are finalized.

Should anyone else happen to stumble on this old post, I would suggest using the T4MVC templates by David Ebbo: See his latest blog post here.

I don't see this as a best practice. For one thing you're going down the path of burying structural specifics down in a bunch of extension methods. (Although you could use resources for the paths, it would mean high-friction changes.)
Further, at what point do you stop? For a site of any complexity you're going to need a lot of these helpers.
I've used a somewhat similar approach when referencing stylesheets, javascript, favicons, etc. although I use HtmlHelper rather the UrlHelper extensions as conceptually I think they're more suited to the task.
Further, because such things are typically added to a master page only, there's no issue with simply passing the complete path into the helper and having it construct an entire tag - rather than just resolve a URI.

I'm using this approch.
It's very useful when your application sitemap is subject to changes.
And yes, you need a lot of those (I my extension class count 1800 lines, with comments)
Main difference, in my case, I build the URL using a strongly-typed builder. It looks like this :
/// <summary>
/// To campaign 'transfer credits' page
/// </summary>
public static string ToCampaignTransferCredits(this UrlHelper helper, int? idCampaignSource)
{
return To<CampaignController>(helper, c => c.Transfer(idCampaignSource));
}
I think this is a very good practice (IMHO) for some reasons :
you have a clear separation between navigation available page/actions and your controllers. I recently had to move methods from one controller to another, and it worked without pain/refactoring/testing.
it's compiled so if you change a controller's method signature you are awared of the changes to do (and you only have 1 or 2 changes, no need to check the whole application)
you can use inheritance and generics on your controllers like a OOP geek, cascade the calls and whatever you find powerful, this approach will hide all the underlying complexity, leaving simples call in the views.

Related

MVC - How to create a wrapper for Html.RenderPartial?

I would like to either override or create a custom function to wrap the RenderPartial shared function found in System.Web.Mvc.Html RenderPartialExtensions.
I found an article talking about this idea here:
http://johncoder.com/Post/AdventuresinDebuggingAFriendlierCalltoRenderPartial
<% Html.TryRenderPartial("ClassB", Model.B); %>
In the example above, they have created a custom sub called TryRenderPartial that does some logic and calls RenderPartial if necessary. Unfortunately this article does not give a code example of the TryRenderPartial sub itself.
I can't figure out how to create this function because the RenderPartialExtensions is not inheritable. Also I'm not sure how to actually output the html because RenderPartial is a sub, not a function, so I don't get how to actually "return" the html. Any ideas?
It's literally trivial to wrap RenderPartial. You just create an HtmlHelper extension like so (in C#, I don't speak VB):
public static class MyRenderPartialExtensions
{
public static void MyRenderPartial(this HtmlHelper htmlHelper, string partialViewName)
{
htmlHelper.RenderPartial(partialViewName)
}
}
You would add similar methods for the other overloads you want to implement.
However, chances are, you probably don't really want to do this... most likely, what you want to do is already possible in a way that the framework exposes.
This is what's known as an XY Problem, which basically means that you have Problem X, and you have decided that you need to do Y to solve it. However, you can't figure out how to do solution Y, so you're asking how to do Y rather than asking how to do your original X problem.
The reason why XY problems are bad is because chances are, the solution you've decided you need to do is not the correct solution, and the reason you're having trouble with it is because it's not the right way to do things.
Frankly, I can't think of a good reason to wrap RenderPartial, since anything you'd do is more than likely doable in some other way.
To respond to your other comment, Html helpers don't "return" anything. That's why they're Sub's. How view rendering works is rather complex, and not a subject easily discussed in an SO answer.
HtmlHelpers don't work via inheritance, they use Extension Methods.
http://msdn.microsoft.com/en-us/library/bb384936.aspx

Is it a good practice to write helper functions in controller itself

I am new to Microsoft ASP.NET MVC framework. I am working on MVC project where I have a controller. It has various ActionResult methods. Also, it needs several helper functions. Can I write them in controller itself? Please guide me.
No, it's not best practice.As helper function needs to be define/implemented in static class. So it is better to to have standalone seprate helper class.
The answer is: it depends. First of all it is not clear what do you mean with helper functions.
if you are talking about ASP.NET MVC HTML Helpers, it is better to move them to separate class. Tutorial how to create and use them.
if you are talking about general helper functions that evaluate something, of course you may leave them in controller, move to the base controller or move to separate class or library (depeneds on context). You may check implementation of standard System.Web.Mvc.Controller, there are a lot of methods and properties in it.
I think there's no specific rule regarding this.
IF
you're going to reuse the helper function, abstract/separate it to another class.
ELSE
put it in the same class for better code cohesion and readability.

What things can I put inside a BaseController to make my MVC life simpler

My base controller has:
[Authorize(Roles = "sys_admin")]
I want to have one action in a controller that's different and is available to "user" and "sys_admin". Can I override and how do I do that?
Also any suggestions on what else I could put in a base controller that might make my coding simpler. For example what's in your base controllers?
Anything that you use in every controller - attributes, methods, properties, etc. The same stuff you would put in any base class.
Just to add to the discussion, I have a few extra utility methods in my shared controller. I write a bunch of little apps for corporate use, so I try to repeat code as little as possible here.
getContext(): Puts together an object containing user info like IP, hostname, id, etc. for logging purposes.
Shared Views/Partials such as Error, Default, and Redirect (used for redirecting ajax requests).
RedirectToError(): I created this to use similar to RedirectToAction. I load up an ErrorObject with info, throw it in session, and return a Redirect to my Error page.
General logging and tracing methods so I can quickly spit out information to a file.
I override OnActionExecuting and check if my session is still valid and redirect to login if its not. Probably better with attributes...went with quick and dirty. Also trace Url.PathAndQuery for debugging here.
Any data access actions that I would use across views with ajax, like loading up a list of departments.
OnException is overridden, as well.
That's what I got in mine so far.
In my base controllers I actually put some utility method ([NonAction]) collected over time. I prefer to add functionalities to Controllers by decorating with Attributes if possible.
Lately my base controller has:
some Properties for retrieving information about the current user (my app
specific informations, not the User.Identity stuffs)
A simple protected override void OnException(ExceptionContext
filterContext); override for at least logging unhandled exception and have
some sort of automatic notifications
A bunch of Cookies related methods (WebForms auth cookies management
for example)
A bunch of usefull standard attributes (usually [Authorize], [HandleError], [OutputCache]) in its declaration.
some standard method for preparing widely used json data types on the fly (when possible I prefer to have a standard json object with ErrorCode, ErrorMessage and a UserData).
With time you'll find more and more utilities to keep with your controllers, try to keep an assembly with the simpler ones (avoiding heavy dependencies), will come handy with your next MVC projects. (the same goes for Helpers and to some degree also for EditorTemplates).
For the Authorize Attribute part, well, I think the cleanest way is to write your own AuthorizeAttribute class, specifically a NonAuthorizeAttribute. I think I've also seen it somewhere on SO.
You can also play with the Order Property of the default AuthorizeAttribute - put different Order in BaseController and in Action, in order to have Action's one executed first, but I cannot recall if you can actually break the Attributes processing chain.
Regards,
M.
We cant tell you what you need in your base controller, you have to reveal these kind of thing as you implement your controllers and see repeating code.. Dont hesitate to refactor these things to your BaseController, and keep in mind, that maybe you should have 2 or more BaseControllers, or 2-layer hierarchy of BaseControllers.
I give you two tips, what i always have in my BaseController :
super-useful helper method for interface-based model binding :
protected T Bind<T, U>()
where T : U, new()
where U : class
{
T model = new T();
TryUpdateModel<U>(model);
return model;
}
You can then have multiple "sets" of properties you want to bind in different scenarios implemented as interfaces, and simple model bind your object (even existing object, from DB) with incoming values.
2.If you use custom AcionResults (maybe your specific Json builders etc.), make your "shortcuts" methods in BaseController. Same thing as View() method is shortcut for return new ViewResult(...)
To add more to the good responses already here -
caching caching caching caching
See
Disable browser cache for entire ASP.NET website

What are good candidates for base controller class in ASP.NET MVC?

I've seen a lot of people talk about using base controllers in their ASP.NET MVC projects. The typical examples I've seen do this for logging or maybe CRUD scaffolding. What are some other good uses of a base controller class?
There are no good uses of a base controller class.
Now hear me out.
Asp.Net MVC, especially MVC 3 has tons of extensibility hooks that provide a more decoupled way to add functionality to all controllers. Since your controllers classes are very important and central to an application its really important to keep them light, agile and loosely coupled to everything else.
Logging infrastructure belongs in a
constructor and should be injected
via a DI framework.
CRUD scaffolding should be handled by
code generation or a custom
ModelMetadata provider.
Global exception handling should be
handled by an custom ActionInvoker.
Global view data and authorization
should be handled by action filters.
Even easier with Global action filters
in MVC3.
Constants can go in another class/file called ApplicationConstants or something.
Base Controllers are usually used by inexperienced MVC devs who don't know all the different extensibility pieces of MVC. Now don't get me wrong, I'm not judging and work with people who use them for all the wrong reasons. Its just experience that provides you with more tools to solve common problems.
I'm almost positive there isn't a single problem you can't solve with another extensibility hook than a base controller class. Don't take on the the tightest form of coupling ( inheritance ) unless there is a significant productivity reason and you don't violate Liskov. I'd much rather take the < 1 second to type out a property 20 times across my controllers like public ILogger Logger { get; set; } than introduce a tight coupling which affects the application in much more significant ways.
Even something like a userId or a multitenant key can go in a ControllerFactory instead of a base controller. The coupling cost of a base controller class is just not worth it.
I like to use base controller for the authorization.
Instead of decorating each action with "Authorize" attribute, I do authorization in the base controller. Authorized actions list is fetched from database for the logged in user.
please read below link for more information about authorization.
Good practice to do common authorization in a custom controller factory?
I use it for accessing the session, application data etc.
I also have an application object which holds things like the app name etc and i access that from the base class
Essentially i use it for things i repeat a lot
Oh, i should mention i don't use it for buisiness logic or database access. Constants are a pretty good bet for a base class too i guess.
I have used base controller in many of my projects and worked fantastic. I mostly used for
Exception logging
Notification (success, error, adding..)
Invoking HTTP404 error handling
From my experience most of the logic you'd want to put in a base controller would ideally go into an action filter. Action Filter's can only be initialized with constants, so in some cases you just can't do that. In some cases you need the action to apply to every action method in the system, in which case it may just make more sense to put your logic in a base as opposed to annotating every action method with a new actionFilter attribute.
I've also found it helpful to put properties referencing services (which are otherwise decoupled from the controller) into the base, making them easy to access and initialized consistently.
What i did was to use a generic controller base class to handle:
I created BaseCRUDController<Key,Model> which required a ICRUDService<TModel> object as constructor parameter so the base class will handle Create / Edit / Delete. and sure in virtual mode to handle in custom situations
The ICRUDService<TModel> has methods like Save / Update / Delete / Find / ResetChache /... and i implement it for each repository I create so i can add more functionality to it.
using this structure i could add some general functionality like PagedList / AutoComplete / ResetCache / IncOrder&DecOrder (if the model is IOrderable)
Error / Notification messages handling: a part in Layout with #TempData["MHError"] code and a Property in base Controller like
public Notification Error
{
set { TempData["MHError"] = value; }
get { return (Notification) TempData.Peek("MHError"); }
}
With this Abstract classes i could easily handle methods i had to write each time or create with Code Generator.
But this approach has it's weakness too.
We use the BaseController for two things:
Attributes that should be applied to all Controllers.
An override of Redirect, which protects against open redirection attacks by checking that the redirect URL is a local URL. That way all Controllers that call Redirect are protected.
I'm using a base controller now for internationalization using the i18N library. It provides a method I can use to localize any strings within the controller.
Filter is not thread safe, the condition of database accessing and dependency injection, database connections might be closed by other thread when using it.
We used base controller:
to override the .User property because we use our own User object that should have our own custom properties.
to add global OnActionExecuted logic and add some global action-filters

ASP.NET MVC: When to use HTML helpers in views - Tidying up the code!

I am trying to refactor my views a bit and up til now i have been using the built HTML helpers but i thought i would create my own - they're extension methods right?
I wonder if anyone can confirm or give advise when an HTML is needed? I think i once saw a document that said if you use 1 IF statement in your views encapsulate it into a html helper - would anyone agree with that?
With regards to creating html helpers, would it be better to create my own class rather than add extension methods to the HTML class that ships with MVC? Any body have ideas on this?
Or possible i shouldn't bother with HTML helpers and just use the built in ones and continue to use my IF statements within views.
Thanks in advance
Use HTML helpers when you want to encapsulate the output of a piece of HTML markup that can take varying values.
I'd recommend creating them as extension methods to HtmlHelper rather than creating your own class, as your own class won't be available inside of the default ViewPage without either instantiating a new instance inside of the View or subclassing ViewPage and using this in the View (or passing in on the model, but that's just wrong!).
HTML Helpers are extension methods. I can confirm as well that I too use the 'if' rule when it comes to views. Any view logic coded should, IMO, be in a helper.
You can use helper to render custom markup, or control which markup(ie existing view) is displayed.
Not too sure about the ease of this, but it does lend itself to more unit testing (please comment on this aspect if someone has more info).
With regards to creating html helpers, would it be better to create my own class rather than add extension methods to the HTML class that ships with MVC? Any body have ideas on this?
If I understand correctly, in this respect my suggestion would to separate your helpers into their own classes. The reasoning behind this for me would be that you easily know when looking at your views what are standard helpers vs the ones you've created. I think this will improve maintainability.
i shouldn't bother with HTML helpers and just use the built in ones and continue to use my IF statements within views.
I'd say No! (or it depends). One of the benefits of using a helper would be to reuse the same view logic in multiple views as opposed to re-coding the same if statements. This means your code is more DRY, which is always better. In the event you need to debug some weirdness error, you only need to look in one place, the newly created helper.

Resources