使用查询字符串参数消除UriTemplate匹配的歧义

msp*_*nts 22 c# wcf uritemplate

我正在使用WCF 4.0来创建REST-ful Web服务.我想要做的是根据查询字符串参数调用不同的服务方法UriTemplate.

例如,我有一个API,允许用户使用其驾驶执照或社会安全号码作为密钥来检索有关某人的信息.在我的ServiceContract/ interface中,我将定义两个方法:

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

[OperationContract]
[WebGet(UriTemplate = "people?ssn={ssn}")]
string GetPersonBySSN(string ssn);
Run Code Online (Sandbox Code Playgroud)

但是,当我使用这两种方法调用我的服务时,我得到以下异常:

UriTemplateTable不支持具有与模板'people?ssn = {ssn}'等效路径的多个模板,但具有不同的查询字符串,其中查询字符串不能通过文字值消除歧义.有关更多详细信息,请参阅UriTemplateTable的文档.

有没有办法做到这一点UriTemplates?这似乎是一种常见的情况.

非常感谢!

小智 11

或者,如果要保留查询字符串格式,则可以在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);
Run Code Online (Sandbox Code Playgroud)


小智 11

我也遇到了这个问题,最终想出了一个不同的解决方案.我不想为对象的每个属性使用不同的方法.

我做了如下:

在服务协定中定义URL模板,而不指定任何查询字符串参数:

[WebGet(UriTemplate = "/People?")]
[OperationContract]
List<Person> GetPersonByParams();
Run Code Online (Sandbox Code Playgroud)

然后在实现中访问任何有效的查询字符串参数:

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);
    }
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用URL等搜索

/PersonService.svc/People 
Run Code Online (Sandbox Code Playgroud)
/PersonService.svc/People?ssn=5552
Run Code Online (Sandbox Code Playgroud)
/PersonService.svc/People?ssn=5552&driversLicense=123456
Run Code Online (Sandbox Code Playgroud)

它还使您能够混合和匹配查询字符串参数,以便使用您想要的内容并省略您不感兴趣的任何其他参数.它的优点是不会将您限制为只有一个查询参数.


小智 8

根据这篇文章,这是不可能的,你将不得不做这样的事情:

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

[OperationContract]
[WebGet(UriTemplate = "people/ssn/{ssn}")]
string GetPersonBySSN(string ssn);
Run Code Online (Sandbox Code Playgroud)