【问题标题】:Using query string parameters to disambiguate a UriTemplate match使用查询字符串参数消除 UriTemplate 匹配的歧义
【发布时间】:2012-01-04 00:30:07
【问题描述】:

我正在使用 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 没有办法做到这一点吗?这似乎是一种常见的情况。

非常感谢!

【问题讨论】:

  • @BaTTy.Koda 感谢您的回复。我最终完全按照该帖子的建议进行了操作,并且效果很好。我认为由于该帖子是从 2008 年开始的,因此 MSDN 文档 (msdn.microsoft.com/en-us/library/bb675245.aspx) 谈到了字符串查询的歧义性,这可能有所改进。但是唉……

标签: c# wcf uritemplate


【解决方案1】:

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

我做了如下:

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

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

【讨论】:

    【解决方案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】:

      根据This post,这是不可能的,你必须这样做:

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

      【讨论】:

        猜你喜欢
        • 2011-02-27
        • 2011-01-25
        • 2010-11-14
        • 2014-07-21
        • 1970-01-01
        • 2012-12-27
        • 1970-01-01
        • 1970-01-01
        • 2016-01-18
        相关资源
        最近更新 更多