Entity Framework 6: Unable to load the specified metadata resource

c# configuration entity-framework entity-framework-6 windows-services

Question

First, this relates to a different query on SO:

I've read and fixed my problem with the following SO blog post and article:

Unable to load the requested metadata resource due to a metadata exception

and

http://blogs.teamb.com/craigstuntz/2010/08/13/38628/

However, I have more concerns than just this "repair."

I have a WebAPI (version 2.1), and the connection string is as follows:

    <connectionStrings>
<add name="ProjectEntities" connectionString="
     metadata=res://*/ProjectModel.csdl|
     res://*/ProjectModel.ssdl|
     res://*/ProjectModel.msl;          
     provider=System.Data.SqlClient;          
     provider connection string=&quot;          
     data source=192.168.0.1;          
     initial catalog=Project;          
     persist security info=True;          
     user id=***;          
     password=***;          
     multipleactiveresultsets=True;          
     App=EntityFramework&quot;" 
     providerName="System.Data.EntityClient" />

If I callToList() on aDbSet using my WebAPI's (false code)

DbContext _DbContext = new ProjectEntities();
DbSet<TEntity> _dbSet = _DbContext.Set<TEntity>();
_dbSet.ToList();

Very well done!

I receive the following issue when I call the same from within a Microsoft Service:Error

The connection string's app.config item is identical to the one for the web.config in every way.

<connectionStrings>
<add name="ProjectEntities" connectionString="
     metadata=res://*/ProjectModel.csdl|
     res://*/ProjectModel.ssdl|
     res://*/ProjectModel.msl;          
     provider=System.Data.SqlClient;          
     provider connection string=&quot;          
     data source=192.168.0.1;          
     initial catalog=Project;          
     persist security info=True;          
     user id=***;          
     password=***;          
     multipleactiveresultsets=True;          
     App=EntityFramework&quot;" 
     providerName="System.Data.EntityClient" />

The blog now demonstrates how to manually reference the dll as follows:

<connectionStrings>
    <add name="ProjectEntities" connectionString="
         metadata=res://Project.Data.dll/ProjectModel.csdl|
         res://Project.Data.dll/ProjectModel.ssdl|
         res://Project.Data.dll/ProjectModel.msl;          
         provider=System.Data.SqlClient;          
         provider connection string=&quot;          
         data source=192.168.0.1;          
         initial catalog=Project;          
         persist security info=True;          
         user id=***;          
         password=***;          
         multipleactiveresultsets=True;          
         App=EntityFramework&quot;" 
         providerName="System.Data.EntityClient" />
  </connectionStrings>

This does not resolve the problem.

Use of the fully qualified name is the only fix I've found so far:

<connectionStrings>
    <add name="ProjectEntities" connectionString="
         metadata=res://Project.Data, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null/ProjectModel.csdl|
         res://Project.Data, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null/ProjectModel.ssdl|
         res://Project.Data, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null/ProjectModel.msl;          
         provider=System.Data.SqlClient;          
         provider connection string=&quot;          
         data source=192.168.250.125\sqlexpress;          
         initial catalog=Project;          
         persist security info=True;          
         user id=***;          
         password=***;          
         multipleactiveresultsets=True;          
         App=EntityFramework&quot;" 
         providerName="System.Data.EntityClient" />
  </connectionStrings>

Why does this function in this way? Why does this function properly in a web project but not in a Windows service project? This error appeared after I upgraded from EF5 to EF6, even though the code was working before. Does anyone have any insight into why this is happening and whether I should be able to use the dll name * in my connection string?

I initially believed the problem was in the location of the service .exe and the failure to copy a file locally, but the Project.Data.dll is present and is the correct version.

I tried using FusionLog to locate the mistake, but I had no luck. I'm really perplexed.

1
9
5/23/2017 12:01:30 PM

Accepted Answer

Why does this occur?

Your problem is simply a result of extra security precautions taken to avoid binary planting or a DLL hijacking attack (View More) while your application is operating as a Windows service.

Why ought I to care?

As you are undoubtedly aware, every referenced DLL file is searched up in a certain, good documentation order. Typically, it begins by searching the DLL in the current application directory before moving on to more "public" places likePATH GAC, folders, etc.

The main concept of binary planting is to insert a malicious DLL file into a folder that is checked before the legitimate DLL folder. Such a rogue DLL would give the attacker control of the machine once loaded.

Windows services are a good target for binary planting attacks because they often run under an elevated account (NetworkService, LocalSystem, LocalService, etc.).

What should I do?

There is a compelling reason why Microsoft has taken extra security precautions to minimize hazards. However, you can try to resolve your problems.

1) The current directory does not match your expectations

In the system folder, a Windows service initially launches (typically, something likeC:\Windows\System32 )

The good news is that it can be fixed very quickly. Just change the current directory when the services start.

System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);

See Phil Haack's blog entry;

2) Carefully read the documentation

The wildcard character has a unique significance and limits where the runtime will check for DLL files, according to EF documentation:

If you specify a wildcard (*) for assemblyFullName, the Entity Framework runtime will search for resources in the following locations, in this order:

1) The calling assembly.

2) The referenced assemblies.

3) The assemblies in the bin directory of an application.

As your system folder is configured as your working folder and you likely don't have any references there, EF may end up looking in the incorrect places and your assemblies with resource-containing files may not load.

3) Use fully qualified assembly names to stay safe.

Although I am unsure of this and haven't tested it, Microsoft may have made it impossible for Windows services to load DLLs without supplying a fully qualified assembly name in order to lower the danger of malicious DLL files being injected;

here Good read on protecting your Windows services (specially chapter 5).

4) Fix it!

EF6 is an open source project by chance. This implies that you can obtain its complete source code and troubleshoot it. Zzz-129-Zzz is a project that is available on CodePlex.

5
4/13/2015 10:37:42 PM

Popular Answer

ZZZ_tmp


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow