Использование параметров строки запроса для устранения неоднозначности соответствия UriTemplate - PullRequest
22 голосов
/ 04 января 2012

Я использую WCF 4.0 для создания веб-сервиса REST-ful.Я хотел бы иметь разные сервисные методы, вызываемые на основе параметров строки запроса в UriTemplate.

Например, у меня есть API, который позволяет пользователям получать информацию о человеке, использующем их драйверомлицензия или их номер социального страхования в качестве ключа.В моем интерфейсе ServiceContract / я определил бы два метода:

[OperationContract]
[WebGet(UriTemplate = "people?driversLicense={driversLicense}")]
string GetPersonByLicense(string driversLicense);

[OperationContract]
[WebGet(UriTemplate = "people?ssn={ssn}")]
string GetPersonBySSN(string ssn);

Однако, когда я вызываю свой сервис обоими методами, я получаю следующее исключение:

UriTemplateTable неподдерживает несколько шаблонов, которые имеют эквивалентный путь как шаблон 'people? ssn = {ssn}', но имеют разные строки запроса, где все строки запроса не могут быть устранены неоднозначно с помощью литеральных значений.См. Документацию для UriTemplateTable для более подробной информации.

Нет ли способа сделать это с UriTemplates?Это похоже на обычный сценарий.

Большое спасибо!

Ответы [ 3 ]

11 голосов
/ 15 августа 2012

В качестве альтернативы, если вы хотите сохранить формат строки запроса, добавление статического параметра строки запроса в начало UriTemplate будет работать.Например:

[OperationContract]
[WebGet(UriTemplate = "people?searchBy=driversLicense&driversLicense={driversLicense}")]
string GetPersonByLicense(string driversLicense);

[OperationContract]
[WebGet(UriTemplate = "people?searchBy=ssn&ssn={ssn}")]
string GetPersonBySSN(string ssn);
11 голосов
/ 06 декабря 2012

Я тоже столкнулся с этой проблемой и в итоге нашел другое решение. Я не хотел иметь разные методы для каждого свойства объекта.

То, что я сделал, было следующим:

Определите шаблон URL в контракте на обслуживание, не задавая параметры строки запроса:

[WebGet(UriTemplate = "/People?")]
[OperationContract]
List<Person> GetPersonByParams();

Затем в реализации получите доступ к любым допустимым параметрам строки запроса:

public List<Person> GetPersonByParms()
    {
        PersonParams options= null;

        if (WebOperationContext.Current != null)
        {
            options= new PersonParams();

            options.ssn= WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["ssn"];
            options.driversLicense = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["driversLicense"];
            options.YearOfBirth = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["YearOfBirth"];
        }

        return _repository.GetPersonByProperties(options);
    }

Затем вы можете искать, используя URL-адреса, такие как

/PersonService.svc/People 
/PersonService.svc/People?ssn=5552
/PersonService.svc/People?ssn=5552&driversLicense=123456

Он также позволяет вам смешивать и сопоставлять параметры строки запроса, поэтому просто используйте то, что вы хотите, и пропустите любые другие параметры, которые вас не интересуют. Преимущество состоит в том, что вы не ограничены одним параметром запроса.

8 голосов
/ 05 января 2012

Согласно Это сообщение , это невозможно, вам придется сделать что-то вроде:

[OperationContract]
[WebGet(UriTemplate = "people/driversLicense/{driversLicense}")]
string GetPersonByLicense(string driversLicense);

[OperationContract]
[WebGet(UriTemplate = "people/ssn/{ssn}")]
string GetPersonBySSN(string ssn);
...