【问题标题】:Cannot catch HttpWebRequest exception when streaming file to MVC controller将文件流式传输到 MVC 控制器时无法捕获 HttpWebRequest 异常
【发布时间】:2018-05-09 13:49:53
【问题描述】:

我有一个要向其发布文件流的 MVC 控制器操作:-

public ActionResult Upload()
{
    try
    {
        HttpPostedFileBase files = Request.Files[0];
        Stream fileStream = files.InputStream;

        String url = ConfigurationManager.AppSettings[ConfigurationParams.ServiceGatewayURI];

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);

        request.Method = "POST";
        request.AllowWriteStreamBuffering = false; 
        request.Timeout = 86400000; 
        request.ContentType = "application/json";
        request.ContentLength = fileStream.Length;
        Stream outputStream = request.GetRequestStream(); 
        int BYTELENGTH = 1024;
        byte[] chunk = new byte[BYTELENGTH];                

        while (fileStream.Position < fileStream.Length)
        {
            int len = fileStream.Read(chunk, 0, BYTELENGTH); 
            outputStream.Write(chunk, 0, len);
        }

        fileStream.Close();
        fileStream.Dispose();
        outputStream.Close();
        outputStream.Dispose();

        return Json("");
    }
    catch (Exception ex)
    {
        return Json(new { error = String.Format("Exception when streaming to back end, {0}"),ex.Message });
    }
}   

然后根据 url 变量中的地址将 inputStream 发布到 API 控制器方法。然后通过对象上下文的另一种方法将流保存到磁盘。

API 控制器方法:-

public String Post(string documentName)
{
    return context.SaveFile(documentName, Request.Content.ReadAsStreamAsync().Result);
}


public string SaveFile(documentName, Stream inputStream)
{   
        // Exception happens here!
}

我面临的挑战是,当 SaveFile 方法中发生异常时,它不会返回到 Upload 控制器调用。上传控制器很高兴地没有意识到保存文件时出现了问题。

在使用 Fiddler 进行调试时,我可以看到两个单独的流,包括来自 SaveFile 方法的 HTTP 500 错误。

我的问题是如何从 SaveFile 方法向 Upload 控制器抛出异常?当引发异常时,我尝试在后端关闭 inputStream,但没有为 Upload 调用返回 500。

谢谢。

【问题讨论】:

  • “然后将 inputStream 发布到 API 控制器方法”...那你是怎么做到的?您如何处理由此产生的异常或 HTTP 错误代码?这似乎是关键,但您已经将代码排除在您的问题之外。如果 API 正确返回 500 错误,那么一切都取决于您在 Upload() 方法中如何处理它。我们可以看到您写信给outputStream,但我认为这不会真正触发 HTTP 请求启动,或者是吗?
  • 感谢阿迪森的评论。使用 Fiddler 进行调试,只要点击第一个花括号,我就可以看到从浏览器到 Upload 控制器方法的 HTTP 连接打开。单步执行代码并到达 Stream outputStream = request.GetRequestStream(); POST 到 API 控制器的连接打开。上传控制器连接以 200 结束,API 连接以 500 结束。尽管 try 和 catch 会处理任何异常,因为 outputStream 行在其中。
  • 没问题...你能回答我的问题吗?
  • 当然,见上文。
  • 我没有使用这个特定的库来发出 HTTP 请求,但我认为你可能需要使用 GetResponse 监听响应:msdn.microsoft.com/en-us/library/… - 根据文档,如果发生错误

标签: asp.net-mvc http-streaming


【解决方案1】:

谢谢,成功了。如果不调用 GetResponse,您似乎无法处理异常。我一添加该行,异常就被主要的 try-catch 捕获了。

我必须阅读 ResponseStream 才能获得完整的详细信息,但目前这个解决方案已经足够好用了。

try
{
    HttpWebResponse theResponse = (HttpWebResponse)request.GetResponse();
    theResponse.Close();
}

catch (WebException wex)
{
    return Json(new { error = wex.Message});
}

【讨论】:

    猜你喜欢
    • 2015-06-08
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 2018-04-28
    • 2018-11-11
    相关资源
    最近更新 更多