I am using a dbContextwhich is described as the following
public class DbContext: System.Data.Entity.DbContext
{
public DbSet<UserAccount> UserAccounts { get; set; }
public DbSet<Sesison> Sessions { get; set; }
}
And in my login action for some reason after checking with the database that the user is correct i am not able to use another entity of the context to save into the database, whats happens is that i won't get the data saved into the database and it will actually stop executing code after the dc.SaveChanges() but i dont get an exeption on my catch, so what my browser is expiriencing is a 500 internal server error.
public ActionResult Login(LoginViewModel model)
{
using (DbContext dc = new DbContext())
{
var v = dc.UserAccounts.SingleOrDefault(a => a.UserName == model.UserName);
if (v != null)
{
if (GetSHA1(model.Password) == v.Password)
{
Guid sessionGuid =Guid.NewGuid();
var session = dc.Sessions.Add(new Sesison() { SessionID = sessionGuid,StartDateTime=DateTime.UtcNow,UserID = v.UserID,ExpireDateTime=DateTime.UtcNow.AddHours(4)});
System.Web.HttpContext.Current.Session["IsLogin"] = true;
System.Web.HttpContext.Current.Session["Session"] = sessionGuid;
try
{
dc.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
// raise a new exception nesting
// the current instance as InnerException
raise = new InvalidOperationException(message, raise);
}
}
throw raise;
}
return Json(new
{
Item1 = "true"
});
}
else
{
return Json(new
{
Item1 = "false",
Item2 = "The username or password you entered is incorrect. Please try again."
});
}
}
else
{
return Json(new
{
Item1 ="false",
Item2 = "The username or password you entered is incorrect. Please try again."
});
}
}
return null;
}
The call to SaveChanges is throwing an exception of a type other than DbEntityValidationException
A quick look at the DbContext SaveChanges call shows that it might throw the following types of exceptions. If you don't want to handle each then you probably want to add a generic Exception handling to find the problem.
// Exceptions:
// T:System.Data.Entity.Infrastructure.DbUpdateException:
// An error occurred sending updates to the database.
//
// T:System.Data.Entity.Infrastructure.DbUpdateConcurrencyException:
// A database command did not affect the expected number of rows. This usually indicates
// an optimistic concurrency violation; that is, a row has been changed in the database
// since it was queried.
//
// T:System.Data.Entity.Validation.DbEntityValidationException:
// The save was aborted because validation of entity property values failed.
//
// T:System.NotSupportedException:
// An attempt was made to use unsupported behavior such as executing multiple asynchronous
// commands concurrently on the same context instance.
//
// T:System.ObjectDisposedException:
// The context or connection have been disposed.
//
// T:System.InvalidOperationException:
// Some error occurred attempting to process entities in the context either before
// or after sending commands to the database.
Related
I Create A News Site With MVC5 But I Have Problem .
in Model i Create A Repository Folder And in this i Create Rep_Setting for
Connect to Tbl_Setting in DataBase .
public class Rep_Setting
{
DataBase db = new DataBase();
public Tbl_Setting Tools()
{
try
{
var qGetSetting = (from a in db.Tbl_Setting
select a).FirstOrDefault();
return qGetSetting;
}
catch (Exception)
{
return null;
}
}
}
And i Create a Rep_News for Main Page .
DataBase db = new DataBase();
Rep_Setting RSetting = new Rep_Setting();
public List<Tbl_News> GetNews()
{
try
{
List<Tbl_News> qGetNews = (from a in db.Tbl_News
where a.Type.Equals("News")
select a).OrderByDescending(s => s.ID).Skip(0).Take(RSetting.Tools().CountNewsInPage).ToList();
return qGetNews;
}
catch (Exception ex)
{
return null;
}
}
But This Code Have Error to Me
OrderByDescending(s=>s.ID).Skip(0).Take(RSetting.Tools().CountNewsInPage).ToList();
Error :
Error 18 'System.Linq.IQueryable<NewsSite.Models.Domain.Tbl_News>' does
not contain a definition for 'Take' and the best extension method overload
'System.Linq.Queryable.Take<TSource>(System.Linq.IQueryable<TSource>, int)' has
some invalid arguments
E:\MyProject\NewsSite\NewsSite\Models\Repository\Rep_News.cs 50 52 NewsSite
How i Resolve it ?
Try it this way. The plan of debugging is to split your execution, this also makes for a more reusable method in many cases. And a good idea is to avoid using null and nullables if you can, if you use them "on purpose" the you must have a plan for them.
DataBase db = new DataBase();
Rep_Setting RSetting = new Rep_Setting();
public List<Tbl_News> GetNews()
{
int skip = 0;
Tbl_Setting tools = RSetting.Tools();
if(tools == null){ throw new Exception("Found no rows in the database table Tbl_Setting"); }
int? take = tools.CountNewsInPage;//Nullable
if(!take.HasValue)
{
// Do you want to do something if its null maybe set it to 0 and not null
take = 0;
}
string typeStr = "News";
List<Tbl_News> qGetNews = (from a in db.Tbl_News
where a.Type.Equals(typeStr)
select a).OrderByDescending(s => s.ID).Skip(skip).Take(take.Value);
return qGetNews.ToList();
}
if qGetNews is a empty list you now don't break everything after trying to iterate on it, like your return null would. instead if returning null for a lit return a new List<>() instead, gives you a more resilient result.
So I said reusable method, its more like a single action. So you work it around to this. Now you have something really reusable.
public List<Tbl_News> GetNews(string typeStr, int take, int skip = 0)
{
List<Tbl_News> qGetNews = (from a in db.Tbl_News
where a.Type.Equals(typeStr)
select a).OrderByDescending(s => s.ID).Skip(skip).Take(take);
return qGetNews.ToList();
}
Infact you shjould always try to avoid returning null if you can.
public class Rep_Setting
{
DataBase db = new DataBase();
public Tbl_Setting Tools()
{
var qGetSetting = (from a in db.Tbl_Setting
select a).FirstOrDefault();
if(qGetSetting == null){ throw new Exception("Found no rows in the database table Tbl_Setting"); }
return qGetSetting;
}
}
We are working on new MVC5 web apps in which we are using existing API libraries for certain functionalities.
Now, these API libraries throws certain exception types which needs to be communicated back to the client browser.
How I want the handling of these exceptions to work is:
If the called action returns a view, then take the user to a page with the exception message
If the called action returns a JSON string, then return the response in string format
My concern now is with #2 since the controller's 'OnException' method always returns a server error and by default ASP.NET will return a default custom error unless otherwise I change the web app configuration as follows
<system.web>
...
<customErrors mode="Off"/>
<system.webServer>
...
<httpErrors errorMode="Detailed" />
My question is, how do I return the JSON string from the 'OnException' without having to change the web configuration as shown above? (i.e. promote the ExceptionContext to return a regular JSON response string).
TIA
protected override void OnException(ExceptionContext filterContext)
{
//If the exeption is already handled we do nothing
if (filterContext.ExceptionHandled)
{
return;
}
// Init
var vm = new ExceptionViewModel();
Exception ex = filterContext.Exception;
var controllerName = filterContext.RouteData.Values["controller"].ToString();
var actionName = filterContext.RouteData.Values["action"].ToString();
// Get action return type
Type controllerType = filterContext.Controller.GetType();
var method = controllerType.GetMethod(actionName);
Type returnType = null;
// If method is null, default to JSONREsult
if (method == null)
{
returnType = typeof(JsonResult);
}
else
{
returnType = method.ReturnType;
}
// Log exception
vm.ErrorLogId = LogException(ex);
// Assign Exception View Model
if (ex is MyCustomExceptionType)
{
filterContext.HttpContext.Response.StatusCode = 200;
vm.ErrorMessage = filterContext.Exception.Message;
}
else if (ex is NotAuthorizedException)
{
// Get Http exception
var httpEx = ex as NotAuthorizedException;
filterContext.HttpContext.Response.StatusCode = httpEx.GetHttpCode();
vm.ErrorMessage = httpEx.Message;
}
else
{
// Set status code to 500 since this exception block indicates an application
// exception occurred
filterContext.HttpContext.Response.StatusCode = 500;
vm.ErrorMessage = "Sorry, I may have malfunctioned. Toink!";
}
// Prepare data to return back to client
if (returnType.Equals(typeof(JsonResult)) || returnType.Equals(typeof(Task<JsonResult>)))
{
filterContext.Result = new JsonResult()
{
Data = vm.ErrorMessage,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
filterContext.Result = new ViewResult()
{
ViewName = "Error",
ViewData = new ViewDataDictionary(vm)
};
}
// Mark exception as a handled
filterContext.ExceptionHandled = true;
}
I am consuming someone elses REST service for my app. the problem is that each request can return 1 of 3 different types when responding
either:
the expected successfull response type
an error response which wraps the 500 (Error)
a validation error response (ValidationErrors)
I am currently calling the service wrapping each request with a class like this:
public class ApiResponse<T>
{
public T ResponseObject { get; set; }
public ValidationErrors<ValidationError> Errors { get; set; }
public Error Error { get; set; }
}
public async Task<ApiResponse<AMethodResponse>> AMethod(AMethodRequest req)
{
ApiResponse<AMethodResponse> resp = new ApiResponse<AMethodResponse> { Errors = new ValidationErrors<ValidationError>() };
using (HttpClient client = HttpClientFactory.Create(new AuthorisationHandler(), new ContentTypeHandler()))
{
client.BaseAddress = new Uri(BaseURI);
var httpResponseMessage = await client.PostAsXmlAsync<AMethodRequest>("AMethod/", req);
if (!httpResponseMessage.IsSuccessStatusCode)
{
//its at this point that I need to work out if i am getting Validation Errors or.. a plain Error
//I can do this, but of course if its a plain error it will fall over
resp.Errors = await httpResponseMessage.Content.ReadAsAsync<ValidationErrors<ValidationError>>();
}
else
{
resp.ResponseObject = await httpResponseMessage.Content.ReadAsAsync<AMethodResponse>();
}
}
return resp;
}
I wonder if there is a more reliable pattern to writing consuming methods.
thanks
it gives a 200 for all is well. 400 for validationerror and 500 for a real error
Check the status code directly, rather than use IsSuccessStatusCode :
var httpResponseMessage = await client.PostAsXmlAsync<AMethodRequest>("AMethod/", req);
switch (httpResponseMessage.StatusCode)
{
case HttpStatusCode.OK: //200
resp.ResponseObject = await httpResponseMessage.Content.ReadAsAsync<AMethodResponse>();
break;
case HttpStatusCode.BadRequest: //400
resp.Errors = await httpResponseMessage.Content.ReadAsAsync<ValidationErrors<ValidationError>>();
break;
case HttpStatusCode.InternalServerError: //500
throw new Exception("failed"); // use appropriate exception and/or read 500 wrapper
break;
}
return resp;
I am new to EF code first approach, what I am trying to do is just inserting a record but somehow the database fails to generate in my SQL Server when my SubmitResult method is executed. I placed a breakpoint at unitOfWork.Save(); and it went through without catching any errors, I assume that if my connection string is invalid it would have thrown an exception. What could possibly be causing this?
Thanks.
[HttpPost]
public JsonResult SubmitResult(String signedRequest, String facebookName, String email, int score, String title)
{
DateTime now = ConstantHelper.GetCurrentTime();
try
{
FacebookSignedRequestUtility fbSignedRequestUtility = new FacebookSignedRequestUtility();
fbData = fbSignedRequestUtility.Parse(FacebookUtility.AppSecret, signedRequest);
Entry entry = new Entry();
entry.Fbuid = fbData.FBUID;
entry.FacebookName = facebookName;
entry.Email = email;
entry.Score = score;
entry.Title = title;
entry.CreatedDateTime = now;
entry.ModifiedDateTime = now;
unitOfWork.EntryRepository.Insert(entry);
unitOfWork.Save();
}
catch (Exception ex)
{
return Json(new { status = "false" });
}
return Json(new { status = "true" });
}
Ok found out that my unitOfWork class has some issues, it works if instantiate my db and save.
AmexContext amc = new AmexContext() ;
amc.SaveChanges();
I have the following form in a Struts2 JSP that contains some radio buttons. There are 2 other forms on the page that work correctly, but this one doesn't. I have determined that the value selected is somehow not being passed, and that that is the reason I'm getting a NullPointerException, but I can't figure out why it's happening. Can anyone help me? Here is my JSP form.
<s:form action="ProcessPoll3">
<table>
<tr>
<td><b><i>Poll #3</i></b></td>
<td>How many kids do you have?</td>
<td><s:radio name="poll3"
list="#{'1':'0.', '2':'1.', '3':'2.',
'4':'3.', '5':'More than 3.'}" />
<s:submit value="Vote Poll #3" align="left" /></td>
</tr>
</table>
</s:form>
My DAO class gets called with this line (and it is being called, for sure):
String poll3;
private HttpServletResponse response;
public String getPoll3() {
return poll3;
}
public void setPoll2(String poll3) {
this.poll3 = poll3;
}
public String execute() {
Poll3DAO poll3DAO = new Poll3DAO();
if (poll3DAO.tallyVote(poll3).equals("success")) {
// Processing goes on here, not relevant to this problem
}
Here is the method in the DAO class, with the breakdown point marked because the parameter that was supposed to be passed was null.
public String tallyVote(String vote) {
String successfulWrite;
request = ServletActionContext.getRequest();
SessionFactory sessionFactory = (SessionFactory) request.getSession()
.getServletContext().getAttribute("sessionFactory");
Session session = sessionFactory.openSession();
try {
// Get previous results
Transaction tx1 = session.beginTransaction();
Query myQuery = session.createQuery("from Poll3");
tx1.commit();
// Update results
Iterator<Poll3> iterate = myQuery.iterate();
Poll3 poll3 = iterate.next();
// NullPointerException occurs on next line
if (vote.equals("1")) {
poll3.setZero(poll3.getZero() + 1);
} else if (vote.equals("2")) {
poll3.setOne(poll3.getOne() + 1);
} else if (vote.equals("3")) {
poll3.setTwo(poll3.getTwo() + 1);
} else if (vote.equals("4")) {
poll3.setThree(poll3.getThree() + 1);
} else if (vote.equals("5")) {
poll3.setMoreThanThree(poll3.getMoreThanThree() + 1);
}
// Write new results back to database;
Transaction tx2 = session.beginTransaction();
session.update(poll3);
tx2.commit();
successfulWrite = "success";
} catch (Exception e) {
System.out.println(e.toString());
successfulWrite = "failure";
}
return successfulWrite;
}
I'm betting it's this:
public void setPoll2(String poll3) { ... }
This is why we have map/collection support to avoid writing cut-and-paste blobs like this.
Any time you find yourself cutting and pasting code like in your snippets it's generally because an abstraction has been ignored/overlooked.