2

我有一个 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我可以单步执行服务器端代码并​​按预期抛出异常。所以我想我想知道如何正确处理客户端的内部服务器错误,这样我就可以返回一些有意义的东西,比如“文件不存在”。一种想法是围绕该方法使用try catch,WebClient.DownloadFile(address, filename)但我不确定这是唯一会发生的错误,即文件不存在。

编辑:使用 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 - 指定的参数超出了有效值的范围。

4

2 回答 2

4

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

而是使用Response.StatusCodeandResponse.StatusDescription有意义的信息返回给客户端。

只让系统抛出异常,因为那样的话,它真的会成为的代码的异常。

编辑添加

回答您的编辑,如果在服务器端找不到文件,我将返回404状态码。让客户处理这个。

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

编辑添加

Response.Status是和整数。这就是为什么你得到ArgumentOutOfRangeException.

确保 Status 是有效的HTTP 返回码之一。

于 2010-03-15T03:30:26.270 回答
0

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

这是事件记录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();
            }                 
        }
    }
于 2010-03-15T04:04:49.540 回答