views:

307

answers:

3

I know that I have seen this before. I can't remember if it was a C4MVC template demo or an input builder thing! I need to know how I can use the convention of CamelCasing my view model properties and having the "CamelCasedProperty" rendered in the label as "Camel Cased Property". This should be handled by the create new view wizard rather than programatically handling this.

+1  A: 

I don't think what you want is possible in vanilla ASP.NET MVC 2.

In ASP.NET MVC 2 you need to decorate your model with a DisplayName attribute with the text you want and then the auto generated wizard will use LabelFor to output the label for the property. Eg:

class MyModel()
{
    [DisplayName("Your Property Name")]
    public string YourPropertyName { get; set; }
}

Then in the view:

<%= Html.LabelFor(m => m.YourPropertyName) %>

If you saw a demo of it being done some other way it could have been from the MvcContrib project for InputBuilders.

Here is direct link to the part of the project I think your referring to:

http://www.lostechies.com/blogs/hex/archive/2009/06/09/opinionated-input-builders-for-asp-net-mvc-part-2-html-layout-for-the-label.aspx

The text highlighted in red are labels that come from the Model type. The label is created from the PropertyInfo object that represents the respective properties of the mode.

The label is Property Name.

The label is the Property Name that is split on the pascal case property name.

The label is specified by using the Label Attribute applied to the property.

Kelsey
+1 Thank you for the info! The DisplayName attribute certainly does what I want in that it allows me to override the properties name when generating the UI. I thought I saw something like a T4 template or something that didn't require to much additional work to do the camel case splitting.
Andrew Siemer
Check out the links I posted, they show examples of it in action but it is not built in out of the box.
Kelsey
Although the code I posted in my answer does what I asked for...I think your answer is more correct in that it points to external resources and projects that are public owned! I will mark your answer as the winner of the chicken dinner! Thanks for your help.
Andrew Siemer
+1  A: 

After some poking around I sort of found a lead to what I was interested in doing. Watching this C4MVC video. I am sure that this might already be completed in MVC Contrib as an input builder. However, I am very interested in understanding all the under pinnings so to speak to learn all that I can for my upcoming book "ASP.NET MVC Cookbook" (shameless plug for public review). Here is the solution I came up with that only requires me to rename the Html.LabelFor to Html.LabelFor2 in the generated code form the "create new view":

I created a method to get the property name from the passed in lambda. I then created another method to parse the property name on the upper case letters contained in the name.

using System;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

namespace FuryPartners.WebClient.Helpers
{
    public class HelperUtilities
    {
        internal static string PropertyName<T, TResult>(Expression<Func<T, TResult>> expression)
        {
            switch (expression.Body.NodeType)
            {
                case ExpressionType.MemberAccess:
                    var memberExpression = expression.Body as MemberExpression;
                    return memberExpression.Member.Name;
                default:
                    return "oops";
            }
        }

        internal static string SplitCamelCase(string camelCaseString)
        {
            string output = System.Text.RegularExpressions.Regex.Replace(
                camelCaseString,
                "([A-Z])",
                " $1",
                RegexOptions.Compiled).Trim();
            return output;
        }
    }
}

I then extended HtmlHelper to have a LabelFor2 method which builds and passes out the appropriate display format of a property name.

using System;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace FuryPartners.WebClient.Helpers
{
    public static class LabelHelpers
    {
        public static MvcHtmlString LabelFor2<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression)
        {
            string propertyName = HelperUtilities.PropertyName(expression);
            string labelValue = HelperUtilities.SplitCamelCase(propertyName);

            string label = String.Format("<label for=\"{0}\">{1}</label>", propertyName, labelValue);
            return MvcHtmlString.Create(label);
        }
    }
}
Andrew Siemer
A: 

I have a simpler new version to create a Title-ized label from Andrews answer, using the MVC2 code to respect any [DisplayName(...)] attributes

public static class LabelHelpers
{
    public static MvcHtmlString LabelTitleizeFor<T, TResult>(this HtmlHelper<T> helper, Expression<Func<T, TResult>> expression)
    {
        string propertyName = ExpressionHelper.GetExpressionText(expression);
        string labelValue = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).DisplayName;

        if (string.IsNullOrEmpty(labelValue))
        {
            labelValue = Inflector.Net.Inflector.Titleize(propertyName);
        }

        string label = String.Format("<label for=\"{0}\">{1}</label>", propertyName, labelValue);
        return MvcHtmlString.Create(label);
    }
}

using http://cid-net.googlecode.com/svn/trunk/src/Cid.Mvc/Inflector.cs

Jason More