Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确抛出和处理web服务异常_C#_.net_Web Services_Web_Exception Handling - Fatal编程技术网

C# 如何正确抛出和处理web服务异常

C# 如何正确抛出和处理web服务异常,c#,.net,web-services,web,exception-handling,C#,.net,Web Services,Web,Exception Handling,我在应用服务器中遵循MVC模式。我试图抛出一个异常,但它没有被正确抛出 以下是来自控制器的代码: [HttpPost] public IHttpActionResult PostAddSuperUser(SuperUserViewModel SU) { try { //more code blHandler.addSuperUser((SuperUser)SU.user, SU.Password); return Ok();

我在应用服务器中遵循MVC模式。我试图抛出一个异常,但它没有被正确抛出

以下是来自控制器的代码:

[HttpPost]
public IHttpActionResult PostAddSuperUser(SuperUserViewModel SU)
{
    try
    {
        //more code
        blHandler.addSuperUser((SuperUser)SU.user, SU.Password);
        return Ok();
    }
    catch (EUserAlreadyExist ex)
    {
        var resp = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
        resp.Content = new StringContent(string.Format("Already exist ", SU.user.Mail));
        resp.ReasonPhrase = "Already exist";
        throw new HttpResponseException(resp);
    }
然后客户端调用它,如下所示:

try{
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:50687/");

            HttpResponseMessage response = await client.PostAsJsonAsync<SuperUserViewModel>("/api/SuperUser/PostAddSuperUser", SUVM);

            if (response.IsSuccessStatusCode)
            {
                new SuccesPupUp("", "SuperUser " + SupUserName + " was added");
            }
            this.Close();
        }
}
catch (HttpResponseException Exc)
{
    new ErrorPopUp("", Exc.Message);
}
试试看{
HttpClient=新的HttpClient();
client.BaseAddress=新Uri(“http://localhost:50687/");
HttpResponseMessage response=wait client.PostAsJsonAsync(“/api/SuperUser/PostAddSuperUser”,SUVM);
if(响应。IsSuccessStatusCode)
{
新的成功升级(“,”超级用户“+超级用户名+”);
}
这个。关闭();
}
}
捕获(HttpResponseException Exc)
{
新错误弹出窗口(“,Exc.Message);
}
根据这个,我正确地抛出了它,但是当我运行它时,我得到了这个错误

我怎样才能修好它


编辑:我想将异常抛出客户端,以便它可以要求用户提供新的电子邮件地址

问题就在这段代码中(似乎很明显,但请注意):

发生的情况是,您正在从上述try捕获一个EUserAlreadyExist异常,然后在没有附带
try-catch
块的情况下抛出一个新异常。这意味着,仅仅因为您在catch中抛出了一个异常,它就不会自动神奇地捕获它,您就必须在catch中有一个单独的
try-catch

进一步说,对this
try-catch
的客户端调用也不会捕获抛出的异常,因为它们(catch语句)捕获的异常类型与抛出的异常类型不同

要修复它,需要捕获在本例中引发的异常,即
HttpResponseException
异常。这意味着您的代码可能如下所示:

  catch (EUserAlreadyExist ex)
    {
    try{
        var resp = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
        resp.Content = new StringContent(string.Format("Already exist ", SU.user.Mail));
        resp.ReasonPhrase = "Already exist";
        throw new HttpResponseException(resp);
       }
       catch(HttpResponseException ex2)
       {
         //do something here with the exception
       }
    }

服务器端代码不需要捕获异常并重新抛出它-这有什么意义?就让它在客户面前浮出水面吧。这就是例外的美丽和力量。问题是MVC想要返回一个视图或HTTP状态码,而不是丰富的强类型异常信息

您似乎在富客户机(客户机-服务器)环境中使用MVC模式,这毫无意义。MVC最适合瘦客户机的情况,即服务器提供视图,而客户机只是呈现视图。当您拥有富客户机时,MVVM模式更有意义。服务器可以提供视图模型(数据),客户端可以接管所有用户交互、视图等

考虑使用MVVM方法(使用WCF)而不是MVC。然后,客户机和服务器将对可以抛出的异常类型有一个共同的理解。服务器可以抛出,客户端可以捕获,简单

然后,您的客户端代码将非常简单:

try
{
    c.AddSuperUser(SUVM);
}
catch (Exception e)
{
    // etc
}

其中c是WCF客户端代理。

正如您看到的,它抛出了您没有捕获的
HttpResponseException
,只需添加第一个catch-
catch(HttpResponseException ex)
,因为您询问的是“正确处理异常”,请注意这是一个“最佳实践”用Exception后缀而不是前缀“E”命名异常。例如,
EInvalidPassword
应该命名为
InvalidPasswordException
,是的,它更长,但它的含义更明显。在
catch()
中,您必须处理
HttpResponseException
,而不是
EUserAlredyExist
,因为您不会抛出
EUserAlredyExist
异常。此问题与。如果从catch块内抛出异常,而该块外没有catch块,则该异常未经处理。@DanielPetrovaliev,很可能他的blHandler.addSuperUser()方法会抛出
EUserAlreadyExist
异常,这就是他捕获该异常的原因。这似乎不正确,为什么要抛出异常,然后立即捕获它?根据@Rodrigo的问题和代码,这个答案在技术上应该是可行的,但我同意以这种方式抛出异常没有多大意义。@笔名我想用服务器端的try catch将异常抛出客户端,那么捕获自己的异常将如何帮助我做到这一点呢?如我所见,如果我添加一个新的try-catch,我将再次捕获它,但我仍然不知道如何处理它,或者如何将它发送到客户端
try
{
    c.AddSuperUser(SUVM);
}
catch (Exception e)
{
    // etc
}