Использование параметров строки запроса, чтобы устранить совпадение соответствия 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
? Это похоже на общий сценарий.
Большое спасибо!
Ответы
Ответ 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
Он также позволяет смешивать и сопоставлять параметры строки запроса, поэтому просто используйте то, что вы хотите, и опустите любые другие параметры, которые вам не интересны. Это имеет то преимущество, что не ограничивает вас одним параметром запроса.