In my index.cshtml I want to display the WizardStepAttribute
Value
So, a user will see at the top of each page,
It can be done, but it is neither easy nor pretty.
First, I would suggest adding a second string property to your WizardStepAttribute class, StepNumber, so that your WizardStepAttribute class looks like this:
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class WizardStepAttribute : Attribute
{
public string StepNumber { get; set; }
public string Name { get; set; }
}
Then, each class must be decorated:
[WizardAttribute(Name = "Enter User Information", StepNumber = "1")]
public class Step1 : IStepViewModel
{
...
}
Next, you need to create a custom DataAnnotationsModelMetadataProvider, to take the values of your custom attribute and insert them into the Step1 model's metadata:
public class MyModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable attributes,
Type containerType,
Func
Then, to present your custom metadata, I suggest creating a custom HtmlHelper to create your label for each view:
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString WizardStepLabelFor(this HtmlHelper htmlHelper, Expression> expression)
{
return WizardStepLabelFor(htmlHelper, expression, null /* htmlAttributes */);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString WizardStepLabelFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes)
{
return WizardStepLabelFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes));
}
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString WizardStepLabelFor(this HtmlHelper htmlHelper, Expression> expression, IDictionary htmlAttributes)
{
if (expression == null)
{
throw new ArgumentNullException("expression");
}
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var values = metadata.AdditionalValues;
// build wizard step label
StringBuilder labelSb = new StringBuilder();
TagBuilder label = new TagBuilder("h3");
label.MergeAttributes(htmlAttributes);
label.InnerHtml = "Step " + values["StepNumber"] + ": " + values["Name"];
labelSb.Append(label.ToString(TagRenderMode.Normal));
return new MvcHtmlString(labelSb.ToString() + "\r");
}
As you can see, the custom helper creates an h3 tag with your custom metadata.
Then, finally, in your view, put in the following:
@Html.WizardStepLabelFor(model => model)
Two notes: first, in your Global.asax.cs file, add the following to Application_Start():
ModelMetadataProviders.Current = new MyModelMetadataProvider();
Second, in the web.config in the Views folder, make sure to add the namespace for your custom HtmlHelper class:
Voila.
counsellorben