Sunday, June 3, 2012

MetadataException: Unable to load the specified metadata resource


All of a sudden I keep getting a MetadataException on instantiating my generated ObjectContext class. The connectionstring in App.Config looks correct - hasn't changed since last it worked - and I've tried regenerating a new model (edmx-file) from the underlying database with no change.



Anyone have any... ideas?



Edit: I haven't changed any properties, I haven't changed the name of any output assemblies, I haven't tried to embed the EDMX in the assembly. I've merely waited 10 hours from leaving work until I got back. And then it wasn't working anymore.



I've tried recreating the EDMX. I've tried recreating the project. I've even tried recreating the database, from scratch. No luck, whatsoever.



I'm truly stumped.


Source: Tips4all

21 comments:

  1. This means that the application is unable to load the EDMX. There are several things which can cause this.


    You might have changed the MetadataArtifactProcessing property of the model to Copy to Output Directory.
    The connection string could be wrong. I know you say you haven't changed it, but if you have changed other things (say, the name of an assembly), it could still be wrong.
    You might be using a post-compile task to embed the EDMX in the assembly, which is no longer working for some reason.


    In short, there is not really enough detail in your question to give an accurate answer, but hopefully these ideas should get you on the right track.

    Update: I've written a blog post with more complete steps for troubleshooting.

    ReplyDelete
  2. This little change help with this problem.

    I have Solution with 3 project.


    connectionString="metadata=res:///Model.Project.csdl|res:///Model.Project.ssdl|res://*/Model.Project.msl;


    change to


    connectionString="metadata=res://*/;

    ReplyDelete
  3. You can get this exception when the Edmx is in one project and you are using it from another.

    The reason is Res://*/ is a uri which points to resources in the CURRENT assembly. If the Edm is defined in a different assembly from the code which is using it, res://*/ is not going to work because the resource cannot be found.

    Instead of specifying ‘*’, you need to provide the full name of the assembly instead (including public key token). Eg:

    res://YourDataAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdefabcedf/YourEdmxFileName.csdl|res://...


    A better way to construct connection strings is with EntityConnectionStringBuilder:

    public static string GetSqlCeConnectionString(string fileName)
    {
    var csBuilder = new EntityConnectionStringBuilder();

    csBuilder.Provider = "System.Data.SqlServerCe.3.5";
    csBuilder.ProviderConnectionString = string.Format("Data Source={0};", fileName);

    csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
    typeof(YourObjectContextType).Assembly.FullName);

    return csBuilder.ToString();
    }

    public static string GetSqlConnectionString(string serverName, string databaseName)
    {
    SqlConnectionStringBuilder providerCs = new SqlConnectionStringBuilder();

    providerCs.DataSource = serverName;
    providerCs.InitialCatalog = databaseName;
    providerCs.IntegratedSecurity = true;

    var csBuilder = new EntityConnectionStringBuilder();

    csBuilder.Provider = "System.Data.SqlClient";
    csBuilder.ProviderConnectionString = providerCs.ToString();

    csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
    typeof(YourObjectContextType).Assembly.FullName);

    return csBuilder.ToString();
    }


    If you still encounter the exception, open the assembly in reflector and check the filenames for your .csdl, .ssdl and .msl files. When the resources have different names to the ones specified in the metadata value, it’s not going to work.

    ReplyDelete
  4. I had a similar error. I had recreated the project (long story), and pulled everything over from the old project. I hadn't realized that my model had been in a directory called 'Model' before, and was now in a directory called 'Models'. Once I changed the connection in my Web.Config from this:

    <add name="RecipeManagerEntities" connectionString="metadata=res://*/Model.Recipe.csdl


    to this:

    <add name="RecipeManagerEntities" connectionString="metadata=res://*/Models.Recipe.csdl


    Everything worked. (Note that I had to change this three places in this string.

    ReplyDelete
  5. I had the same problem. I just had a look into my complied dll with reflector and see that the name of the ressource where not the right ones. I renamed and look fines now

    ReplyDelete
  6. This happened to me when I accidentally switched the Build Action of the edmx file (appears under Properties in the IDE) from 'EntityDeploy' to 'None'. EntityDeploy is what populates the metadata for you: see http://msdn.microsoft.com/en-us/library/cc982037.aspx

    ReplyDelete
  7. The ultimate solution (even after recreating the database on two other machines, as well as EDMX and other sundries) was to not use the horribly limited Entity Framework. Looking forward to evaluating it again in .NET 4.0.

    EDIT:

    After running into the same problem -again- and going all over teh googles for an answer, I finally found someone who'd had the same problem. It appears that the connectionstring wasn't correctly generated by Visual Studio's wizard, and the link to the metadata resources were missing an important path. Not completely bloody obvious, I tell you. =)

    http://forums.asp.net/p/1409590/3082930.aspx

    ReplyDelete
  8. I've just spent a happy 30 minutes with this. I'd renamed the entities object, renamed the entry in the config file, but there's more ... you have to change the reference to the csdl as well

    very easy to miss - if you're renaming, make sure you get everything ....

    ReplyDelete
  9. In my case, this issue was related to renaming my model's edmx file... correcting the app.config connection string for the csdl/ssdl/msl files fixed my issue.

    If you're using the EF 4.0 designer to generate your csdl/ssdl/msl, these 3 "files" will actually be stored within the model's main edmx file. In this case, the post by Waqas is pretty much on the mark. It's important to understand that "Model_Name" in his example will need to be changed to whatever the current name of your model's .edmx file (without the .edmx).

    Also, if your edmx file is not at the root level of your project, you need to preface Model_Name with the relative path, e.g.

    res://*/MyModel.WidgetModel.csdl|res://*/MyModel.WidgetModel.ssdl|res://*/MyModel.WidgetModel.msl


    would specify the csdl/ssdl/msl xml is stored in the model file 'WidgetModel.edmx' which is stored in a folder named 'MyModel'.

    ReplyDelete
  10. I have written this helper class to create instances of ObjectContext objects when they are defined in a different project than the project using it. I parse the connection string in the config file and replace '*' by the full assembly name.

    It is not perfect because it uses reflection to build the object, but it is the most generic way of doing it that I could find.

    Hope it helps someone.

    public static class EntityHelper<T> where T : ObjectContext
    {
    public static T CreateInstance()
    {
    // get the connection string from config file
    string connectionString = ConfigurationManager.ConnectionStrings[typeof(T).Name].ConnectionString;

    // parse the connection string
    var csBuilder = new EntityConnectionStringBuilder(connectionString);

    // replace * by the full name of the containing assembly
    csBuilder.Metadata = csBuilder.Metadata.Replace(
    "res://*/",
    string.Format("res://{0}/", typeof(T).Assembly.FullName));

    // return the object
    return Activator.CreateInstance(typeof(T), csBuilder.ToString()) as T;
    }
    }

    ReplyDelete
  11. For all of you SelftrackingEntities Users ,
    if you have followed the Microsoft Walk-through and separated the Object context class into
    the wcf service project (by linking to the context .tt) so this answer is for you :

    part of the shown answers in this post that includes code like :

    ... = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
    typeof(YourObjectContextType).Assembly.FullName);


    WILL NOT WORK FOR YOU !! the reason is that YourObjectContextType.Assembly now resides in a different Assembley (inside the wcf project assembly) ,

    So you should replace YourObjectContextType.Assembly.FullName with -->

    ClassTypeThatResidesInEdmProject.Assembly.FullName


    have fun.

    ReplyDelete
  12. For my case, it is solved by changing the properties of edmx file.
    1- Open the edmx file
    2- Right click on any place of the edmx desiner
    3- choose properties
    4- update Property called "Metadata Artifact Processing" to "Embed in Output Assembly"

    this solved the problem for me.
    The problem is, when the container try to find the meta data, it cant find it. so simply make it in the same assembly.
    this solution will not work if you have your edmx files in another assembly

    ReplyDelete
  13. I was able to resolve this in Visual Studio 2010, VB.net (ASP.NET) 4.0.

    During the entity model wizard, you will be able to see the entity connection string. From there you can copy and paste into your connection string.

    The only thing I was missing was the "App_Code." in the connections string.

    entityBuilder.Metadata = "res://*/App_Code.Model.csdl|res://*/App_Code.Model.ssdl|res://*/App_Code.Model.msl"

    ReplyDelete
  14. I deleted the app.connection string and started over.
    app.config stuff delete. Then re-add the entity data model stuff, it should be fine.

    ReplyDelete
  15. I also had the same problem and solution as per Rick, except that I was importing an existing .edmx to a new project, and while the base namespace didn't matter it was imported into a different subdirectory so I also had to update the connection string inside Web.Config in three places, to include the different subdirectory naming:

    ReplyDelete
  16. My theory is that if you have more than one edmx file with same name (Model1 for example), it will give that exception.
    I've got same problem when I decided to name all my edmx files (sitting in different projects) as Model1 because I thought they should be independent.

    ReplyDelete
  17. Another cause for this exception is when you include a related table in an ObjectQuery, but type in the wrong navigation property name.

    Example:

    var query = (from x in myDbObjectContext.Table1.Include("FKTableSpelledWrong") select x);

    ReplyDelete
  18. I was having problems with this same error message. My issue was resolved by closing and re-opening Visual Studio 2010.

    ReplyDelete
  19. Sometimes the assembly that contains the model is not loaded:

    [TestMethod]
    public void TestOpenWithConfigurationAfterExplicit()
    {
    String dummy = typeof(MallApp).Assembly.FullName;
    //force the assembly loaded.
    using (DbContext ctx = new DbContext("name=MyContainer))
    {
    }
    }


    The type MallApp lives in the same assembly as the entity model. Without the explicit loading, an System.Data.MetadataException will be thrown.

    ReplyDelete
  20. I had the same problem with a solution which contained projects in a Solution Folder, when they were moved to the Solution Root (in order to overcome a suspected bug with the Mvc3AppConverter due to project locations).

    Although the solution compiled after all* project references were re-added as needed, the error was thrown when the website was fired up.

    The EDMX is in one of the projects which was moved (the 'Data' project), but of course the lack of a reference to the Data project didn't cause a compile error, just a run-time error.

    Simply adding the missing reference to the primary project resolved this problem, no need to edit the connection at all.

    I hope this helps someone else.

    ReplyDelete
  21. Had same issue because I renamed an assembly.

    I had to also rename it in AssemblyTitle and AssemblyProduct attributes in project Properties/AssemblyInfo.cs, and also deleting and re adding the reference to the edmx file.

    Then it worked just fine.

    ReplyDelete