Reputation: 177
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. 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
[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
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 `
Upvotes: 1
Views: 4911
Reputation: 6335
your business layer and your api are two different things.
you don't throw errors from your api unless something really bad happened with your own code.
The api always returns meaningful http codes and that's how the clients know what's going on.
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.
Upvotes: 1
Reputation: 27039
Do not throw 500 internal server error but try and communicating using specific http codes. 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);
Upvotes: 2