异常处理时捕获块中的 System.Web.Http.HttpResponseException

Posted

技术标签:

【中文标题】异常处理时捕获块中的 System.Web.Http.HttpResponseException【英文标题】:System.Web.Http.HttpResponseException in catch block while exception handling 【发布时间】:2019-05-03 17:03:02 【问题描述】:

我故意违反数据库中的唯一约束,并尝试处理异常。

这是我的形式:

HttpResponseMessage response = KorisniciService.PostResponse(k);
                if (response.IsSuccessStatusCode)
                
                    MessageBox.Show(Messages.add_usr_succ);
                    DialogResult = DialogResult.OK;
                    Close();
                
                else
                
                    string message = response.ReasonPhrase;
                    if (string.IsNullOrEmpty(Messages.ResourceManager.GetString(response.ReasonPhrase)))
                        message = Messages.ResourceManager.GetString(response.ReasonPhrase);


                    MessageBox.Show("Error code: " + response.StatusCode + " Message: " + message);
                

我的控制器:

public IHttpActionResult PostKorisnici(Korisnici obj)
        
            if (!ModelState.IsValid)
                return BadRequest();
            try
            
                obj.KorisnikId = Convert.ToInt32(dm.esp_Korisnici_Insert(obj.Ime, obj.Prezime, obj.Email, obj.Telefon, obj.KorisnickoIme, obj.LozinkaSalt, obj.LozinkaHash, obj.Status, obj.Adresa, obj.GradId).FirstOrDefault());
            
            catch (EntityException ex)
            
                throw CreateHttpResponseException(Util.ExceptionHandler.HandleException(ex), HttpStatusCode.Conflict);
            


            foreach (var item in obj.Uloge)
            
                    dm.esp_KorisniciUloge_Insert(obj.KorisnikId, item.UlogaId);
            
            return CreatedAtRoute("DefaultApi", new  id = obj.KorisnikId , obj);
        

HttpResponseException 制作函数:

private HttpResponseException CreateHttpResponseException(string reason, HttpStatusCode code)
        


            HttpResponseMessage msg = new HttpResponseMessage()
            
                StatusCode = code,
                ReasonPhrase = reason,
                Content = new StringContent(reason)
            ;
            return new HttpResponseException(Request.CreateResponse(msg));
        

异常处理类:

public class ExceptionHandler
    
        public static string HandleException(EntityException error)
        

            SqlException ex = error.InnerException as SqlException;

                switch (ex.Number)
                
                    case 2627:
                    
                        return GetConstraintExceptionMessage(ex);
                    
                    default:
                        return error.Message + "(" + error +")";
                
        
        /*Message "Violation of UNIQUE KEY constraint 'CS_KorisnickoIme'. Cannot insert duplicate key in object 'dbo.Korisnici'. The duplicate key value is (farish).\r\nThe statement has been terminated."    string*/

        private static string GetConstraintExceptionMessage(SqlException error)
        
            string newMessage = error.Message;
            int startIndex = newMessage.IndexOf("'");
            int endIndex = newMessage.IndexOf("'", startIndex + 1);

            if (startIndex>0 && endIndex>0)
            
                string constraintName = newMessage.Substring(startIndex + 1, endIndex - startIndex - 1);

                if (constraintName == "CS_KorisnickoIme")
                    newMessage = "username_con";
                else if (constraintName == "CS_Email")
                    newMessage = "email_con";


            
             return newMessage;
        

因此,当我产生错误时,我在 post 方法的第一个 catch 块中收到 System.Web.Http.HttpResponseException 而不是弹出窗口(在教程视频中显示良好) 没有任何东西传回我的表单。

【问题讨论】:

【参考方案1】:

我认为因为异常被抛出而不是在 try/catch 块中,或者接收 CreateHttpResponseException 的 catch 块中,正在吸收它而不提供响应对象。

编辑 您可以发布 KorisniciService.PostResponse 的代码吗?

没有任何东西传回我的表单

最终的结果是什么?从您发布的表单代码中,它应该弹出带有成功消息的消息框,或者弹出带有失败消息的消息框。实际发生了什么?

第二次编辑

根据更多信息,在您的表单代码中使用它...

try

    HttpResponseMessage response = KorisniciService.PostResponse(k);

    if (response.IsSuccessStatusCode)
    
        MessageBox.Show(Messages.add_usr_succ);
        DialogResult = DialogResult.OK;
        Close();
    

catch(HttpResponseException ex)

    string message = ex.ReasonPhrase;

    if (string.IsNullOrEmpty(Messages.ResourceManager.GetString(ex.ReasonPhrase)))
        message = Messages.ResourceManager.GetString(ex.ReasonPhrase);


    MessageBox.Show("Error code: " + ex.StatusCode + " Message: " + message);

【讨论】:

你可以忽略我的问题的那一部分,因为没有任何东西传回我的表单的原因是控制器中我的 post 方法的第一个 catch 块中抛出的异常。 那么在这种情况下,这是因为您的表单代码中没有 try...catch 块...您遇到了一个未捕获的异常,这是标准行为。 由于某种原因我无法捕获 HttpResponseException,只有 HttpRequestException,我已经添加了所有引用,但仍然没有运气。 HttpRequestException 没有所需的成员。我也尝试过捕获一般异常并进行强制转换,但没有可用的必需成员。 由于我有 2 个项目,我在 UI 项目中丢失了一些包,在我添加了您的代码之后,我仍然在与以前相同的位置出现异常:“ System.Web .Http.HttpResponseException: '处理 HTTP 请求导致异常。有关详细信息,请参阅此异常的 'Response' 属性返回的 HTTP 响应。'" 这是响应: StatusCode: 409,ReasonPhrase:'username_con',版本:1.1,内容:System.Net.Http.StringContent,标题: Content-Type:text/plain;字符集=utf-8 所以基本上创建了一个异常,因为 409 是一个冲突代码,并且原因短语很好,它只是没有传递回表单,而是在显示的 catch 块中停止执行未捕获的异常。

以上是关于异常处理时捕获块中的 System.Web.Http.HttpResponseException的主要内容,如果未能解决你的问题,请参考以下文章

动手动脑-异常处理

Java异常处理的基础知识

Java异常处理

如何从Publish-Module中捕获异常?

如何使用多个catch块处理异常

检查 PL/SQL 异常块中的特定错误代码