Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
305 views
in Technique[技术] by (71.8m points)

c# - ASP.NET Core modify/substitute request body

I want to do a substitution on HttpContext.Request.Body.

I've tried to do it inside a middleware:

public async Task Invoke(HttpContext context)
{
    if (context.Request.Path.Value.Contains("DataSourceResult"))
    {
        var originalBody = new StreamReader(context.Request.Body).ReadToEnd();
        DataSourceRequest dataSource = null;

        try
        {
            dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalBody);
        } catch
        {
            await _next.Invoke(context);
        }

        if (dataSource != null && dataSource.Take > 2000)
        {
            dataSource.Take = 2000;

            var bytesToWrite = dataSource.AsByteArray();
            await context.Request.Body.WriteAsync(bytesToWrite, 0, bytesToWrite.Length);
        }
        else
        {
            var bytesToWrite = originalBody.AsByteArray();
            await context.Request.Body.WriteAsync(bytesToWrite, 0, bytesToWrite.Length);
        }
    }

    await _next.Invoke(context);
}

The first problem is that the body can be read only once, and secondly, the stream is read-only and can't be written to.

How can I modify/substitute Request.Body? I need to change property value of request body.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Take the request body, read its content, make whatever changes are necessary if at all, then create a new stream to pass down the pipeline. Once accessed, the request stream has to be replaced.

public async Task Invoke(HttpContext context) {
    var request = context.Request;
    if (request.Path.Value.Contains("DataSourceResult")) {
        //get the request body and put it back for the downstream items to read
        var stream = request.Body;// currently holds the original stream                    
        var originalContent = new StreamReader(stream).ReadToEnd();
        var notModified = true;
        try {
            var dataSource = JsonConvert.DeserializeObject<DataSourceRequest>(originalContent);
            if (dataSource != null && dataSource.Take > 2000) {
                dataSource.Take = 2000;
                var json = JsonConvert.SerializeObject(dataSource);
                //replace request stream to downstream handlers
                var requestContent = new StringContent(json, Encoding.UTF8, "application/json");
                stream = await requestContent.ReadAsStreamAsync();//modified stream
                notModified = false;
            }
        } catch {
            //No-op or log error
        }
        if (notModified) {
            //put original data back for the downstream to read
            var requestData = Encoding.UTF8.GetBytes(originalContent);
            stream = new MemoryStream(requestData);
        }

        request.Body = stream;
    }
    await _next.Invoke(context);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...