如何使用Web服务正确地抛出和处理异常

时间:2015-05-28 20:24:21

标签: c# .net web-services web exception-handling

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

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

<div class="col-md-6 clients">
    <div class="row">
       <div class="col-xs-4"><img src="img/1.jpg" alt="" class="img-responsive"></div>
      ...
    </div>

    <div class="image-separator"></div>

    <div class="row">
      <div class="col-xs-4"><img src="img/1.jpg" alt="" class="img-responsive"></div>
      ...
    </div>
</div>

然后客户端将其称为:

[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);
    }

根据这个this我正确地投掷它,但是当我运行它时我得到了这个错误enter image description here

我该如何解决?

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

2 个答案:

答案 0 :(得分:0)

问题出在这段代码中(似乎很明显,但请耐心等待):

  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);
    }

发生的事情是你从上面的尝试中捕获一个EUserAlreadyExist异常,然后在没有伴随try-catch块的情况下抛出一个新的异常。所以这意味着只是因为你在一个捕获中抛出一个异常,它不会自动地抓住它,你必须在你的捕获中有一个单独的try-catch

进一步说明,客户端对此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
       }
    }

答案 1 :(得分:0)

服务器端代码不需要捕获异常并重新抛出它 - 重点是什么?只是让它冒泡到客户端。这就是例外的美丽和力量。麻烦是MVC想要返回一个View或一个HTTP状态代码,而不是丰富的强类型异常信息。

您似乎在富客户端(客户端 - 服务器)情况下使用MVC模式,这没有任何意义。 MVC最适合瘦客户端情况,即服务器提供视图,客户端只是呈现它们。当您拥有富客户端时,MVVM模式更有意义。服务器可以提供View Model(数据),客户端可以接管所有用户交互,视图等。

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

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

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

其中c是WCF客户端代理。