简体   繁体   中英

OData in MVC3 + EF layered architecture

I'm a total newbie to WCF-related stuff, so forgive my naive question, but I am not sure where to start in pinpointing an error while learning OData basics.

I have an existing MVC3 application using a database, using the universal membership provider (added via nuget) and a small SDF database accessed via SQL Server Compact Edition Client Data Provider 4.0. I created it with the following steps:

1) create a new library project for the data layer , add EDMX from a database, then add ADO.NET DB context and entities generators templates.

2) create a new library project for generic data interfaces : a repository interface, implemented in (1), and the entities t4 template with its output, moved from (1) into this project (changing the TT inputFile parameter so that it refers to the EDMX in the other project).

3) create a new MVC application which uses Ninject to instantiate the generic repository declared in (2) with the SDF-based repository implemented in (1).

The web application works fine, and I can view and edit data. Now I should expose some of its functions via a WCF service and I was looking at OData for this. So I added a new WCF Data Service, and changed the generated code just to test it, by adding the name of my entities class (as implemented in (1)) and the name of an entity set, eg:

public class ProjectService : DataService<OrganizerEntities>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("Projects", EntitySetRights.AllRead);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }
}

Anyway when I open the SVC in the browser I get a Request Error : The server encountered an error processing the request. See server logs for more details. . If I look at the log, I see first of all a warning like:

... http://msdn.microsoft.com/it-IT/library/System.ServiceModel.EvaluationContextNotFound.aspx Configuration evaluation context not found . ...

and then an ArgumentNullException exception whose details follow. In all the samples or tutorials I've found I see the typical not-so-real-world example where the data layer is not separated from the consumer application: create a new MVC app, add an EDMX, add a WCF Data Service, change some lines of generated code, and all magically works :). So I suppose this is related to my layered architecture, especially for the missing context warning. Could anyone help in using this service in a layered scenario like this? Thanks!

... Value cannot be null. Parameter name: key 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.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.ProcessMessa ge41(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) System.ArgumentNullException: Value cannot be null. Parameter name: key 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.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.ProcessMessa ge41(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) ...

This may not be the best solution but here is how i managed to layer with EF and WCF:

  1. Create your MVC application project.

  2. Create a new Web Application project, add your entity models and your WCF services to this project. Edit the post build events to copy the relevant dlls from you bin/ along with your .svc files to your MVC project.

  3. Create your library project, add your service references. Use this library from your MVC app. Make sure you use the path to the MVC .svc file when instantiating contexts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM