为实体框架使用WCF数据服务操作提供程序

时间:2013-05-21 15:16:54

标签: wcf entity-framework-5 wcf-data-services odata

我在Entity Framework 5 DbContext上有一个DataService类:

public class MyDataService : DataService<MyDbContext>, IServiceProvider
{

    [WebGet]
    public IQueryable<Product> GetProducts1(int category)
    {
        return from p in this.CurrentDataSource.Products
               where p.Category == category
               select p;
    }
}

现在我想将我的DbContext中的方法公开给DataService并使用这个示例代码:http://efactionprovider.codeplex.com/

public class MyDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }

    [NonBindableAction]
    public IQueryable<Product> GetProducts2(int category)
    {
        return from p in this.CurrentDataSource.Products
               where p.Category == category
               select p;
    }

}

访问http://localhost:12345/MyDataService.svc/$metadata show that both methods are known, but the first one hat a m:HttpMethod =“GET”`attribut

<EntityContainer Name="MyDbContext" m:IsDefaultEntityContainer="true">
    ...
    <FunctionImport Name="GetProducts1" ReturnType="Collection(MyNameSpace.Product)" EntitySet="Products" m:HttpMethod="GET">
        <Parameter Name="category" Type="Edm.Int32" Nullable="false"/>
    </FunctionImport>
    <FunctionImport Name="GetProducts1" ReturnType="Collection(MyNameSpace.Product)" EntitySet="Products">
        <Parameter Name="category" Type="Edm.Int32" Nullable="false"/>
    </FunctionImport>
    ...

我可以通过访问url

来执行GetProducts1
http://localhost:12345/MyDataService.svc/GetProducts1?category=1

这对GetProducts2不起作用(因为GET不允许) 但我设法通过使用fiddler执行GetProducts:

POST: http://localhost:12345/MyDataService.svc/GetProducts1
Request Headers:
    User-Agent: Fiddler
    Host: localhost:12345
    Content-Length: 12
    Content-Type: application/json

Request Body:
    {category:1}

好的,现在这是我的问题:我使用服务参考的Windows应用程序使用此服务。由于DataServiceContext派生类中的代码生成不包括我自己需要调用它们的操作。

对于第一个(GetProducts1),我可以这样做:

    public IEnumerable<Product> GetProducts1(int category)
    {
        var proxy = new MyDataServiceContext(
            "http://localhost:12345/MyDataService.svc");
        var queryString = String.Format("{0}/GetProducts1?category={1}",
            proxy.BaseUri, category);
        var uri = new Uri(queryString, UriKind.RelativeOrAbsolute);
        return proxy.Execute<Product>(uri);
    }

但是我正在与第二个挣扎。我试过了:

    public IEnumerable<Product> GetProducts2(int category)
    {
        var proxy = new MyDataServiceContext(
            "http://localhost:12345/MyDataService.svc");
        var queryString = String.Format("{0}/GetProducts2",
            proxy.BaseUri);
        var uri = new Uri(queryString, UriKind.RelativeOrAbsolute);
        return proxy.Execute<Product>(uri, "POST", false, 
            new UriOperationParameter("category", category));
    }

但我得到DataServiceClientException: Content-Type-Header value missing.(状态代码400)

有没有办法使用Execute方法调用此方法?我希望继续使用DataServiceContext而不是自己制作任何原始请求。

提前致谢

顺便说一句。

我正在使用visual studion 2010以及来自nuget的Microsoft.Data.ServicesMicrosoft.Data.Services.Client个软件包,而不是默认的System.Data.Services dll,因为我认为我需要设置config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;来执行首先是行动。

1 个答案:

答案 0 :(得分:1)

尝试使用BodyOperationParameter而不是UriOperationParameter。操作参数包含在请求体中而不是Uri中。