关于Visual Studio 2008:为什么WCF数据服务客户端代理代码中缺少我的ServiceOperation方法?

Why is my ServiceOperation method missing from my WCF Data Services client proxy code?

我有一个简单的WCF数据服务服务,我想公开一个服务操作,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class ProductDataService : DataService<ProductRepository>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(IDataServiceConfiguration config)
    {
      config.SetEntitySetAccessRule("*",
            EntitySetRights.ReadMultiple | EntitySetRights.ReadSingle);
      config.SetServiceOperationAccessRule("*",
            ServiceOperationRights.All);
      config.UseVerboseErrors = true;
    }

// This operation isn't getting generated client side
[WebGet]
public IQueryable<Product> GetProducts()
{
    // Simple example for testing
    return (new ProductRepository()).Product;
}

为什么在客户端上添加服务引用时GetProducts方法不可见?

我正在运行Visual Studio 2008 SP1和.NET Framework 3.5 SP1。我还下载并安装了此更新:

MS KB: 976127 - An update is available that provides additional features and improvements for ADO.NET Data Services in the .NET Framework 3.5 SP1 on a computer that is running Windows 7 or Windows Server 2008 R2


最后解决了这个问题。要在数据服务类上调用服务操作,您需要使用数据服务上下文对象的CreateQueryExecute方法。例如:

1
2
3
4
5
6
7
8
9
10
11
ProductDataService ctx = new ProductDataService(
    new Uri("http://localhost:1234/ProductDataService.svc/"));

// Method 1:
DataServiceQuery<Product> q = ctx.CreateQuery<Product>("GetProducts");
List<Product> products = q.Execute().ToList();

// Method 2:
Uri uri = new Uri(String.Format("{0}GetProducts", ctx.BaseUri),
             UriKind.RelativeOrAbsolute);
List<Product> products = ctx.Execute<Product>(uri).ToList();

如果需要参数,请在具有以下签名的服务操作中说出产品类别:

1
2
[WebGet]
public IQueryable<Product> GetProducts(string category)

我们会这样做:

1
2
3
4
5
6
7
8
9
// Method 1:
DataServiceQuery<Product> q = ctx.CreateQuery<Product>("GetProducts")
                                .AddQueryOption("category","Boats") ;
List<Product> products = q.Execute().ToList();

// Method 2:
Uri uri = new Uri(String.Format("{0}GetProducts?category={1}",
                    ctx.BaseUri,"Boats"), UriKind.RelativeOrAbsolute);
List<Product> products = ctx.Execute<Product>(uri).ToList();


(此答案不正确(请参阅评论),但故意留在此处以阻止其他答案盲目地跌入同一个洞中)

IIRC,它也必须是[OperationContract]

1
2
3
4
5
6
[OperationContract, WebGet]
public IQueryable<Product> GetProducts()
{
    // Simple example for testing
    return (new ProductRepository()).Product;
}

(理想情况下,服务本身应该是[ServiceContract])


我对以下样本有类似的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
 public class TestService : DataService<MyService>
{
    // This method is called only once to initialize service-wide policies.
    public static void InitializeService(DataServiceConfiguration config)
    {

        config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

    }

    [WebGet]
    public IQueryable<string> GetStrings(int index)
    {
        string[] list = {"One","two" };
        return list.AsQueryable();

    }
}

当我浏览服务http://localhost:3059/TestService.svc时,列表没有列出具有WebGet属性的方法,但是我可以使用来访问它
http://localhost:3059/TestService.svc/GetStrings?index=1

这向我建议,WCF数据服务定义在通过网络浏览器进行浏览时未列出操作,或者存在一些未记录的方式将两者都包含在列表中。