2010-03-18 10 views
7

У меня есть простой службы WCF Data Services, и я хочу, чтобы выставить Service Operation следующим образом:Почему мой метод ServiceOperation отсутствует в моем прокси-коде клиента WCF Data Services?

[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

+0

Операции не видны через .svc-файл. Они появляются в файле метаданных, который вы можете увидеть с помощью этого URL: http: // localhost: 3059/TestService.svc/$ metadata – 2011-12-07 14:01:02

ответ

10

Наконец-то решила это. Чтобы вызвать операцию обслуживания в классе службы данных, вам необходимо использовать методы контекста данных службы данных 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(); 
+0

Спасибо за сообщение ответа после того, как вы его нашли! –

+0

Еще один способ, которым службы передачи данных WCF ужасно нарушены ... Спасибо за это решение. – Yuck

+1

Вот сообщение в блоге от Microsoft в Microsoft, подробно описанное выше. http://blogs.msdn.com/b/writingdata_services/archive/2011/03/28/calling-service-operations-from-the-client.aspx. В основном такая же информация, но, возможно, стоит кому-то. –

1

(этот ответ неправильно (см комментарии), но намеренно оставил здесь, чтобы остановить другие ответы спотыкаясь слепо в то же отверстие)


IIRC, она также должна быть [OperationContract]

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

(а в идеале сам сервис будет [ServiceContract])

+1

Morning Marc. Я попробовал украсить атрибут 'OperationContract', но при добавлении ссылки на службу на клиенте я получаю сообщение об ошибке:« OperationContractAttributes действительны только для методов, объявленных в типе, который имеет ServiceContractAttribute. ». – Kev

+0

Затем ... Если я добавлю атрибут '[ServiceContract]' к классу, как было предложено, я получаю другую ошибку: класс службы типа .. и определяет ServiceContract и наследует ServiceContract от типа System.Data.Services. IRequestHandler. Наследование контрактов может использоваться только между типами интерфейсов. Если класс помечен ServiceContractAttribute, он должен быть единственным типом в иерархии с ServiceContractAttribute. «В идеале я бы не получил в итоге две службы. – Kev

+0

@Kev - ОК, тогда проигнорируйте это. Я оставлю это здесь просто в случае, если кто-то другой попадет в ту же ошибку. Я запустил astoria ... –

0

У меня была аналогичная выпуск со следующим образцом

[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 не перечислить когда он просматривается через веб-браузер или есть недокументированный способ получить оба в списке.

 Смежные вопросы

  • Нет связанных вопросов^_^