代码之家  ›  专栏  ›  技术社区  ›  erlando

为什么我的WCF数据服务客户端代理代码中缺少ServiceOperation方法?

  •  7
  • erlando  · 技术社区  · 15 年前

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

    [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

    3 回复  |  直到 12 年前
        1
  •  10
  •   erlando    15 年前

    终于解决了这个问题。要对数据服务类调用服务操作,需要使用数据服务上下文对象的 CreateQuery Execute 方法。例如:

    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();
    

    如果需要参数,请说明具有此签名的服务操作的产品类别:

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

    我们会这样做:

    // 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();
    
        2
  •  1
  •   Marc Gravell    15 年前

    (这个答案是 不正确的 (见评论),但故意留下来阻止其他答案盲目跌跌撞撞地进入同一个洞)


    IIRC,它还需要 [OperationContract]

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

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

        3
  •  0
  •   GraphicsMuncher    12 年前

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

     [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数据服务定义不会列出通过Web浏览器浏览时的操作,或者有一些未记录的方法可以将这两种方法都包含在列表中。