Introduction
Have you ever needed to get a simple property name from MVC View Model?
"Why would I need that?" - you may ask. The answer is pretty simple - if you have jQuery/JavaScript code that works with form elements created from view model, you can have those element names strongly typed in your JavaScript. Also it might be useful in some content output scenarios as well.
What we need
Let's say we have this class:
public class SomeClass {public class SomeClass {
public string SomeProperty { get; set; }
}
And we have a view model that implements the class above:
public class SomeViewModel{
public SomeClass SomeClass { get; set; }
}
Then on our MVC View, which inherits from our view model 'SomeViewModel
', you have a text box on your form:
@Html.TextBoxFor(model => model.SomeClass.SomeProperty)
Which creates html:
<input id="SomeClass_SomeProperty" name="SomeClass.SomeProperty" type="text">
And, for example, you want to add a JQuery UI Datepicker to that text box:
$('#Someclass_SomeProperty').datepicker();
But if we rename 'SomeProperty
' property or 'SomeClass
' class, we'll have to manually rename references to it from jQuery. Which might be unpleasant with a large amount of jQuery code.
So, we need to have this 'Someclass_SomeProperty
' created in a strongly typed manner. How do we do that?
Create HtmlHelper Extension
We will create a simple extension of the MVC HtmlHelper class. So, first let's create an extension class anywhere in the project:
using System;
using System.Linq.Expressions;
using System.Web.Mvc;
public static class MvcExtensions {
public static string GetPropertyName<TModel>
(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, object>> propertyNameExpr) {
return ExpressionHelper.GetExpressionText(propertyNameExpr).Replace('.', '_');
}
}
Then on the view, when we want to add a
jQuery UI datepicker to textbox, we do this:
$('#@Html.GetPropertyName(model => model.SampleClass.SampleProperty)').datepicker();
And the output is:
$('#Someclass_SomeProperty').datepicker();
Which is just what we wanted!
Additionally, if we just need to get the name of the property, but not the class, add this extension to class MvcExtensions
:
public static string GetPropertyNameShort<TModel>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, object>> propertyNameExpr) {
var expression = ExpressionHelper.GetExpressionText(propertyNameExpr);
return expression.Substring(expression.LastIndexOf('.') + 1);
}
So now, the same code on the view will return this:
$('#SomeProperty').datepicker();
I found this extension to be very useful in large complex applications, especially after you use ReSharper to rename classes/properties.
P.S.
A little amendment - this code from extensions above:
var expression = ExpressionHelper.GetExpressionText(propertyNameExpr);
Will work fine, but will fail when either class or property is null. If you need it to work on null properties/values, change line above like this:
var lambda = propertyNameExpr as LambdaExpression;
var expression = lambda.Body.ToString().Replace(")", "");
return expression.Substring(expression.IndexOf('.') + 1);
And that's all folks, thank you for reading!