views:

34

answers:

2

I have a Silverlight 4 app using RIA Services in which I moved all of the RIA Services-specific code to a separate module (a WCF RIA Services class library) called "AppServices". Let's call the main app "Silverlight4App". I need to authenticate the users against a different database than the database where the rest of the data is stored. I have added an EF model to AppServices.Web, which is also where the authentication service currently resides. The Web.config file is in the main app, i.e. in Silverlight4App.

In the connectionStrings section of the web.config file, I originally had this:

<add name="AuthEntities" connectionString="metadata=res://*/AuthModel.csdl|res://*/AuthModel.ssdl|res://*/AuthModel.msl;provider=... />

and I got the following error:

"Load operation failed for query 'GetUser'. Unable to load the specified metadata resource."

Then I tried various things such as:

<add name="AuthEntities" connectionString="metadata=..\..\bin\AuthModel.csdl|..\..\bin\AuthModel.ssdl|..\..\bin\AuthModel.msl;provider=... />

and got this error:

"Load operation failed for query 'GetUser'. The specified metadata path is not valid. A valid path must be either an existing directory, an existing file with extension '.csdl', '.ssdl', or '.msl', or a URI that identifies an embedded resource."

I also tried copying the metadata files to various locations. In the end, I got a little further with the following.

<add name="AuthEntities" connectionString="metadata=~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.csdl|~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.ssdl|~\..\..\..\Silverlight4App.Web\Metadata\AuthModel.msl;provider=... />

With the above connection string, I got the following error:

"Load operation failed for query 'GetUser'. The supplied connection string is not valid, because it contains insufficient mapping or metadata information.\r\nParameter name: connectionString Inner exception message: Unable to determine application context. The ASP.NET application path could not be resolved."

Well, at least it seems to have found the metadata files! Out of frustration I finally tried simply hard-coding the entire path to the metadata files:

<add name="AuthEntities" connectionString="metadata=C:\Users\...\Silverlight4App.Web\Metadata\AuthModel.csdl|C:\Users\...\Silverlight4App.Web\Metadata\AuthModel.ssdl|C:\Users\...\Silverlight4App.Web\Metadata\AuthModel.msl;provider=... />

It worked perfectly!! Unfortunately, it's a lousy solution, especially when I go to deploy the application.

It seems odd that the attempt that I tried just before the hard-coded attempt (see above) complained that there was insufficient information and yet the hard-coded attempt, which pointed to the exact same files, appears to contain sufficient information. Hmm...

Any ideas? I could surely use some help!

A: 

Look in the compiled assembly with Reflector to see if the resources are there; if they are, they should be accessible using the first method. If not then there's something wrong with your deployment; you always have the option to deploy them as loose files of course. If this doesn't help, ask for more clarification, I'll be at my desk tomorrow with the code at hand to explain further (had to deal with something like this a while ago).

Alex Paven
Reflector showed namespace-qualified names for the metadata files. When I tried adding the namespace to the filenames, eg. "res://*/Models.AuthModel.csdl", it worked. Thanks for the tip, Alex!!
MylesRip
A: 

The best way to tackle this is create a factory to produce your EF object. The factory can pass in a edmxconnection object which can be generated as such: (Excuse the VB)

Public Shared Function GetEDMXConnectionString(Of T As ObjectContext)(Optional ByVal connectionString As String = "") As EntityConnection
  Dim dbConnection As New SqlConnection(connectionString)
  Dim resourceArray As String() = {"res://*/"}
  Dim assemblyList As Assembly() = {GetType(T).Assembly}
  Dim metaData As New MetadataWorkspace(resourceArray, assemblyList)
  Dim edmxConnection As New EntityConnection(metaData, dbConnection)

  Return edmxConnection
End Function

This connection can then be passed into the Context instance via the constructor.

Slappy