Search code examples
asp.net-web-apihttpmodule

Modify Request.Content in WebApi DelegatingHandler


I need to modify requested content to replace some characters (because of some unicode problems). Previously (in ASP.NET MVC), I did this with HttpModules; but in WebApi, it seems that I should DelegatingHandler but it is totally different.

How can I modify request.Content inside the SendAsync method? I need something like this:

protected async override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var s = await request.Content.ReadAsStringAsync();
    // do some modification on "s"
    s= s.replace("x","y");

    request.Content = new StringContent(s);

    var response = await base.SendAsync(request, cancellationToken);
    
    return response;
}

In the code above, I think I should check the request's content type and then decide what to do. If yes, which checks should I do?


Solution

  • I did something like this in SendAsync. Although it is not a comprehensive solution, it works:

    //first : correct the URI (querysting data) first
    request.RequestUri = new Uri(Correcr(request.RequestUri.ToString()));
    
    var contentType = request.Content.Headers.ContentType;
    
    if (contentType != null)
    {
        if (contentType.MediaType == "application/x-www-form-urlencoded")//post,put,... & other non-json requests
        {
            var formData = await request.Content.ReadAsFormDataAsync();
            request.Content = new FormUrlEncodedContent(Correct(formData));
        }
        else if (contentType.MediaType == "multipart/form-data")//file upload , so ignre it
        {
            var formData = await request.Content.ReadAsFormDataAsync();
            request.Content = new FormUrlEncodedContent(Correct(formData));
        }
        else if (contentType.MediaType == "application/json")//json request
        {
            var oldHeaders = request.Content.Headers;
            var formData = await request.Content.ReadAsStringAsync();
            request.Content = new StringContent(Correct(formData));
            ReplaceHeaders(request.Content.Headers, oldHeaders);
        }
        else
            throw new Exception("Implement It!");
    }
    
    return await base.SendAsync(request, cancellationToken);
    

    and this helper function:

    private void ReplaceHeaders(HttpContentHeaders currentHeaders, HttpContentHeaders oldHeaders)
    {
        currentHeaders.Clear();
        foreach (var item in oldHeaders)
            currentHeaders.Add(item.Key, item.Value);
    }