我在我的应用服务器中关注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我正确地投掷它,但是当我运行它时我得到了这个错误
我该如何解决?
编辑:我想将异常抛给客户端,以便它可以要求用户提供新的电子邮件地址
答案 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客户端代理。