c# - significado - Usar parámetros de cadena de consulta para desambiguar una coincidencia de UriTemplate
que es la desambiguación en biologia (3)
Estoy usando WCF 4.0 para crear un servicio web REST-ful. Lo que me gustaría hacer es tener diferentes métodos de servicio llamados en base a los parámetros de cadena de consulta en el UriTemplate
.
Por ejemplo, tengo una API que permite a los usuarios recuperar información sobre una persona que usa su licencia de conducir o su número de seguro social como clave. En mi ServiceContract
/ interfaz definiría dos métodos:
[OperationContract]
[WebGet(UriTemplate = "people?driversLicense={driversLicense}")]
string GetPersonByLicense(string driversLicense);
[OperationContract]
[WebGet(UriTemplate = "people?ssn={ssn}")]
string GetPersonBySSN(string ssn);
Sin embargo, cuando llamo a mi servicio con ambos métodos obtengo la siguiente excepción:
UriTemplateTable no es compatible con varias plantillas que tengan una ruta equivalente como plantilla ''people? Ssn = {ssn}'', pero tienen diferentes cadenas de consulta, donde las cadenas de consulta no pueden ser desambiguadas a través de valores literales. Consulte la documentación de UriTemplateTable para obtener más detalles.
¿No hay alguna forma de hacer esto con UriTemplates
? Parece un escenario común.
¡Muchas gracias!
Alternativamente, si desea mantener el formato de cadena de consulta, sería útil agregar un parámetro de cadena de consulta estática al comienzo de UriTemplate. Por ejemplo:
[OperationContract]
[WebGet(UriTemplate = "people?searchBy=driversLicense&driversLicense={driversLicense}")]
string GetPersonByLicense(string driversLicense);
[OperationContract]
[WebGet(UriTemplate = "people?searchBy=ssn&ssn={ssn}")]
string GetPersonBySSN(string ssn);
De acuerdo con esta publicación , no es posible, tendría que hacer algo como:
[OperationContract]
[WebGet(UriTemplate = "people/driversLicense/{driversLicense}")]
string GetPersonByLicense(string driversLicense);
[OperationContract]
[WebGet(UriTemplate = "people/ssn/{ssn}")]
string GetPersonBySSN(string ssn);
También me encontré con este problema y, finalmente, se me ocurrió una solución diferente. No quería tener un método diferente para cada propiedad de un objeto.
Lo que hice fue lo siguiente:
Defina la plantilla de URL en el contrato de servicio sin especificar ningún parámetro de cadena de consulta:
[WebGet(UriTemplate = "/People?")]
[OperationContract]
List<Person> GetPersonByParams();
Luego, en la implementación, acceda a cualquier parámetro de cadena de consulta válido:
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);
}
Luego puede buscar usando URLs como
/PersonService.svc/People
/PersonService.svc/People?ssn=5552
/PersonService.svc/People?ssn=5552&driversLicense=123456
También le permite mezclar y combinar los parámetros de cadena de consulta, de modo que simplemente use lo que desee y omita cualquier otro parámetro que no le interese. Tiene la ventaja de no restringirlo a un solo parámetro de consulta.