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

发布于 2024-08-25 13:15:13 字数 1175 浏览 7 评论 0原文

我有一个简单的 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 知识库:976127 - 已发布更新,为 ADO.NET 数据服务提供附加功能和改进在运行 Windows 7 或 Windows Server 2008 R2 的计算机上的 .NET Framework 3.5 SP1 中

I have a simple WCF Data Services service and I want to expose a Service Operation as follows:

[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;
}

Why isn't the GetProducts method visible when I add the service reference on the client?

I'm running Visual Studio 2008 SP1 and .NET Framework 3.5 SP1. I also downloaded and installed this update:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅黛梨妆こ 2024-09-01 13:15:13

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

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

Finally solved this. To call a service operation on a data service class you need to use data service context object's CreateQuery or Execute methods. For example:

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

If parameters were required, say a product category on a service operation that had this signature:

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

We would do:

// 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();
情仇皆在手 2024-09-01 13:15:13

(这个答案是不正确(见评论),但故意留在这里是为了阻止其他答案盲目地陷入同一个洞)


IIRC,它也需要是一个[OperationContract]

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

(理想情况下,服务本身就是一个[ServiceContract]

(this answer is incorrect (see comments), but is deliberately left here to stop other answers stumbling blindly into the same hole)


IIRC, it also needs to be an [OperationContract]

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

(and ideally the service itself would be a [ServiceContract])

噩梦成真你也成魔 2024-09-01 13:15:13

我在以下示例中遇到了类似的问题

 [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 浏览器浏览或存在时不会列出操作一些未记录的方法可以将两者都添加到列表中。

I had a similar issue with following sample

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

    }
}

When I browsed the service http://localhost:3059/TestService.svc, the list didn't list the method with the WebGet attribute, but I am able to access it using
http://localhost:3059/TestService.svc/GetStrings?index=1

This suggests to me that the WCF data service definition doesn’t list the operations when it's browsed through a web browser or there is some undocumented way to get both in the list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文