Creating custom Html Helper in MVC3

Creating custom attribute is pretty simple really, just follow the example. You need to return MvcHtmlString – that is string with your html to be displayed on a page – this will not be escaped.

public static MvcHtmlString DisplayWithNameFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,Expression<Func<TModel, TProperty>> expression)
{
    ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    if (metaData.Model == null)
    {
        return MvcHtmlString.Create(String.Empty);
    }

    string html = "<div class=\"display-label\">";
    html += htmlHelper.LabelFor(expression).ToString();
    html += "</div><div class=\"display-field\">";
    html += htmlHelper.DisplayFor(expression).ToString();
    html += "</div>";

    return MvcHtmlString.Create(html);
}

MVC Recipies: On Page Action Return to the previous page

Whenever you need a page to return to the previous page when you get an form submit or some other action, this can be used:

Have a base controller that is inherited by all your controllers. That is always a good idea – you can easily add things that work site-wide.
In you base controller have a OnActionExecuting overriden – here we are going to store the previous page.
Something like this:

public abstract partial class MyController : Controller
{

public ActionResult RedirectToPrevious(String defaultAction, String defaultController)
{
  if (Session == null || Session["PrevUrl"] == null)
  {
      return RedirectToAction(defaultAction, defaultController);
  }

  String url = ((Uri)Session["PrevUrl"]).PathAndQuery;

  if (Request.Url != null && Request.Url.PathAndQuery != url)
  {
      return Redirect(url);
  }

  return RedirectToAction(defaultAction, defaultController);
}


protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var httpContext = filterContext.HttpContext;

    if (httpContext.Request.RequestType == "GET"
        && !httpContext.Request.IsAjaxRequest()
        && filterContext.IsChildAction == false)    // do no overwrite if we do child action.
    {
        // stop overwriting previous page if we just reload the current page.
        if (Session["CurUrl"] != null 
            && ((Uri)Session["CurUrl"]).Equals(httpContext.Request.Url) ) 
            return;

        Session["PrevUrl"] = Session["CurUrl"] ?? httpContext.Request.Url;
        Session["CurUrl"] = httpContext.Request.Url;
    }
}
}

Now, as I figured, it is not the best idea for redirecting everything by default. For validation purposes you would like not to redirect

Then you can reference Session[“PrevUrl”] in controllers, but there is a better way of doing it – create attribute!

public class RedirectToPreviousPageAttribute : ActionFilterAttribute
{
///

/// Place [RedirectToPreviousPage] attribute on Controller action
/// and when you do submit of form, this functionality will kick in.
/// We check if Session has Previous URL set and force to redirect
/// to whatever it says.
/// If no Session variable is set, just do what it is supposed to do in the first place.
///

/// public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var httpContext = filterContext.HttpContext;

    if (httpContext.Session == null || httpContext.Session["PrevUrl"] == null)
    {
        base.OnResultExecuted(filterContext);
        return;
    }

    String url = ((Uri)httpContext.Session["PrevUrl"]).PathAndQuery;

    if (httpContext.Request.Url != null && httpContext.Request.Url.PathAndQuery != url)
    {
        httpContext.Response.Redirect(url);
    }


    base.OnResultExecuted(filterContext);

}

}

And now, wherever you are put this attribute on a controller action (or entire controller), it will redirect to the previous page:

[HttpPost]
public virtual ActionResult Edit(Model model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    _repository.InsertOrUpdate(model);
    _repository.Save();

    return RedirectToPrevious("Index", "Controller");
}

VoilĂ ! Good to go!

Dependency resolver in .Net

Ninject is very cool and lightweight DI container.
But you can not always inject objects through constructor – sometimes you must have parameter-less constructor, like in MvcApplication object.
In that case you can use DependencyResolver from System.Web.Mvc namespace from System.Web assembly

_userDataService = 
DependencyResolver.Current.GetService<IUserDataService>();

Unfortunately MSDN documentation does not have much, only link to this blog post: http://bradwilson.typepad.com/blog/2010/10/service-location-pt5-idependencyresolver.html

Razor view: conditionally include debug versions of JS libraries

In Razor compiler directives do not work, cause Razor Views are not compiled.
So this would not work:

@{ #if DEBUG}

@{#else}

@{#endif}

But you can trick that thing into submission, thanks to this StackOverflow topic

A better, more generic solution is to use an extension method, so all views have access to it:

public static bool IsReleaseBuild()
{
#if DEBUG
    return false;
#else
    return true;
#endif
}

You can then use it like follows in any view (razor syntax):

@if(IsReleaseBuild())

Generate T4MVC templates

Everybody is talking how good the T4 templates, but nobody tells you how to generates the bloody things.

In VS2012 if you open command window (View-> Other Windows -> Command Window) and execute
TextTransformation.TransformAllTemplates – that should do the trick.

If you would like a button for that – add Build Toolbar Panel and it should contain “Transform All Templates” button.

Or you can install Chirpy and configure it to do T4MVC for you on every build: