I've created a custom MessageHandler as such:
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;
}
}
It appears that I can't directly change the QueryString, which is a bit odd as I thought that the entire point of custom message handlers in the Web API pipeline was to allow this exact sort of thing. The ability issue pre and post operations on request/response, including things like data scrubbing / injection etc.
I already know I can do what I want very easily utilizing OWIN (as I've already done it), but now I'm trying to do this without OWIN. Am I going to have to create an entirely new HttpRequestMessage in order to just change the QueryString? From the looks of it, I'll have to build a new Uri, then construct the HttpRequestMessage, then copy over each and every other piece from the original.
Is that the only way to do this? or is there a better way that I'm just not aware of?
- Please note, that other routines later in the pipeline are setup to use a token found in the header of the request, but setting the header is not possible if the request came from a submission to an iframe, which is where the process above comes into place. The token is added to the querystring, then converted to a header to prevent changes to the rest of the pipeline.
You're correct, the query string is read-only. Just use a standard redirect with the substituted query string values.
For interest sake, it is possible to modify the query string even though it is read-only but I would avoid this practice.