Thursday, December 15, 2011

Using Entity Framework-based Repository Pattern in MVC Causes Errors

Using Entity Framework 4.0 in an MVC 3.0 application using the repository pattern where the data model is created in a separate project can result in compilation errors generated when the view are requested. Basically the views fail to compile properly if the view's model is an IEnumerable type of an entity object.

The compiler error message is not very helpful (though it gives hints)

Compiler Error Message: BC30456: 'Title' is not a member of 'ASP.views_

This indicates that the View object failed to compile all together and this only happens when the Entity Framework generated objects are involved in the model of the View.


Line 1:  <%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable (Of WebApp.Domain.MyModelObject))" %>


One way to force the compiler to give a better message is to have the view accept a generic object and then later in the view code cast the object to what it really is (in this case an IEnumerable (Of WebApp.Domain.MyModelObject)

So the new Page directive looks like

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of Object)" %>

And now instead of using Model right away, we have to cast it to its actual type

<% Dim modelData = CType(Me.Model , IEnumerable(Of WebApp.Domain.MyModelObject)) %>


Doing the above changes causes the compiler to give a better message because it's now able to compile the view but at run-time it finds that there are missing assemblies (the message below explains it)

Compiler Error Message: BC30007: Reference required to assembly 'System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' containing the base class 'System.Data.Objects.DataClasses.EntityObject'. Add one to your project.

And the guilty line that caused the error as you might have expected is

<% Dim modelData = CType(Me.Model , IEnumerable(Of WebApp.Domain.MyModelObject ))  %>

And now it's obvious that we need to add the references to our web.config (system.web -> compilation -> assemblies)
<add assembly ="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

There are other reasons why this error might come up which may not have to do with Entity Framework
look here for more http://stackoverflow.com/questions/1545538/asp-net-error-bc30456-title-is-not-a-member-of-asp-views-controllername-view