【问题标题】:Web API 2.2, Is there an easy way to update the HttpRequestMessage's QueryString in a DelegatingHandler?Web API 2.2,是否有一种简单的方法可以在 DelegatingHandler 中更新 HttpRequestMessage 的 QueryString?
【发布时间】:2015-06-15 15:02:48
【问题描述】:

我已经创建了一个这样的自定义 MessageHandler:

public class WebAPICustomMessageHandler : DelegatingHandler {

  protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
  //Parse QueryString
    NameValueCollection queryString = HttpUtility.ParseQueryString(request.RequestUri.Query);

    if (queryString != null) {
    //Find my token
      String token = queryString.Get("qsVariable");

      if (!String.IsNullOrWhiteSpace(token)) {
      //Remove token so it doesn't impact future handlers / controllers / etc.
        queryString.Remove("qsVariable");
        request.RequestUri.Query = queryString.ToString(); //How can we modify the querystring? apparently it's readonly?

      //Append token as custom header to the request
        request.Headers.Add("token", new String[] { token });
      }
    }

    HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

    return response;
  }

}

看来我无法直接更改 QueryString,这有点奇怪,因为我认为 Web API 管道中自定义消息处理程序的全部目的是允许这种确切的事情。能够根据请求/响应发出前后操作,包括数据清理/注入等。

我已经知道我可以使用 OWIN 轻松地做我想做的事(正如我已经做过的那样),但现在我试图在没有 OWIN 的情况下做到这一点。我是否必须创建一个全新的 HttpRequestMessage 才能更改 QueryString?从外观上看,我必须构建一个新的 Uri,然后构建 HttpRequestMessage,然后从原始的每个部分复制。

这是唯一的方法吗?还是有更好的方法我只是不知道?

  • 请注意,稍后管道中的其他例程已设置为使用在请求标头中找到的令牌,但如果请求来自提交到 iframe,则无法设置标头,这是进程所在的位置以上就到位了。令牌被添加到查询字符串中,然后转换为标头以防止对管道的其余部分进行更改。

【问题讨论】:

    标签: c# query-string asp.net-web-api2


    【解决方案1】:

    你是对的,查询字符串是只读的。只需使用带有替换查询字符串值的标准重定向。

    public class WebAPICustomMessageHandler : DelegatingHandler {
    
      protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
        var token = query["qsVariable"];
    
        // just 'short-circuit' if our token was not found...
        if (token == null) 
          return await base.SendAsync(request, cancellationToken);
    
        token = "newValue"; // modify your value here...
        query["token"] = token;
    
        // redirect with new query string...
        var response = request.CreateResponse(HttpStatusCode.Redirect);
        var uri = request.RequestUri;
        var ub = new UriBuilder(uri.Scheme,
          uri.Host,
          uri.Port,
          uri.AbsolutePath);
        ub.Query = query.ToString();
        response.Headers.Location = ub.Uri;
        return response;
      }
    }
    

    出于兴趣,modify the query string 是可能的,即使它是只读的,但我会避免这种做法。

    【讨论】:

    • 我想你可能误解了我想要做的事情。当通过 iFrame(而不是 AJAX 调用)发出请求时,您不能附加自定义标头信息,这通常是处理此令牌的方式。我想在查询字符串上获取任何带有令牌的请求并将其移动到标头中,然后再将其交给管道的其余部分,但如前所述,Web API 不会让我实际更改查询字符串。通过重定向将修改后的响应发送回 iFrame 并不能真正帮助我。令牌需要从查询字符串中删除,因此它不会影响我们的 OData 设置。
    猜你喜欢
    • 2016-05-31
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    • 2012-07-08
    • 1970-01-01
    • 2020-03-18
    • 2012-12-03
    相关资源
    最近更新 更多