This project is read-only.

Use of DataAnnotations for Formatting in View Model

Topics: Customizing Orchard, Writing modules
Nov 14, 2012 at 12:37 AM

Is it possible to use MVC DataAnnotations to control the formatting of my properties within a view model in Orchard?  For example, if I wanted to format a DateTime property so that it always displays just the date and not the time, in standard MVC I would add the following annotation above my property.

[DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]

However, in Orchard, it appears to be ignoring this property.  The only annotation I have found that works is the [Required] annotation, but even with that, if I use [Required(ErrorMessage="Please enter this data")], the ErrorMessage text isn't being displayed.

Nov 14, 2012 at 12:38 AM

Just use shape templates. That's the Orchard way.

Nov 14, 2012 at 12:44 AM
Edited Nov 14, 2012 at 12:46 AM

Thanks for the very quick response Bertrand, but here's my issue.  In my custom Type, I have a display template that looks like the following:

    <p>Size: @Model.PropertyPart.SquareFootage</p>
    <p>Built: @Model.PropertyPart.YearBuilt</p>
    <p>Date Acquired: @Model.PropertyPart.AcquisitionDate.ToString("MMMM yyyy")</p>
    <p>Date of Disposition: @Model.PropertyPart.DispositionDate.ToString("MMMM yyyy")</p>

First, it seems "hokey" to do this in the view when MVC typically uses the DataAnnotations on a ViewModel to do this for all views that are passed the ViewModel.  In my case, I have to add (and maintain) this code in the standard display and EditorTemplate views.  Secondly, if a value is null, it throws an error, so I have to do additional null checking before I pass the ViewModel in.  With the DataAnnotations, null checking is done automatically.  Is there a better way than what I am doing?

Nov 14, 2012 at 1:01 AM

I just checked, and the EditorFor and DisplayFor methods are the ones from System.Web.Mvc, so you should be able to use that. Actually I just tried it out, with success. What I did was create a view model with a DateTime property and the DisplayFormat annotation, then render that property using Html.DisplayFor in the view.

Nov 14, 2012 at 1:19 AM

Skywalker, thank you very much.  I should have realized that.  It points me in the right direction, but one final question.  I don't think I'm coding my driver properly to pass it a ViewModel within the Display method.  I'm actually following most of the code on your website, but I'm confused on how to use ViewModels with the Display method.  Here's my code in the driver:

protected override DriverResult Display(PropertyPart part, string displayType, dynamic shapeHelper) {
			var viewModel = PropertyMaps.Map(part);
			return ContentShape("Parts_Property", () => 
				shapeHelper.Parts_Property(ViewModel: viewModel));

And here's the code in my shape template ("Parts/Property.cshtml")

@using Foo.Properties.ViewModels
@{ var viewModel = (PropertyViewModel)Model.ViewModel; }
	<p>Size: @viewModel.SquareFootage</p>
	<p>Built: @viewModel.YearBuilt</p>
	@Html.DisplayFor(m => m.viewModel.AcquisitionDate)
	@Html.DisplayFor(m => m.viewModel.DispositionDate)

Now, when I try that, I get an error stating "An expression tree may not contain a dynamic operation".  Am I not passing in the ViewModel properly?

Nov 14, 2012 at 2:23 AM

Nevermind Skywalker.  I figured it out with some help from the post at (  I appreciate you pointing me in the right direction.  

For everyone else, here's how I figured out how to pass a strongly typed view to the Display method and how to render it in the view.  Please let me know if anything you see here is incorrect.

Basically, I created a folder called DisplayTemplates under Views and then added the view template there.  Then I changed the Display method to call shapeHelper.DisplayTemplate and passed in the TemplateName and Model.  Finally, I then declared the model on my view.  Here's the code.

In the Display method of the driver:

protected override DriverResult Display(PropertyPart part, string displayType, dynamic shapeHelper) {
	var viewModel = PropertyMaps.Map(part);
	return ContentShape("Parts_Property", () =>
		shapeHelper.DisplayTemplate(TemplateName: "Parts/Property", Model: viewModel));

Then for the view which I moved to: Views/DisplayTemplates/Parts/Property.cshtml:

@using Foo.Properties.ViewModels
@model PropertyViewModel
	<p>Size: @Html.DisplayFor(m => m.SquareFootage) sq. ft.</p>
	<p>Built: @Html.DisplayFor(m => m.YearBuilt)</p>
	<p>Acquisition Date: @Html.DisplayFor(m => m.AcquisitionDate)</p>
	<p>Date of Disposition: @Html.DisplayFor(m => m.DispositionDate)</p>
Oct 1, 2013 at 1:14 PM
Edited Oct 3, 2013 at 8:11 AM
Hi, thanks for the post. Was very useful.

In continuation to this, if the model state is not valid on post to a controller action, I want to show the same template with validation errors? Since the template is in DisplayTemplates folder, returning a view doesn't work as it does not look in the DisplayTemplates Folder of a module.