Подтвердить что ты не робот

Использование параметров строки запроса, чтобы устранить совпадение соответствия UriTemplate

Я использую 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 не поддерживает несколько шаблонов, которые имеют эквивалентный путь как шаблон "люди? ssn = {ssn}", но имеют разные Строки запроса, в которых строки запроса не могут быть однозначно устранены литеральные значения. Дополнительную информацию см. В документации для UriTemplateTable. деталь.

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

В качестве альтернативы, если вы хотите сохранить формат строки запроса, будет добавлен параметр статической строки запроса в начало 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);

Ответ 3

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

Я сделал следующее:

Определите шаблон 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

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