Insertion failed when used Asp.Net Mvc, Linq, Entity Framework - asp.net-mvc-4

I am trying to add row to table using asp.net mvc kendo ui. But for the first time, it is a success. when do second time, the debugging pointer says "The process or thread has been changed since the last step" and try to add the first insertion values also. Since the table does not allow the duplication of primary key the insertion fails at second time. Please advie.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Insert([DataSourceRequest] DataSourceRequest request, AdminHeaderImage batchModel)
{
if (ModelState.IsValid)
{
using (var Entity = new DealerEntities())
{
Entity.AdminHeaderImages.AddObject(batchModel);
Entity.SaveChanges();
return RedirectToAction("Index");
}
}
else
{
return RedirectToAction("Index");
}
}
public ActionResult Index()
{
using (var Entity = new DealerEntities())
{
var outPut = Entity.AdminHeaderImages.ToList();
return View(outPut);
}
}

It seems your Entity object is shared between requests.
I recommend having an entity object per web request.
This article explains more
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/05/18/how-to-manage-objectcontext-per-request-in-asp-net.aspx

I just used the following code at the end of Insert which would refresh my entity.
"return Json(new [] { product }.ToDataSourceResult(request, ModelState));"
This solved my problem.

Related

ASP.NET Core WEB API Problem with GET parameters in API method

I have this controller
[ApiController]
[Route("api/[controller]")]
public class FamiliesController : ControllerBase
{
readonly FamilyFinanceContext db;
public FamiliesController(FamilyFinanceContext context)
{
db = context;
}
[HttpDelete("deletefamily")]
public async Task<ActionResult<Family>> DeleteFamilly(int id)
{
Family user = db.Families.FirstOrDefault(x => x.Id == id);
if (user == null)
{
return NotFound();
}
db.Families.Remove(user);
await db.SaveChangesAsync();
return Ok(user);
}
}
after call https://localhost:44373/api/families/deletefamily?id=2 i have this error - HTTP ERROR 405
In theory this GET parameters must work. What i done not correctly?
As ESG stated, your trying to do a DELETE, so you need to use the DELETE verb, not the GET verb. You're getting a 405 Method Not Allowed for this reason (you cannot use GET on a DELETE action). You should use a tool like PostMan (https://www.postman.com/) to create your DELETE requests, since you can't really do it easily just in a browser.
To fall more in line with REST convention, you should consider changing your DELETE method slightly:
[HttpDelete("{id}")]
public async Task<ActionResult> DeleteFamily([FromRoute] int id)
{
Family user = db.Families.FirstOrDefault(x => x.Id == id);
if (user == null)
{
return NotFound();
}
db.Families.Remove(user);
await db.SaveChangesAsync();
return NoContent();
}
You would then call this as DELETE https://localhost:44373/api/families/2
By using the [HttpDelete("{id}"] attribute, your moving the id from the query string to the URI, which is more in line with REST convention (the URI represents an object). Query string parameters are more typically used for optional capabilities, such as filtering, sorting, etc and not the endpoint representing the object itself.
Typically DELETE actions do not return content, but that is up to you. If you really want to return the user object, then stick with Ok(user), but NoContent is more typical of the DELETE verb.

Trying to simply add a variable value to database

New to asp.net core.I have a database (let's call in database123), with table Student. Student has 4 Columns, StudentId, StudentNameName, StudentGender and CreatedUtc.
No probs adding data via razor page to database. But I want the CreatedUtc value to be inserted into the database, not via the view, but via the controller (it is the date the record was created and should come from DateTime.Now.ToString or something similar.
I am having trouble figuring out where and how to code this into the Create.cshtml.cs controller. I assume it needs to be entered into the public async Task OnPostAsync().
Currently I have this
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
MessageVar += $" Server time { DateTime.Now.ToString() }"; // Get Date and Time
_context.Student.Add(Student);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
In the CreateModel area above, I have this:-
public string MessageVar { get; private set; } = "Local Server Time: ";
Any help would be greatly appreciated. I know it is probably really simple, but just having trouble finding it.
Thanks in advance,
Before saving your student, set the time.
student.createdutc = DateTime.UtcNow;

MVC - refresh controller SQL data model from View?

I am new to MVC, have some experience in webforms.
I currently have an ActionResult function in my controller that binds all my SQL data to a model, which then I can then successfully build a dataview from in the view.
My issue is that to have everything work properly, I need to call my ActionResult directly in the controller before rendering the page, and this works just fine:
public ActionResult Index()
{
Bind_grid();
return View();
}
public class My_Table
{
public string info_a { get; set; }
public string info_b { get; set; }
public string mod_id { get; set; }
}
public ActionResult Bind_grid()
{
SqlConnection checkitem = new SqlConnection("Data Source=[IPADDRESS];Persist Security Info=True;User ID=userid;Password=password");
string query = "SELECT id, info_a, info_b FROM [my_db].[dbo].[ref_index]";
SqlCommand execute = new SqlCommand(query, checkitem);
var model = new List<My_Table>();
using (checkitem)
{
checkitem.Open();
SqlDataReader rdr = execute.ExecuteReader();
while (rdr.Read())
{
var table = new My_Table();
table.info_a = rdr["info_a"].ToString();
table.info_b = rdr["info_b"].ToString();
table.mod_id = rdr["id"].ToString();
model.Add(table);
}
checkitem.Close();
}
return View(model);
}
I am wondering how to refresh the model from the view instead of requiring it to be ran before returning the view, I've tried AJAX calls and #HTML.Action calls to Bind_grid, but I can't seem to get the page to refresh the data.
Any suggestions in running Bind_grid from a view to refresh the model?
Currently I try this:
function bind_data() {
$.ajax({
url: '#Url.Action("Bind_grid")',
method: 'POST',
});
#{
int p = 0;
foreach (var d in Model)
{
#:console.log(#d.mod_id);
p++;
}
}
}
And I set a javascript interval for 10 seconds to run the bind_data() function,
remove some IDs from the SQL database between intervals,
but the data written to the console is still the original fetched, not the refreshed data.
If I manually refresh the page (F5), I get a correct update of data.
I'm guessing I need to do some kind of partial postback to refresh the razor data, but am not sure the best way to do it in MVC. Any help is appreciated.
You should be able to use the jquery load method, call in your JavaScript interval
$("#grid").load("bind_grid");
Fixed the issue by doing all processing in the codebehind, changed the Bind_grid()
to JsonResult, returning Json(model.ToArray(), JsonRequestBehavior.AllowGet);
Was able to do successful pulls via ajax request.

Long time execution action asp.net core mvc

What is the best approach to write an action that takes 1 minute or more to execute but returns immediately the control to the view ?
I know that there is Hangfire solution, but it uses a database to store executions and I need something more simple.
I´m using asp.net core.
This is what my action is doing:
private void CipherData()
{
var posts = _context.Posts.All().ToList();
foreach (var post in posts)
{
post.TextCrypt = EncryptionHelper.Encrypt(post.Text);
_context.Posts.Update(post);
}
_context.SaveChanges();
}
I was having problem using Task.Run (that is a way to do this), because it loses the database context (injected).
So I create a new database context to use in this process. Basically:
public IActionResult CipherData()
{
Task.Run(() =>
{
//create a new dbcontext here
//perform database manipulation using this new dbcontext
}
return RedirectToAction("Index", "Home");
}

Preserving model in ASP.NET MVC 4

I have an ASP.NET MVC 4 app. I'm relatively new to ASP.NET MVC 4. Currently, I'm trying to build a basic Task list app.
public ActionResult Create()
{
var model = new TaskModel();
return View("~/Views/Task.cshtml", model);
}
[HttpPost]
public ActionResult Create(TaskModel model)
{
if (model.TaskName.Length == 0)
{
// Display error message
}
else
{
// Save to database
// Write success message
}
return View("~/Views/Task.cshtml", model);
}
If there is an error, I display an error message on the screen. My problem is, the previously entered values in the view are not shown. The entire view is blank.How do I preserve the values in the view in this case?
Thank you!
I use TempData for this.
public ActionResult Create()
{
var model = new TaskModel();
TempData["task"] = model;
return View("~/Views/Task.cshtml", model);
}
[HttpPost]
public ActionResult Create()
{
var task = (TaskModel)TempData["task"];
UpdateModel(task);
if (model.TaskName.Length == 0)
{
// Display error message
}
else
{
// Save to database
// Write success message
}
TempData["task"] = task;
return View("~/Views/Task.cshtml", model);
}
MVC works different than WebForms, since there is no concept of 'controls', you have to preserve the state yourself. Another option if you don't want to use TempData is to use an LosFormatter to Serialize your controls into a hidden HTML field. This would replicate the functionality of ViewState in ASP.NET WebForms