Web 客户端使用下载文件从服务器抓取文件 - 处理异常

发布于 2024-08-24 22:50:30 字数 1773 浏览 5 评论 0原文

我有一个 Web 服务,在其中操作 POST 和 GET 方法,以促进客户端/服务器样式体系结构中某些文件的上传/下载功能。基本上,用户可以单击按钮下载特定文件,在应用程序中进行一些更改,然后单击上传按钮将其发回。

我遇到的问题是下载。假设用户需要 3 个文件 1.txt、2.txt 和 3.txt。除了 2.txt 在服务器上不存在之外。

所以我有类似的代码(在服务器端):

public class HttpHandler : IHttpHandler
{

    public void ProcessRequest
    {
       if (context.Request.HttpMethod == "GET")
       {
          GoGetIt(context)
       }
    }

private static void GoGetIt(HttpContext context)
{
     var fileInfoOfWhereTheFileShouldBe = new FileInfo(......);

     if (!fileInfoOfWhereTheFileShouldBe.RefreshExists())
     {
          //Remove this line below
          //throw new Exception("Oh dear the file doesn't exist");

          //Replace with a force return of whichever code I chose e.g. 200
          ??...
     }

    ...

所以我遇到的问题是,当我运行应用程序时,我在客户端使用 WebClient 来使用 DownloadFile 方法,然后使用上面的代码,我得到:

WebException 是未处理:远程服务器返回错误:(500) 内部服务器错误。

(调试时)如果我连接到浏览器并使用 http://localhost:xxx/1.txt 我可以单步执行服务器端代码并​​按预期抛出异常。所以我想我想知道如何正确处理客户端的内部服务器错误,以便我可以返回一些有意义的内容,例如“文件不存在”。一种想法是在 WebClient.DownloadFile(address, filename) 方法周围使用 try catch,但我不确定这是唯一会发生的错误,即文件不存在。

编辑:遵循使用 HttpResponse 的解决方案

因此,如果我要使用 HttpResponse,我可以获得一些如何开始的建议吗?

我从客户端删除异常抛出,并用自定义 HttpResponse 替换?所以基本上我想我会选择一个代码来使用,比如 200,并在上面的 if 语句中强制返回代码 200。见评论。

然后在客户端只需使用 If (Response.StatusCode == 200) 并做我想做的任何事情(通知用户文件不存在)

我的路线正确吗?

编辑2:

我一直在尝试在我的文件复制方法周围使用try catch,然后在catch中设置状态代码或状态描述,但这在设置状态描述时会引发异常..像这样:

context.Response.StatusDescription = ex.ToString();
context.Response.Status = ex.ToString();

ArgumentOutOfRangeException - 指定的参数超出了有效值的范围。

I have a web service in which I am manipulating POST and GET methods to facilitate upload / download functionality for some files in a client/server style architecture. Basically the user is able to click a button to download a specific file, make some changes in the app, then click upload button to send it back.

Problem I am having is with the download. Say the user expects 3 files 1.txt, 2.txt and 3.txt. Except 2.txt does not exist on the server.

So I have code like (on server side):

public class HttpHandler : IHttpHandler
{

    public void ProcessRequest
    {
       if (context.Request.HttpMethod == "GET")
       {
          GoGetIt(context)
       }
    }

private static void GoGetIt(HttpContext context)
{
     var fileInfoOfWhereTheFileShouldBe = new FileInfo(......);

     if (!fileInfoOfWhereTheFileShouldBe.RefreshExists())
     {
          //Remove this line below
          //throw new Exception("Oh dear the file doesn't exist");

          //Replace with a force return of whichever code I chose e.g. 200
          ??...
     }

    ...

So the problem I have is that when I run the application, and I use a WebClient on client side to use DownloadFile method which then uses the code I have above, I get:

WebException was unhandled: The remote server returned an error: (500) Internal Server Error.

(While debugging) If I attach to the browser and use http://localhost:xxx/1.txt I can step through server side code and throw the exception as intended. So I guess I'm wondering how I can handle the internal server error on the client side properly so I can return something meaningful like "File doesn't exist". One thought was to use a try catch around the WebClient.DownloadFile(address, filename) method but i'm not sure thats the only error that will occur i.e. the file doesn't exist.

edit: following the solution using HttpResponse

So if I were to use HttpResponse, could I get some suggestions as how to start?

I remove the exception throw from the client side, and replace with custom HttpResponse? So basically I guess I would chose a code to use, say 200, and force return code 200 in that if statement above. See comment.

Then on client side just use If (Response.StatusCode == 200) and do whatever I want to do (inform user file doesn't exist )

I'm along the right lines?

edit 2:

I've been trying using a try catch around my file copy methods, then in the catch, setting the status code or status description but this throws exceptions when setting the status description.. like this:

context.Response.StatusDescription = ex.ToString();
context.Response.Status = ex.ToString();

ArgumentOutOfRangeException - specified argument was out of the range of valid values.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伪装你 2024-08-31 22:50:30

如果您正在编写 IHttpHandler 接口,则不应在该代码上引发异常。绝不!

请改用 Response.StatusCodeResponse.StatusDescription 返回有意义的信息给客户端。

让抛出异常仅针对系统,因为这样,它将真正成为您的代码的异常。

编辑添加

答复您的编辑,我的做法是,如果在服务器端找不到文件,则会返回 404 状态代码。并让客户处理这个问题。

但是,正如您所指出的,您正在处理 Web 服务,因此,我只需在标头中添加一些额外的响应,以便更好地指定客户端应用程序的服务器端实际发生的情况。

编辑添加

Response.Status 是整数。这就是您收到 ArgumentOutOfRangeException 的原因。

确保状态是有效的 HTTP 返回代码之一。

If you're programming the IHttpHandler interface you shouldn't throw exceptions on that code. Never!

Instead use the Response.StatusCode and Response.StatusDescription to return meaningful information to the client.

Let the throwing exception only to the system because then, it will REALLY be an exception to YOUR code.

Edited to add

Answering to your edit, the way I'd do it would be to in case of a file not found on the server side would return a 404 Status Code. And let the client handle this.

However, as you have put you're dealing with an web service, so, I'd simply add some additional response in the headers in order to better specify what really is going on the server side to your client application.

Edited to Add

Response.Status is and integer. That's why you're getting the ArgumentOutOfRangeException.

Make sure that Status is one of the valid HTTP return codes.

最后的乘客 2024-08-31 22:50:30

不要抛出异常,而是将异常记录在文本文件或事件日志中,以便您可以准确地看到错误发生时发生的情况。

以下是事件日志记录的示例代码 http://support.microsoft.com/kb/307024
用于保存在文本文件中

    public void WriteExceptionToDisk(Exception exceptionLog)
    {

        string loggingname = @"c:\Exception-" + DateTime.Today.Month.ToString()
                             + "-" + DateTime.Today.Day.ToString() + "-" +
                             DateTime.Today.Year.ToString() + ".txt";
        // Put the exception some where in the server but
        // make sure Read/Write permission is allowed.
        StringBuilder message = new StringBuilder();
        if (exceptionLog != null)
        {
            message.Append("Exception Date and Time ");
            message.AppendLine(); 
            message.Append("   ");
            message.Append(DateTime.Today.ToLongDateString() + " at ");
            message.Append(DateTime.Now.ToLongTimeString());
            message.AppendLine();
            message.Append("Exception Message ");
            message.AppendLine(); message.Append("   ");
            message.Append(exceptionLog.Message);
            message.AppendLine();
            message.AppendLine("Exception Detail ");
            message.AppendLine();
            message.Append(exceptionLog.StackTrace);
            message.AppendLine();
        }
        else if (message == null || exceptionLog == null)
        {
            message.Append("Exception is not provided or is set as null.Please pass the exception.");
        }

        if (File.Exists(loggingname))// If logging name exists, then append the exception message
        {

            File.AppendAllText(loggingname, message.ToString());
        }
        else
        {
            // Then create the file name
            using (StreamWriter streamwriter = File.CreateText(loggingname))
            {
                streamwriter.AutoFlush = true;
                streamwriter.Write(message.ToString());
                streamwriter.Close();
            }                 
        }
    }

Instead of throwing the exception, Log the exception in a text file or event log so that you can see exactly what happened when the error occur.

Here is sample code for event logging http://support.microsoft.com/kb/307024.
For saving in the text file

    public void WriteExceptionToDisk(Exception exceptionLog)
    {

        string loggingname = @"c:\Exception-" + DateTime.Today.Month.ToString()
                             + "-" + DateTime.Today.Day.ToString() + "-" +
                             DateTime.Today.Year.ToString() + ".txt";
        // Put the exception some where in the server but
        // make sure Read/Write permission is allowed.
        StringBuilder message = new StringBuilder();
        if (exceptionLog != null)
        {
            message.Append("Exception Date and Time ");
            message.AppendLine(); 
            message.Append("   ");
            message.Append(DateTime.Today.ToLongDateString() + " at ");
            message.Append(DateTime.Now.ToLongTimeString());
            message.AppendLine();
            message.Append("Exception Message ");
            message.AppendLine(); message.Append("   ");
            message.Append(exceptionLog.Message);
            message.AppendLine();
            message.AppendLine("Exception Detail ");
            message.AppendLine();
            message.Append(exceptionLog.StackTrace);
            message.AppendLine();
        }
        else if (message == null || exceptionLog == null)
        {
            message.Append("Exception is not provided or is set as null.Please pass the exception.");
        }

        if (File.Exists(loggingname))// If logging name exists, then append the exception message
        {

            File.AppendAllText(loggingname, message.ToString());
        }
        else
        {
            // Then create the file name
            using (StreamWriter streamwriter = File.CreateText(loggingname))
            {
                streamwriter.AutoFlush = true;
                streamwriter.Write(message.ToString());
                streamwriter.Close();
            }                 
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文