Linq to Sql in mvc 4 - sql

I'm having some problems editing an object in the mvc4 framework using linq to sql.
The "tbBoeking" object has been generated by Visual Studio 2010 and resides in a .dbml file. It has just been generated and no alterations have been made to it or the database.
Code in BoekingController.cs:
//This class has been generated and resides in a .dbml file
private DataClassesDataContext db = new DataClassesDataContext();
//Display edit form
public ActionResult Edit(int id = 0)
{
tbBoeking boeking = db.tbBoekings.Single(p => p.boeknummer == id);
if (boeking == null)
{
return HttpNotFound();
}
return View(boeking);
}
//Process changes made in form
[HttpPost]
public ActionResult Edit(tbBoeking boeking)
{
if (ModelState.IsValid)
{
db.tbBoekings.Attach(boeking, true);
db.SubmitChanges();
return RedirectToAction("Index");
}
return View(boeking);
}
Displaying the edit form works fine but when I press submit and the second Edit() is called things go wrong:
On db.submitchanges() I get an error which simply states:
"Row not found or changed".
I have read a few other posts about this error but they were not helpful for me. I think I'm making some basic mistake with Linq-to-sql or concurrency. Am I using Attach() in the wrong place or is it something else?
Thanks in advance,
Blight

Is all of the required information filled in? Also, do you have some sort of timestamp that might need updated. I have heard of the code ignoring the asUpdated flag if a versioning system is in place. That error can be very generic, so checking some other things can help
If the above suggestions do not help, then I would run a SQL profiler trace to see the SQL that is being fed to the server.

Related

Unable to create a Role using RoleManager in Blazor Serverside

I had some code using the RoleManager that I had copied from an MVC project to create roles in a Blazor project.
It compiles okay but when I step through the code it gets to that line and then appears to throw and exception, as it doesn't ever go to the next line. I am unable to catch an exception though.
Since my code didn't work I found code on the web and it behaved the same, so I changed how it was injected and I got a different error, so I found a third way of doing it and that too gets to the line that tests to see if there is a role already existing and blows up.
Here is the latest attempt
[Inject]
IServiceProvider services {get;set;}
public async Task Initialize()
{
using (var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>())
{
string proRole = "Pro";
if (!await roleManager.RoleExistsAsync(proRole))
{
var temp = await roleManager.CreateAsync(new IdentityRole { Name = proRole });
}
}
}
And it blows up on the awaited if statement.
Here is the previous code that should work that doesn't.
string proRole = "Pro";
string proClientRole = "ProClient";
if (!await _roleManager.RoleExistsAsync(proRole))
{
var temp = await _roleManager.CreateAsync(new IdentityRole { Name = proRole });
}
which is inside of a method.
I also had it as #{code in the Razor file and after an hour of trying different things there I moved it to a base class because they have been more stable in the past.
It is not the database connection because that is well verified and also because UserManager is called in the same class and it work
I also tried this code (Blazor Role Management Add Role trough UI (Crud)) both suggestions.
This is one bad thing about Blazor for me is it is buggy I never know if it is my bad, or just something wrong with the latest greatest. But I am assuming it is my bad in this case.
Anyway any help would be much appreciated, I am way too many hours on this,
I copy/pasted the same code to the "/" page and it works there.
For some reason it wouldn't work in a component loaded into a component but the standard Role code works as expected in the "/" page.
Most likely I should have restarted my computer as it now works in the original location too.

Why is my record being deleted from the db when I attempt to update the record from entity framework MVC?

When I attempt to update a record from entity framework the record is being deleted from the table. There are no errors thrown so it really has me baffled what is happening.
I am fairly new to entity framework and asp.net. I've been learning it for about a month now.
I can update the record without any issues from SQL Server but not from vs. Here is the code to update the db:
// GET: /Scorecard/Edit/5
public ActionResult Edit(int id, string EmployeeName)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
CRS_Monthly crs_monthly = GetAgentById(id);
crs_monthly.EmployeeName = EmployeeName;
if (crs_monthly == null)
{
return HttpNotFound();
}
return View(crs_monthly);
}
// POST: /Scorecard/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="REC_ID,Cur_Plan,Plan_Update,Comments,Areas_Improve,Strengths,UPDATED_BY,UPDATED_TIME,Agent_Recognition")] CRS_Monthly crs_monthly)
{
if (ModelState.IsValid)
{
crs_monthly.UPDATED_TIME = DateTime.Now;
crs_monthly.UPDATED_BY = Request.LogonUserIdentity.Name.Split('\\')[1];
db.Entry(crs_monthly).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(crs_monthly);
}
When I run the debugger crs_monthly is valid and looks fine until db.SaveChanges(). Any help is greatly appreciated!
You should never save an instance of your entity created from a post, especially when you're utilizing Bind to restrict which properties are bound from the post data. Instead, always pull the entity fresh from the database and map the posted values on to it. This ensures that no data is lost.
Using Bind is a horrible practice, anyways. The chief problem with it is that all your properties are listed as string values, and you're introducing maintenance concerns. If remove one of these properties or change the name, the Bind list is not automatically updated. You must remember to change every single instance. Worse, if you add properties, you have to remember to go back and include them in this list or else your data just gets silently dropped with no notice.
If you need to only work with a subset of properties on your entity, create a view model containing just those properties. Then, again, map the posted values from your view model onto an instance of your entity pulled fresh from the database.

SQL adding new record on update

I have an MVC5 EF6.1 app that is working the way I want it to in every aspect except editing records.
I am using a view model to handle the create and edit forms. The view model matches the entity model, except it does not include an Id, and it has some extra properties for handling file uploads.
Creating records works perfectly. The edit form populates fields just the way it is supposed to. On update, the changes are recognized.
The problem is that instead of updating the record, a new record reflecting the changes is added to the database. The record that should have been updated is still there.
I have tried everything I can find to try to fix this. I have tried updating with and without EntityState. I have tried setting OriginalValues and CurrentValues. I have even tried using a raw SQL statement. All have the same result: a record with the new data is added, and the original is left unchanged.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, MyViewModel model)
{
var thisRecord = db.MyEntity.Find(id);
//some stuff to update thisRecord properties
db.SaveChanges();
}
That much works fine. What can I do to change the record I am working on and not make a new one?
Any help would be greatly appreciated. This is driving me nuts.
Try this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, MyViewModel model)
{
var thisRecord = db.MyEntity.Find(id);
thisRecord.SomeProperty = newValue;
// UPDATE: Try adding this line:
_db.Entry(thisRecord).State = EntityState.Modified;
db.SaveChanges();
// Whatever other processing you're doing
}

My first MVC project yields odd error; it stops in the middle of a comment. Why is that?

I'm trying to learn MVC, using VS 2012. I've created a simple Intranet application, and added entity framework. Because I wanted to just start learning I added only 1 table (named Providers) from a SQL Server database. Then I added a controller for Providers table (I believe EF renamed Providers to simply Provider). Then I generated the views for the Provider controller. However, something very strange is going on with the code. When I run it, it fails, but it stops on a line of code that I've commented out?! What in heck is going on? Here's a screen image of the error:
Here's the code for the Index() for the ProviderController class:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Index()
{
//return View(db.Providers.ToList());
//var currentProviders = from p in db.Providers
// where p.ContractIsCurrent == true && p.Facility == 1
// orderby p.ContractName
// select p;
var currentProviders = db.Providers.Where(c => c.ContractIsCurrent && c.Facility == 1)
.OrderBy(c => c.ContractName)
.ToList();
return View(currentProviders);
}
and in case you want to see it, here's the link to the whole project (it doesn't include the change that I have listed above):
Link on my OneDrive
Looks like your pdb file is out of sink.
Clean your solution and ReBuild the application. should fix this

The view or its master was not found or no view engine supports the searched locations

Error like:The view 'LoginRegister' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/MyAccount/LoginRegister.aspx
~/Views/MyAccount/LoginRegister.ascx
~/Views/Shared/LoginRegister.aspx
~/Views/Shared/LoginRegister.ascx
~/Views/MyAccount/LoginRegister.cshtml
~/Views/MyAccount/LoginRegister.vbhtml
~/Views/Shared/LoginRegister.cshtml
~/Views/Shared/LoginRegister.vbhtml
Actually my page view page is ~/Views/home/LoginRegister.cshtml so what i do
and my RouteConfig is
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "MyAccount", action = "LoginRegister", id = UrlParameter.Optional }
);
}
}
Be careful if your model type is String because the second parameter of View(string, string) is masterName, not model. You may need to call the overload with object(model) as the second parameter:
Not correct :
protected ActionResult ShowMessageResult(string msg)
{
return View("Message",msg);
}
Correct :
protected ActionResult ShowMessageResult(string msg)
{
return View("Message",(object)msg);
}
OR (provided by bradlis7):
protected ActionResult ShowMessageResult(string msg)
{
return View("Message",model:msg);
}
Problem:
Your View cannot be found in default locations.
Explanation:
Views should be in the same folder named as the Controller or in the Shared folder.
Solution:
Either move your View to the MyAccount folder or create a HomeController.
Alternatives:
If you don't want to move your View or create a new Controller you can check at this link.
In Microsoft ASP.net MVC, the routing engine, which is used to parse incoming and outgoing URL Combinations, is designed with the idea of Convention over Configuration. What this means is that if you follow the Convention (rules) that the routing engine uses, you don't have to change the Configuration.
The routing engine for ASP.net MVC does not serve web pages (.cshtml). It provides a way for a URL to be handled by a Class in your code, which can render text/html to the output stream, or parse and serve the .cshtml files in a consistent manner using Convention.
The Convention which is used for routing is to match a Controller to a Class with a name similar to ControllerNameController i.e. controller="MyAccount" means find class named MyAccountController. Next comes the action, which is mapped to a function within the Controller Class, which usually returns an ActionResult. i.e. action="LoginRegister" will look for a function public ActionResult LoginRegister(){} in the controller's class. This function may return a View() which would be by Convention named LoginRegister.cshtml and would be stored in the /Views/MyAccount/ folder.
To summarize, you would have the following code:
/Controllers/MyAccountController.cs:
public class MyAccountController : Controller
{
public ActionResult LoginRegister()
{
return View();
}
}
/Views/MyAccount/LoginRegister.cshtml: Your view file.
In your LoginRegister action when returning the view, do below, i know this can be done in mvc 5, im not sure if in mvc 4 also.
public ActionResult Index()
{
return View("~/Views/home/LoginRegister.cshtml");
}
Check the build action of your view (.cshtml file) It should be set to content. In some cases, I have seen that the build action was set to None (by mistake) and this particular view was not deploy on the target machine even though you see that view present in visual studio project file under valid folder
This could be a permissions issue.
I had the same issue recently. As a test, I created a simple hello.html page. When I tried loading it, I got an error message regarding permissions. Once I fixed the permissions issue in the root web folder, both the html page and the MVC rendering issues were resolved.
Check whether the View (.ASPX File) that you have created is having the same name as mentioned in the Controller. For e.g:
public ActionResult GetView()
{
return View("MyView");
}
In this case, the aspx file should be having the name MyView.aspx instead of GetView.aspx
I got this error because I renamed my View (and POST action).
Finally I found that I forgot to rename BOTH GET and POST actions to new name.
Solution : Rename both GET and POST actions to match the View name.
If the problem happens intermittently in production, it could be due to an action method getting interrupted. For example, during a POST operation involving a large file upload, the user closes the browser window before the upload completes. In this case, the action method may throw a null reference exception resulting from a null model or view object. A solution would be to wrap the method body in a try/catch and return null. Like this:
[HttpPost]
public ActionResult Post(...)
{
try
{
...
}
catch (NullReferenceException ex) // could happen if POST is interrupted
{
// perhaps log a warning here
return null;
}
return View(model);
}
I had this same issue.
I had copied a view "Movie" and renamed it "Customer" accordingly.
I also did the same with the models and the controllers.
The resolution was this...I rename the Customer View to Customer1 and
just created a new view and called it Customer....I then just copied
the Customer1 code into Customer.
This worked.
I would love to know the real cause of the problem.
UPDATE
Just for grins....I went back and replicated all the renaming scenario again...and did not get any errors.
I came across this error due to the improper closing of the statement,
#using (Html.BeginForm("DeleteSelected", "Employee", FormMethod.Post))
{
} //This curly bracket needed to be closed at the end.
In Index.cshtml view file.I didn't close the statement at the end of the program. instead, I ended up closing improperly and ran into this error.
I was sure there isn't a need of checking Controller ActionMethod code because I have returned the Controller method properly to the View. So It has to be the view that's not responding and met with similar Error.
If you've checked all the things from the above answers (which are common mistakes) and you're sure that your view is at the location in the exceptions, then you may need to restart Visual Studio.
:(
In my case, I needed to use RedirectToAction to solve the problem.
[HttpGet]
[ControleDeAcessoAuthorize("Report/ExportToPDF")]
public ActionResult ExportToPDF(int id, string month, string output)
{
try
{
// Validate
if (output != "PDF")
{
throw new Exception("Invalid output.");
}
else
{
...// code to generate report in PDF format
}
}
catch (Exception ex)
{
return RedirectToAction("Error");
}
}
[ControleDeAcessoAuthorize("Report/Error")]
public ActionResult Error()
{
return View();
}
I ran into this a while ago and it drove me crazy because it turned out to be simple. So within my View I was using a grid control that obtained data for the grid via an http request. Once the middle tier completed my request and returned the dataset, I received the same error. Turns out my return statement was 'return View(dataset);' instead of 'return Json(dataset);
I couldn't find any solution to this problem, until I found out the files didn't exist!
This took me a long time to figure out, because the Solution Explorer shows the files!
But when I click on Index.cshtml I get this error:
So that was the reason for this error to show. I hope this answer helps somebody.