简体   繁体   English

如何从WebAPI引发异常

[英]How to throw Exception from WebAPI

I have business logic which has throw exception, which I need to transfer to my api controller and show when my webapi fails to read. 我有引发异常的业务逻辑,我需要将其转移到我的api控制器并显示我的webapi无法读取的时间。 I have tray catch in all place. 我到处都放着托盘。 In Business Logic` 在业务逻辑中`

public static Models.User Login(Models.Login model)
        {
            try
            {
                using (var db = new Data.TPX5Entities())
                {
                    var query = (from a in db.User
                                 where a.UserID == model.UserName || a.UserCode == model.UserName || a.UserName == model.UserName
                                 select new Models.User
                                 {
                                     EMail = a.EMail,
                                     IsUsed = a.IsUsed,
                                     Memo = a.Memo,
                                     MobilePhone = a.MobilePhone,
                                     Password = a.Password,
                                     Telephone = a.Telephone,
                                     UserCode = a.UserCode,
                                     UserID = a.UserID,
                                     UserName = a.UserName
                                 }).ToList();
                    if (query == null || query.Count == 0)
                    {
                        throw new Exception(@LanguageHelper.GetSystemKeyValue(CultureHelper.GetCurrentCulture(), "/resource/Model/BLL_User_MSG_UserNotFound"));
                    }
                    else if (query.Count > 1)
                    {
                        throw new Exception(@LanguageHelper.GetSystemKeyValue(CultureHelper.GetCurrentCulture(), "/resource/Model/BLL_User_MSG_UserCodeRepeat"));
                    }
                    else
                    {
                        if (query[0].Password == model.Password)
                        {
                            return query[0];
                        }
                        else
                        {
                            throw new Exception(@LanguageHelper.GetSystemKeyValue(CultureHelper.GetCurrentCulture(), "/resource/Model/BLL_User_MSG_InCorrectPassword"));
                        }
                    }

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

then web api controller I use try catch again 然后我使用的Web API控制器再次尝试捕获

 [HttpPost]
        public Models.User Login(Models.Login model)
        {
            Models.User mUser = null;
            try
            {
                mUser = BusinessLogic.User.Login(model);
                if (mUser == null)
                    throw new Exception("Object is null.");
            }
            catch(Exception ex)
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent(ex.Message, Encoding.UTF8), ReasonPhrase = "Login Exception" });
            }
            return mUser;
        }

and then I call in my client I use try catch to check again 然后打电话给我的客户,我用try catch再次检查

private void btnLogin_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty( txtUser.Text))
            {
                TPX.Core.MessageBoxHelper.ShowError(Core.LanguageHelper.GetSystemKeyValue(GlobalParameters.Language, "/resource/Message/MS_FormLogin_Error_UserEmpty"));
                return;
            }
            try
            {               
                //登录系统
                string md5Password = TPX.Core.Security.MD5.GetMD5(txtPassword.Text);
                TPX.Models.Login mLogin = new TPX.Models.Login();
                mLogin.UserName = txtUser.Text.Trim();
                mLogin.Password = md5Password;
                //Retrieve User Information
                string itemJson = Newtonsoft.Json.JsonConvert.SerializeObject(mLogin);
                string userURL = GlobalParameters.Host + "api/User/Login";

                using (System.Net.WebClient webClient = new System.Net.WebClient())
                {
                    webClient.Headers["Content-Type"] = "application/json";
                    webClient.Encoding = Encoding.UTF8;
                    string sJson = webClient.UploadString(userURL, "POST", itemJson);

                    TPX.Models.User myDeserializedObj = (TPX.Models.User)Newtonsoft.Json.JsonConvert.DeserializeObject(sJson, typeof(TPX.Models.User));

                    ClientContext.Instance.UserID = myDeserializedObj.UserID;
                    ClientContext.Instance.UserCode = myDeserializedObj.UserCode;
                    ClientContext.Instance.UserName = myDeserializedObj.UserName;
                    ClientContext.Instance.Password = myDeserializedObj.Password;
                }
                DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            catch (WebException ex)
            {
                TPX.Core.MessageBoxHelper.ShowException((Core.LanguageHelper.GetSystemKeyValue(GlobalParameters.Language, "/resource/Message/MS_FormLogin_Ex_LoginError")),ex);
            }

        }

When I login with wrong credential need to throw error. 当我使用错误的凭据登录时,需要抛出错误。 Now I am getting error "The remote Server return error:(500)Internal Server Error', Instead I want to throw exact error which my business logic throw. Thanks ` 现在我收到错误消息“远程服务器返回错误:(500)内部服务器错误”,而我想抛出我的业务逻辑抛出的确切错误。

Do not throw 500 internal server error but try and communicating using specific http codes. 不要抛出500个内部服务器错误,而是尝试使用特定的http代码进行通信。 In your case you want to communicate login failure so tell your client that specifically. 在您的情况下,您希望传达登录失败的信息,因此请特别告知您的客户端。

Either use: 可以使用:

 throw new HttpResponseException(HttpStatusCode.Unauthorized);

Or, a custom message like this: 或者,这样的自定义消息:

 var msg = new  HttpResponseMessage(HttpStatusCode.Unauthorized) { 
 ReasonPhrase = "whatever you want it!" };
 hrow new HttpResponseException(msg);

your business layer and your api are two different things. 您的业​​务层和api是两件事。

you don't throw errors from your api unless something really bad happened with your own code. 除非您自己的代码发生了非常糟糕的事情,否则您不会从api中抛出错误。

The api always returns meaningful http codes and that's how the clients know what's going on. 该api总是返回有意义的http代码,这就是客户端如何知道发生了什么。

Example: 例:

[HttpPost]
    public IHttpActionResult Login(Models.Login model)
    {
        var mUser = BusinessLogic.User.Login(model);
            if (mUser == null)
                return NotFound();

        return Ok(mUser);
    }

you are now returning something meaningful which makes sense to a client and you are actually helping them understand what's going on. 您现在正在返回对客户有意义的有意义的东西,并且实际上是在帮助他们了解正在发生的事情。

There are multiple ways to return data, this is only one of them. 返回数据的方式有多种,这只是其中一种。

Avoid throwing errors, it is expensive in terms of resources used and the more users you have the worse it will get. 避免引发错误,这在使用的资源上是昂贵的,并且拥有的用户越多,获得的效果就越差。

You can have your business layer return a message in form of a string and then return that as a result of the API call and the other response shows you how. 您可以让您的业务层以字符串形式返回一条消息,然后作为API调用的结果返回该消息,另一个响应向您展示如何。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM