I hit my head against a wall for a while today when I was trying to create a data service using my EF POCOs. I have my model & context in one assembly and my generated POCO entities in another.
When I ran the service (I had exposed all EntitySets for AllRead), I got the mysterious error:
The server encountered an error processing the request. See server logs for more details.
Even with config.UseVerboseErrors = true; in my service, the message did not change.
I finally saw the real problem first in Intellitrace (I’m using VS2010 and .NET 4.0) and then by setting the service behavior’s IncludeExceptionDetailInFaults to true.
This is what the detailed exception looks like:
The server encountered an error processing the request. The exception message is 'Value cannot be null. Parameter name: key'. See server logs for more details. The exception stack trace is:
at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at System.Data.Services.Providers.ObjectContextServiceProvider.PopulateMetadata(IDictionary`2 knownTypes, IDictionary`2 childTypes, IDictionary`2 entitySets) at System.Data.Services.Providers.BaseServiceProvider.PopulateMetadata() at System.Data.Services.DataService`1.CreateProvider() at System.Data.Services.DataService`1.EnsureProviderAndConfigForRequest() at System.Data.Services.DataService`1.HandleRequest() at System.Data.Services.DataService`1.ProcessRequestForMessage(Stream messageBody) at SyncInvokeProcessRequestForMessage(Object , Object , Object ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object inputs, Object& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet
Key in here for me are “PopulateMetadata” and argument is null.
Looks like we can’t read the metadata, i.e. the CSDL, MSL and/or SSDL files. I’ve got he connection string in web.config so that ‘s not it.
With this info in hand, I found this forum post which clarified the issue: Fail to work with POCO ModelContainer which entities are located in
I neede to force the metadata to load into the application process. I have a handy trick for this which is simpler than the one suggested in the forum.
I blogged about it in 2008: Quick Trick for forcing MetadataWorkspace ItemCollections to load.
So, I added this override to the data service:
protected override BAPOCOs CreateDataSource()
var context = new BAPOCOs();
var tracestring = context.CreateQuery<Contact>("BAPOCOs.Contacts").ToTraceString();
Note that calling ToTraceString does not cause a command to be executed on the server.
And my service was back in working condition, however…
There is one thing I’m not happy with. I originally had a test in there to see if the metadata was already loaded. If so, then no need to call ToTraceString. The metadata is supposed to remain in teh app process so after the first hit, I should be skipping the ToTraceString code. However, it was being hit every time and if I forced it to skip, then I was back to the original error.
This seems like an expensive waste of resources and if that’s the case, I’m doing it on EVERY call, I’d rather use the more complex code which explicitly loads the MDW rather than my little trick which is not a big deal if I’m only doing it once. The upside is that this is essentially an Entity SQL query and by default ESQL queries are cached and do not need to be recompiled. So perhaps it's not so bad. Either way, I'd like to get this solution to a more satisfactory state.
I have asked about this in the above mentioned forum thread. And will add to this blog post when I get more info.