ASP NET Core modify/substitute a request body

て烟熏妆下的殇ゞ 提交于 2019-12-18 05:47:14

问题


I need to do the substitution of HttpContext.Request.Body.

I've tried to do it inside 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);
    }

First problem is that the body can be read only once, and second one is that the stream is read only and can't be written. How can I modify/substitute request.body(I need to change property value of request body)?


回答1:


Take the request body, read it's content, make what ever changes are necessary if at all, then create a new stream to pass down the pipeline. Once accessed, the request stream has to be replace.

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);
}


来源:https://stackoverflow.com/questions/44498802/asp-net-core-modify-substitute-a-request-body

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!