visual-studio-2008wcf-data-servicesastoria

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


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


Solution

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