views:

358

answers:

3

Consider an extension method whose purpose is to either:

  • render an <a> tag
  • on some condition, just return a string without a link

  Question: in an extension method, how can you leverage the proper routing logic with Route Values, etc. rather than hardcoding the string. I suspect HtmlHelper.GenerateRouteLink is part of the solution, but please suggest the best way to achieve this.

public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
    if (string.IsNullOrEmpty(userAcctName))
        return "--Blank--";

    //some lookup to A.D.            
    DomainUser user = ADLookup.GetUserByAcctName(userAcctName);

    if (user == null)
        return userAcctName;

    //would like to do this correctly!
    return string.Format("<a href='/MyAppName/User/View/{0}' title='{2}'>{1}</a>"
                        , user.Mnemonic, user.DisplayName, user.Location);

    //normally returns http://mysite.net/MyAppName/User/View/FOO
    }

More info:

  • using ASP.NET MVC 1.0

alt text

+2  A: 

would this work?

public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
    if (string.IsNullOrEmpty(userAcctName))
        return "--Blank--";

    //some lookup to A.D.            
    DomainUser user = ADLookup.GetUserByAcctName(userAcctName);

    if (user == null)
        return userAcctName;

    return html.ActionLink(user.DisplayName, "user", "View", new {title=user.Location});
    //normally returns http://mysite.net/MyAppName/User/View/FOO
}
Pharabus
Thanks Pharabus; Unfortunately `html` doesn't have/show that method as available.
p.campbell
really? it is a helper method under the System.Web.Mvc.Html namespace for the htmlHelper class. What version of Asp.NEt MVC framework are you using?
Pharabus
+1  A: 

My experience with GenerateRouteLink has been an uphill battle. It's been a while since I messed with it but if it's the Method I'm thinking of Microsoft has made it "internal" so you can't access and use it outside the MVC assembly. There are a number of workarounds that I played with and didn't really like.

What I ended up doing to avoid hard coding the url in my helper methods is have it accept a 'string url' parameter and use Url.Action in my view when I call the helper method. It's not the cleanest but it's a workaround that worked well for me.

<%= Html.CreateUserLink("userAcctName", Url.Action("Home", "Controller") %>
DM
+3  A: 

I just had to do something similar to this yesterday. There may be a slicker way to do it, but it helps me to see exactly what is going on, so I don't assume anything.

public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
    if (string.IsNullOrEmpty(userAcctName))
        return "--Blank--";

    //some lookup to A.D.            
    DomainUser user = ADLookup.GetUserByAcctName(userAcctName);

    if (user == null)
        return userAcctName;

    RouteValueDictionary routeValues = new RouteValueDictionary();

    routeValues.Add("controller", "User");
    routeValues.Add("action", "View");
    routeValues.Add("id", user.Mnemonic);

    UrlHelper urlHelper = new UrlHelper(html.ViewContext.RequestContext);
    TagBuilder linkTag = new TagBuilder("a");

    linkTag.MergeAttribute("href", urlHelper.RouteUrl(routeValues));
    linkTag.MergeAttribute("title", user.Location);
    linkTag.InnerHtml = user.DisplayName;

    return linkTag.ToString(TagRenderMode.Normal);
}
Neil T.
+1 Thanks Neil. I've edited your answer to suit the changes I made to get it to work. `MergeAttribute` was more appropriate, and the ViewContext.RequestContext was the object available instead of ResponseContext. Thank you for this sample code!
p.campbell
Nice solution. +1
DM