1

I have refactored an application which uses EF5 Database First. The application uses metadata classes to add data annotations to the entity properties. Before the refactor, these worked. They are mostly just display names and data formats.

Example:

    [MetadataType(typeof(QueryDetailsResultMetadata))]
    public partial class QueryDetailsResult : IPortfolio
    {
        public string Source { get { return "Local"; } }
    }

    public class QueryDetailsResultMetadata
    {
        //Fields from QueryDetailsResult requiring annotations

        [Display(Name = "Company Name")]
        public string SiteName { get; set; }

        [Display(Name = "Contact Telephone Number")]
        public string ContactTelNo { get; set; }
    }

Before the refactor, the partial class did not inherit from an interface and it did not have the non mapped property. These changes are however required. Neither of these two should be causing a problem as both are well documented as valid solutions.

The interface looks like this

public interface IPortfolio
{
    int Id { get; set; }
    string SiteName { get; set; }
    string YearOfManufacture { get; set; }
    string Contact { get; set; }
    string ContactTelNo { get; set; }
    string Source { get;}
}

The display uses the properties like this

@Html.DisplayNameFor(model => model.Portfolio.ContactTelNo)

On the View at runtime, the property names are shown rather than the display names. Any ideas why? I can't see any reason for the annotations to be broken

//edit

I tried moving the annotations on to the new non-mapped fields in the partial and removed them from the metadata class. To seee if it had any effect. None. Also double checked the edmx is in the same Namespace as the partial class and metadata file which it is.

Any thoughts on what to check or try? Not having much success this end, most google results are just saying to use a metadata class which is already in place.

//2nd Edit

Moving annotations out of metadata class and on to the interface did the trick.

Lotok
  • 4,517
  • 1
  • 34
  • 44
  • The problems is with your new `IPortfolio` interface ... http://stackoverflow.com/questions/2652811/asp-net-mvc-displayattribute-and-interfaces – nemesv Jan 01 '14 at 22:36
  • I was under the impression [annotations on an interface](http://stackoverflow.com/questions/5919567/is-it-possible-to-use-dataannotations-with-interfaces) doesn't work. I will give this a shot! Thanks – Lotok Jan 01 '14 at 22:41
  • @nemesv Can you please re-add that as an answer so I can accept it and assign you points. Worked a treat. The annotations aren't even needed in metadata class now. I suppose Microsoft Team changed their mind as they seemed against implementing it in the link I posted above. Thanks v much! – Lotok Jan 02 '14 at 21:10

1 Answers1

3

It is a little bit confusing how the DataAnnotation attributes are wroking with interfaces because:

But how it works only depends on the type of your "container" in the view so lets consider the following types:

public class QueryDetailsResult : IPortfolio
{
    public string SiteName { get; set; }
}

public interface IPortfolio
{
    string SiteName { get; set; }
}

So if you have @Html.DisplayNameFor(model => model.Portfolio.SiteName) in your view

  • and your model class looks like

    public class Model {
       public QueryDetailsResult Portfolio { get; set; }
    } 
    

    then you need to put the DisplayAttribute on the SiteName property of your QueryDetailsResult class because MVC looks for the "container" type in the model.Portfolio.SiteName expression which is QueryDetailsResult

  • but if you have your model class defined as

    public class Model {
       public IPortfolio Portfolio { get; set; }
    } 
    

    then you need to put it on the SiteName property of the IPortfolio interface because your "container" type is the IPortfolio interface.

Community
  • 1
  • 1
nemesv
  • 138,284
  • 16
  • 416
  • 359