ASP.NET MVC: Constructing UrlHelper

I needed to have a class external to the controller’s and views that could generate a correctly formed Url using the UrlHelper.

I found this question on Stackoverflow which helped me with a solution. The solution was as follows:

HttpContextWrapper httpContextWrapper =
    new HttpContextWrapper(HttpContext.Current);

UrlHelper urlHelper = new UrlHelper(
    new RequestContext(
        httpContextWrapper, 
        new RouteData()));

I previously got confused about the RouteData object, but it seems (unless I’m mistaken) to essentially be route values, which in this case i don’t need… Not sure on that though!

As constructed above, the UrlHelper is able to take the RequestContext and get all the registered routes and therefore generate a correctly structured url when you call Action etc.

Advertisements

Upgrade to MVC 2 causes Unable to cast object of type ‘System.Web.UI.Triplet’ to type ‘System.Object[]’ relating to AntiForgeryToken

This has something to do with the way that MVC 1 and MVC 2 generate anti forgery tokens. It seems they might do things differently.

The solution is to clear your browser cookies.

James Crowley has a bit of information on it (first link in resources below!)

Resources

http://weblogs.asp.net/james_crowley/archive/2010/03/18/beware-upgrade-to-asp-net-mvc-2-0-with-care-if-you-use-antiforgerytoken.aspx

http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=199385

MVC 2 Strongly Typed Helper Method

Some quick information about generating a strongly types helper method in MVC 2: Covers:

  • An Expression as a method argument
  • Getting a valid name for the form field
  • Getting type information about the property specified on the view.

An Expression as a method argument

The Below gives a basic example of a strongly types helper method definition

public static MvcHtmlString MyHelperFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression)

{
}

Getting a valid name for the form field

Say we put this into the view

<%= Html.EnumDropDownFor(Model => Model.ContactDetails.Phone.Type) %>

We can generate a form field name like this:

var fullPropertyPath =
    htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(
        ExpressionHelper.GetExpressionText(expression)); 

This would result in fullPropertyPath being “ContactDetails.Phone.Type”. We can then use this as the name attribute on the form field we render.

Getting type information about the property specified on the view.

We can also get meta data about the type that the …Phone.Type property get’s/sets using ModelMetadata class’s FromLambdaExpression method like this:

var modelMetadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(
    expression, htmlHelper.ViewData);

var propertyType = modelMetadata.ModelType;

Custom Server and Client Side Required Validator in MVC 2 using jQuery.validate

This post has been moved here.

Satellite Assemblies – Example in ASP.NET MVC

We were trying to create satellite assemblies for globalization and figured it out in an MVC application…

first time using YouTube… it’s not very clear, but hopefully it helps! … hopefully when this one has finished processing it will be clearer than it is now… as i said. noob at the (you)tube!

Steps are basically:

  1. Add the globalization attribute in the Web.config file
  2. Add a folder for the resx files.  (we don’t want it in App_GlobalData as it won’t be compiled into the current assembly, but a seperate one!)
  3. Create your resx file and contents
  4. Ensure the resx is set to public.
  5. Copy the resx
  6. Create translation (say fr for french)
  7. Create the view to show the contents
  8. Test in both languages

So it’s very simple: Create the resx files, ensure they are public (not 100% whether this is needed, not tested yet!) set the globalization attribute in web.config and change your browser language to test!

Creating a Custom Controller Factory

Quick notes about replacing the current controller factory in ASP.NET MVC

How to Create the Custom Controller Factory

  1. Create a class that inherits from DefaultControllerFactory (see this)
  2. Set the controller factory in application start (see this)

That’s should be about it 🙂

Why would you implement a custom controller factory? (Thoughts for me relating specifically to IoC)

  1. You can configure which type of controller you want, so you can configure the IoC container to load a new class that is in a dll that you chuck in the bin directory.
  2. You can inject the dependencies (like repositories) into the constructor automatically

Other interesting tidbits.

Html.RenderPartial in ASP.NET MVC

Just some notes on RenderPartial in ASP.NET MVC

  • If you only include the name of the partial (excluding the extension) the framework will look for the partial by
  1. Looking in the current directory (of the view that RenderPartial is being called from) and adding the extension .aspx to the partial name
  2. Looking in the current directory (of the view that RenderPartial is being called from) and adding the extension .ascx to the partial name
  3. Looking in the Views/Shared folder for the partial and adding the extension .aspx to the partial name
  4. Looking in the Views/Shared folder for the partial and adding the extension .ascx to the partial name.
  • You can’t put the extension on the end of the partial name like this as you will get an error due to the framework appending the aspx or ascx extensions to this partial name so that you end up with RenderPartial_ThisOne.ascx.aspx and RenderPartial_ThisOne.ascx.ascx, which, needless to say, is not what you would be looking for.

<% Html.RenderPartial("RenderPartial_ThisOne.ascx"); %>

  • You can pass to render partial a tilde-styled uri pointing to a partial as follows, as this is considered to be a fully qualified path to the partial. Nothing is added to the path, it is just make relative to the current application. In my opinion this is a better way to do it as it is 1. Clearer where the partial is 2. The framework doesn’t have to look in several places to find the file instead it knows exactly where it is.

<% Html.RenderPartial("~/Partials/RenderPartial_ThisOne.ascx"); %>

  • You can pass ViewData to Partials as follows.

<% Html.RenderPartial("SharedTestPartial", "This is the model Data", new ViewDataDictionary { { "MyID", 12 }}); %>

  • Remember that when ViewData is NOT passed to the Partial the Whole ViewData of the View will be passed to the Partial. (a copy of the ViewData is passed… see the next point)
  • Note that if the ViewData is edited in a partial those changes will not be reflected in the ViewData of the View that called the partial (Much like parsing a value type to a function which alters the parameter doesn’t alter the calling functions version of the variable).