【问题标题】:How to forward a 'saved' request stream to another Action within the same controller?如何将“已保存”的请求流转发到同一控制器中的另一个动作?
【发布时间】:2026-01-29 14:15:02
【问题描述】:

我们需要对我们的移动设备发送的大型 http 请求进行分块。这些较小的块流被合并到服务器上的一个文件中。一旦收到所有块,我们需要一种方法将保存的合并请求提交给同一控制器中的另一个方法(Action),该方法将处理这个大的 http 请求。如何才能做到这一点?我们在下面尝试的代码导致服务挂起。有没有办法在没有往返的情况下做到这一点?

//Open merged chunked file
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

//Read steam support variables
int bytesRead = 0;
byte[] buffer = new byte[1024];

//Build New Web Request. The target Action is called "Upload", this method we are in is called "UploadChunk"
HttpWebRequest webRequest;
webRequest = (HttpWebRequest)WebRequest.Create(Request.Url.ToString().Replace("Chunk", string.Empty));
webRequest.Method = "POST";        
webRequest.ContentType = "text/xml";     
webRequest.KeepAlive = true;
webRequest.Timeout = 600000;
webRequest.ReadWriteTimeout = 600000;
webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;

Stream webStream = webRequest.GetRequestStream();  //Hangs here, no errors, just hangs

我已经研究过使用 RedirectToAction 和 RedirecctToRoute,但这些方法不适合我们想要做的事情,因为我们无法编辑 Request.InputStream(因为它是只读的)来执行大型请求流。

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    你可以构建你想要的,保存在TempDataRedirectToAction,然后从'TempData'中提取它

    类似这样的:

    public ActionResult DoSomething()
    {
        var data = GetData();
        TempData["Data"] = data;
    
        RedirectToAction("Forward");
    }
    
    public ActionResult Forward()
    {
        var data = TempData["data"];
        if (data == null)
            throw new ArgumentException("data is null");
    
        // Do your magic.
    
    }    
    

    【讨论】:

    • 如果我们走这条路,那么 Forward() 动作将需要为每个上传的文件解析出各种表单字段和文件流字节(混乱)。我们希望利用该框架,使重定向看起来像来自客户端的原始帖子,并且我们得到 Request.Form 和 Request.Files 已经填充了合并的流。在引用 Request 对象的目标 Action 中有大量逻辑负载,我们真的希望重用此逻辑,而不是打开一罐试图钩住合并流数据进行处理的蠕虫。
    • 投票赞成这个“答案”的人显然没有阅读完整的问题集。
    【解决方案2】:

    找到我要找的东西here: 需要执行以下步骤:

    1) 创建文件流以从文件中读取合并的块
    2) 使用目标 URI 创建新 System.Net.HttpWebRequest
    3) 将标头从原始请求复制到 2) 中记录的新请求
    4) 将文件流中的内容复制到新请求
    5) 将新请求的内容长度设置为文件流的长度
    6) 关闭文件流和新的请求流
    7) 将标头从原始请求复制到新请求
    8) 将 Cookie 从原始请求复制到新请求


    所以基本上它与编写 ASP.NET 东西时可以使用的逻辑相同。

    【讨论】:

      最近更新 更多