22

我正在使用 WCF 4.0 创建一个 REST-ful Web 服务。我想做的是根据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?这似乎是一个常见的场景。

非常感谢!

4

3 回答 3

12

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

我所做的如下:

在服务合同中定义 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

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

于 2012-12-06T14:38:25.770 回答
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);
于 2012-08-14T20:17:00.660 回答
8

根据这篇文章,这是不可能的,您必须执行以下操作:

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

[OperationContract]
[WebGet(UriTemplate = "people/ssn/{ssn}")]
string GetPersonBySSN(string ssn);
于 2012-01-05T15:11:15.930 回答