ilivewithian
ilivewithian

Reputation: 19692

Is it possible to build an ASP MVC app without magic strings in views?

I'm very new to ASP .Net MVC, I bought the Pro ASP .Net MVC Framework book from Apress last week and it's proving to be very helpful.

The problem that I'm seeing so far is that almost all the example views are riddled with magic strings. I've managed to go through and figure out a few alternatives, but the code starts to get kinda difficult to read. For example:

<% using(Html.BeginForm("RemoveFromCart", "Cart")){ %>
    <%= Html.Hidden("ProductID", line.Product.ProductID) %>
    <%= Html.Hidden("returnUrl", ViewData["returnRrl"]) %>
    <input type="submit" value="Remove" />
<% } %>

Becomes:

<% using (Html.BeginForm<CartController>(c => c.RemoveFromCart(null, line.Product.ProductID, (string)ViewData["returnUrl"]))) { %>
    <input type="submit" value="Remove" />
<% } %>

I can get away with this example, because the first parameter to RemoveFromCart is pulled from the session via a ModelBinder, but it's not intuitive to read.

My concern is that I'm going to spend my time fighting the framework to avoid magic strings and in the process end up with mark up that's a pain to read. In peoples experience is this a valid concern and is there a reference on the web where there is a "magic string method" to "type safe method" lookup table?

Upvotes: 7

Views: 1509

Answers (4)

synhershko
synhershko

Reputation: 4492

I would highly recommend this read - it's short and summarizes all the basics in a very clear way. It was written by Scott Guthrie, who is the .NET MVC PM among other things in MS: http://weblogs.asp.net/scottgu/archive/2009/04/28/free-asp-net-mvc-nerddinner-tutorial-now-in-html.aspx

Upvotes: 0

OdeToCode
OdeToCode

Reputation: 4986

By using T4MVC and the MVC Futures, you can easily eliminate 99% of the magic strings.

Both of those projects are available from http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471

T4MVC will take care of controllers, actions, and routing, while the futures stuff has strongly-typed HTML helpers. The MVCContrib project is another project to look at, as it includes some strongly-typed fluent HTML builders.

Upvotes: 6

Robert Harvey
Robert Harvey

Reputation: 180787

I read with interest this blog post from LosTechies:
A new breed of magic strings in ASP.NET MVC

They suggest changing this:

Url.Action<ProductsController>(x => x.Edit(null), new { productId = prodId })

which contains the magic string productID, to this:

Url.Action<ProductsController>(x => x.Edit(null), 
    new RouteValueDictionary { { ProductsController.ProductId, prodId } })

ProductId is now strongly-typed.

Or you can create a real object instead of an anonymous one:

Url.Action<ProductsController>(x => x.Edit(null), 
    new EditProductParams { product = prodId })

But now you need this:

public class EditProductParams
{
    public Guid product { get; set; }
}

Their last suggestion is to use a fluent interface. You can write this:

Url.Action<ProductsController>(x => x.Edit(null, null), 
    Params.Product(product).Customer(customer))

Which looks pretty clean (if a little redundant), but it requires this:

public static class Params
{
    public static ParamBuilder Product(Product product)
    {
        var builder = new ParamBuilder();

        return builder.Product(product);
    }

    public static ParamBuilder Customer(Customer customer)
    {
        var builder = new ParamBuilder();

        return builder.Customer(customer);
    }
}

...and this:

public class ParamBuilder
{
    private Product _product;
    private Customer _customer;

    public ParamBuilder Product(Product product)
    {
        _product = product;
        return this;
    }

    public ParamBuilder Customer(Customer customer)
    {
        _customer = customer;
        return this;
    }
}

...and this:

public static implicit operator RouteValueDictionary(ParamBuilder paramBuilder)
{
    var values = new Dictionary<string, object>();

    if (paramBuilder._product != null)
    {
        values.Add("p", paramBuilder._product.Id);
    }

    if (paramBuilder._product != null)
    {
        values.Add("c", paramBuilder._customer.Id);
    }

    return new RouteValueDictionary(values);
}

I could see this working if it could be written using generics, so that it would only have to be written once.

Upvotes: 4

theraneman
theraneman

Reputation: 1630

I think you might know this already, but we can certainly create strongly typed Views which would allow us to use Html.Encode(Model.PropertyName) format in the View. Here is a link which explains this

http://blogs.lessthandot.com/index.php/WebDev/WebDesignGraphicsStyling/me-and-asp-net-mvc-less-magic-strings .

Upvotes: 1

Related Questions