【问题标题】:Is it possible to have "overloaded" uritemplates?是否有可能有“重载”的 uritemplates?
【发布时间】:2018-09-10 20:48:11
【问题描述】:
        [OperationContract]
    [WebGet(UriTemplate = "/searchresults/{searchTerm}/{searchType}", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    Message GetSearchResults(string searchTerm, string searchType);

    [OperationContract]
    [WebGet(UriTemplate = "/searchresults/{searchTerm}", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    Message GetSearchResults(string searchTerm);

这可能吗?如果没有,有人可以提出替代方案吗?

【问题讨论】:

    标签: wcf uritemplate


    【解决方案1】:

    我发现这对我来说是最好的解决方案:

        [OperationContract(Name = "SearchresultsWithSearchType")]
        [WebGet(UriTemplate = "/searchresults/{searchTerm}/{searchType=null}", 
        ResponseFormat = WebMessageFormat.Xml)]
        Message GetSearchResults(string searchTerm, string searchType);
    
    
        [OperationContract(Name = "SearchresultsWithoutSearchType")]
        [WebGet(UriTemplate = "/searchresults/{searchTerm}", 
        ResponseFormat = WebMessageFormat.Xml)]
        Message GetSearchResults(string searchTerm);
    

    这匹配:

    "http://myservice/searchresults/mysearchterm"

    "http://myservice/searchresults/mysearchterm/"

    "http://myservice/searchresults/mysearchterm/mysearchtype"

    【讨论】:

    • 这对你真的有用吗? WCF 通常不允许使用相同名称的两个操作。
    • 它确实对我有用 - OperationContract 属性的 Name 属性区分了两者。但是,底层方法仍然需要不同的签名。
    【解决方案2】:

    不,不是真的——因为字符串参数searchType 可以为NULL——所以你真的没有办法区分这两个URL 模板。如果您使用的是不可为空的类型,例如INT 或其他东西,情况会有所不同 - 然后您(和 .NET 运行时)可以将两个 URL 模板分开(基于 INT 是否存在的事实)。

    您需要做的只是在您的GetSearchResults 方法中检查searchType 是否为空或NULL,然后采取相应措施。

    [OperationContract]
    [WebGet(UriTemplate = "/searchresults/{searchTerm}/{searchType}", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare)]
    Message GetSearchResults(string searchTerm, string searchType);
    

    在你的实现中:

    public Message GetSearchResults(string searchTerm, string searchType)
    {
       if(!string.IsNullOrEmpty(searchType))
       {
          // search with searchType
       }
       else
       {
          // search without searchType
       }
       ......
    }
    

    【讨论】:

    • 谢谢 - 我的问题是:“myservice/searchresults/searchterm”或“myservice/searchresults/searchterm”即没有搜索类型部分的 URL 将不匹配上面的模板并返回 404。我需要默认searchType 参数?
    • @pones: 好的 - 嗯....我的印象是它会匹配那个模板。但似乎你确实需要这两个 URI 模板。感谢您分享您的见解!
    【解决方案3】:

    我通过使用 STREAM 从客户端传递数据来实现这一点。 您甚至可以有 2 个名称相同但方法名称不同的操作。 从前端确保将 contentType 设置为“text/javascript”或“application/octet-stream”, 如果使用 AJAX 或 jQuery,请尝试从 HTML 或数据变量中以 POST 形式发送数据

    举例

    [OperationContract]
    [WebInvoke(Method = "PUT", UriTemplate = "user/id/{id}/", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
            string UpdateUser(string id, System.IO.Stream stream);
    
    [OperationContract]
    [WebInvoke(Method = "DELETE", UriTemplate = "user/id/{id}/", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
            string DeleteUser(string id);
    

    或者用 PUT 和 DELETE 代替 GET 和 POST

    【讨论】:

      猜你喜欢
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 2014-06-19
      • 1970-01-01
      • 2014-07-23
      • 2021-08-30
      • 2017-03-14
      • 1970-01-01
      相关资源
      最近更新 更多