Updating multiple records at the same time in MVC - asp.net

Trying to update more than 1 record using a form submission in MVC (bringing existing data into the View from the DB and allowing user to make changes).
In the View, I can return as many existing records as I need ready to be edited, without a problem:
#model IEnumerable<object>
#{
List<Portal.Models.Primary_Client> PClient = Model.ToList()[0] as List<Portal.Models.Primary_Client>;
List<Portal.Models.Primary_Dependent> PDependant = Model.ToList()[1] as List<Portal.Models.Primary_Dependent>;
List<Portal.Models.Primary_AnnExp> PAnnExp = Model.ToList()[2] as List<Portal.Models.Primary_AnnExp>;
List<Portal.Models.Primary_IncExp> PIncEx = Model.ToList()[3] as List<Portal.Models.Primary_IncExp>;
List<Portal.Models.Primary_InvAssets> PInvAssets = Model.ToList()[4] as List<Portal.Models.Primary_InvAssets>;
List<Portal.Models.Primary_Liabilities> PLiabilities = Model.ToList()[5] as List<Portal.Models.Primary_Liabilities>;
List<Portal.Models.Primary_LifeAssets> PLAssets = Model.ToList()[6] as List<Portal.Models.Primary_LifeAssets>;
ViewBag.Title = "Completed Form";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("EditPLA/" + newid, "Forms", FormMethod.Post))
{
for (int i = 0; i < PLAssets.Count; i++)
{
<div class="form-group">
#Html.HiddenFor(Model => PLAssets[i].LifAsset_ID)
#Html.HiddenFor(Model => PLAssets[i].PLForm_ID)
#Html.HiddenFor(Model => PLAssets[i].Client_ID_PriFK)
</div>
<div class="container">
<div class="row">
<div class="col-sm">
#Html.Label("Asset Type")
#Html.EditorFor(Model => PLAssets[i].PLAsset_Type, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-sm">
#Html.Label("Asset Amount")
#Html.EditorFor(Model => PLAssets[i].PLAmount_Per_Annum, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
<br />
}
<div class="button" style="text-align:center;">
<input type="submit" class="btn btn-success" value="Save" />
<button class="btn btn-danger" data-dismiss="modal">Cancel</button>
</div>
}
However, my model does not populate properly when I submit the form as the field names are not passing as expected and do not match my model field names. I suspect this is because of how I create the fields using the loop.
My Editor field names look like this:
<input class="form-control text-box single-line" id="CS___8__locals1_PLAssets_0__PLAmount_Per_Annum" name="CS$<>8__locals1.PLAssets[0].PLAmount_Per_Annum" type="text" value="3">
When I would have expected to see something more like this:
<input class="form-control text-box single-line" id="PLAmount_Per_Annum" name="PLAmount_Per_Annum" type="text" value="3">
I believe this is made more difficult than usual because I have several Models being passed to my View through an Object, but I don't know how else to create these fields with the correct name.
FYI - My Controller looks like this:
[HttpPost]
public ActionResult EditPLA(List<Primary_LifeAssets> Assets, int id)
{
if (ModelState.IsValid)
{
foreach (var i in Assets)
{
var c = db1.Primary_LifeAssets.Where(a => a.LifAsset_ID.Equals(i.LifAsset_ID)).FirstOrDefault();
if (c != null)
{
c.PLForm_ID = i.PLForm_ID;
c.PLAmount_Per_Annum = i.PLAmount_Per_Annum;
c.PLAsset_Type = i.PLAsset_Type;
}
}
db1.Entry(Assets).State = EntityState.Modified;
db1.SaveChanges();
ViewBag.Message = "Successfully Updated.";
return RedirectToAction("Existing/" + id, "Forms");
}
ViewBag.Message = "Save failed.";
return RedirectToAction("Existing/" + id, "Forms");
}

Related

How to call method on the Controller from view

First of all I'm a little new on this and I have a lot of questions but one of them is the next one.
Is there any way to call methods (without view) situated on the Controller from another view and send one parameter at the same time?
I've been trying to do it but I can't.
I have tried this:
#{
((HomeController)this.ViewContext.Controller).Method1();
}
but I get an error which says that namespace could not be found
the flow is: open the view->click on add button->select one row from other table->through coding, send the Id of the product to the method I need in order to find a product and insert it into my new table.
here you have some code.
First View
<div id="lista" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
#{Html.RenderAction("selectOrden", "Producto");}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
Controller
[HttpGet]
public ActionResult selectOrden()
{
try
{
client = new FireSharp.FirebaseClient(config);
FirebaseResponse response = client.Get("Producto");
dynamic data = JsonConvert.DeserializeObject<dynamic>(response.Body);
var list = new List<Producto>();
foreach (var item in data)
{
list.Add(JsonConvert.DeserializeObject<Producto>(((JProperty)item).Value.ToString()));
Debug.WriteLine(JsonConvert.DeserializeObject<Producto>(((JProperty)item).Value.ToString()).nombreProducto);
return View(list);
}
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, ex.Message);
}
return View();
}
//Inserta registros de productos en las ordenes de compra
[HttpPost]
public void selectOrdena(string id)
{
client = new FireSharp.FirebaseClient(config);
FirebaseResponse responseProdu = client.Get("Producto/" + id);
Producto dataProdu = JsonConvert.DeserializeObject<Producto>(responseProdu.Body);
ViewBag.Soli = dataProdu;
Debug.WriteLine("Hello");
//return View(dataProdu);
}
Second View
#model IEnumerable<FirebaseMVCTestApp.Models.Producto>
#{
ViewBag.Title = "selectOrden";
Layout = null;
}
<h2>selectOrden</h2>
#using (Html.BeginForm("Save","ProductoController", FormMethod.Post))
{
<form method="post">
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<table id="table_idxd" class="display">
<thead>
<tr>
<th>
Nombre del producto
</th>
<th>
Cantidad
</th>
<th>
Costo
</th>
<th>
Precio
</th>
<th>
Codigo
</th>
<th>Acción</th>
</tr>
</thead>
#{ try
{
foreach (var item in Model)
{
<tr>
<td>
#Html.EditorFor(model => item.nombreProducto, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(modelItem => item.cantidad, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(modelItem => item.costo, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(modelItem => item.precio, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(modelItem => item.codigo, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.ActionLink("Agregar", "selectOrdena", new { id = item.idProducto })
<input type="submit" value="Save" class="btn btn-default" />
</td>
</tr>
}
}
catch (Exception ex)
{
}
}
</table>
</form>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
The method you provided is valid.
This is how you call an instance method on the Controller:
#{
((HomeController)this.ViewContext.Controller).Method1();
}
This is how you call a static method in any class:
#{
SomeClass.Method();
}
This will work assuming the method is public and visible to the view.But according to what you said, an error was reported:
that namespace could not be found
The reason may be that the project that references the assembly may have a different frame type from the assembly.You can check this post, it may be helpful to you:https://stackoverflow.com/questions/4764978/the-type-or-namespace-name-could-not-be-found
Ok I've checked all the other threads and I think it was going so far from my problem, but I have already solved it by adding this line on the second view
#using FirebaseMVCTestApp.Controllers
in that way the view could see the controller I needed.
I know that the question was a little newbbie but if I didn't ask I would probably never find the answer.
Thank you. :)

How to make a prepopulated form in ASP.NET MVC and Entity Framework

So I have a list of clients in a database with various information about them. I need to print all of them out with a slidedown form with their current information already there, and the ability to add or change it.
I am able to print out all the clients and their info but when I try to edit the form it is disabled even though there is no disabled attribute set.
Here is the controller
public ActionResult Index()
{
var context = new U2XPlanningAutomationToolEntities();
string query = "SELECT * FROM Clients";
IEnumerable<Client> data = context.Database.SqlQuery<Client>(query);
List<Client> clients = new List<Client>(data);
ViewBag.Clients = clients;
string email = Session["email"] as string;
if (!String.IsNullOrEmpty(email))
{
return View();
}
return View("../Account/Login");
}
The View
#foreach (var client in ViewBag.Clients)
{
string plan_changes = client.plan_changes;
string critical_milestones = client.critical_milestones;
string pdd = client.pdd;
string inbound = client.inbound;
string outbound = client.outbound;
string other = client.other;
<div class="row client">
<div class="col-sm-3"><span id="#client.id" class="glyphicon glyphicon-plus dropdownBtn"></span><p>#client.name</p></div>
<div class="col-sm-3"><p>#client.oep_start</p></div>
<div class="col-sm-3"><p>#client.oep_end</p></div>
<div class="col-sm-3 text-right"><button id="#client.id" class="btn btn-primary delete-client">Delete</button></div>
<div class="col-sm-12 slider" id="slider_#client.id">
#using (Html.BeginForm("UpdateClient", "Home", FormMethod.Post))
{
<div class="col-sm-4">
<input type="hidden" name="id" value="#client.id" />
#Html.LabelFor(c => c.plan_changes, "Plan Changes")
#*<textarea name="plan_changes" class="form-control" cols="20" rows="2">#plan_changes</textarea>*#
#Html.TextArea("plan_changes", plan_changes, new { #class = "form-control" })
#Html.LabelFor(c => c.critical_milestones, "Critical Milestones")
#Html.TextArea("critical_milestones", critical_milestones, new { #class = "form-control" })
</div>
<div class="col-sm-4">
#Html.LabelFor(c => c.pdd, "Plan Document Design")
#Html.TextArea("pdd", pdd, new { #class = "form-control" })
#Html.LabelFor(c => c.inbound, "Inbound")
#Html.TextArea("inbound", inbound, new { #class = "form-control" })
</div>
<div class="col-sm-4">
#Html.LabelFor(c => c.outbound, "Outbound")
#Html.TextArea("outbound", outbound, new { #class = "form-control" })
#Html.LabelFor(c => c.other, "Other")
#Html.TextArea("other", other, new { #class = "form-control" })
</div>
<div class="col-sm-12 text-center">
<input type="submit" value="Update" name="update" class="btn btn-primary" />
</div>
}
</div>
</div>
}
If my approach seems weird to you it might be because I am brand new to MVC ASP.NET, I am coming from a PHP background.
Thanks in advance!
Please use a IEnumerable<Client> in you view instead of putting it into a viewbag. Can you try to pass the id in the Html.BeginForm. Do you have an UpdateClient method in your HomeController class?

ASP.NET MVC 5: How to avoid hidden form field manipulation during model binding?

I am working on a tutorial from the Microsoft website with the end result like this image:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-5/_static/image4.png
The price textbox in the View is:
<div class="form-group">
#Html.LabelFor(model => model.AlbumToEdit.Price, "Price", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AlbumToEdit.Price)
#Html.ValidationMessageFor(model => model.AlbumToEdit.Price)
</div>
</div>
Which renders as:
<input class="text-box single-line" id="AlbumToEdit_Price" name="AlbumToEdit.Price" type="text" value="9.99">
If I inspect the HTML via DevTools and add the below:
<input id="AlbumToEdit_Price" name="AlbumToEdit.Price" type="hidden" value="33.33">
And click the Save button to save the album details, the binding process is taking the 33.33 in consideration, regardless what I insert in the Price textbox, probably because both <input> tags share the same id and name.
How can I avoid this?
Controller code follows:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(AlbumToEditViewModel postedViewModel)
{
if (ModelState.IsValid)
{
db.Entry(postedViewModel.AlbumToEdit).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
AlbumToEditViewModel albumToEditViewModel = new AlbumToEditViewModel
{
AlbumToEdit = postedViewModel.AlbumToEdit,
Artists = new SelectList(db.Artists, "ArtistId", "Name", postedViewModel.AlbumToEdit.ArtistId),
Genres = new SelectList(db.Genres, "GenreId", "Name", postedViewModel.AlbumToEdit.GenreId)
};
return View(albumToEditViewModel);
}

How to fetch data from database in same input textbox after form submit?

I have next method where we use fom post to send date to database:
[HttpPost]
public ActionResult AddDateToDatabase(StudyDateViewModel model)
{
var studyDate = model.StudyDate;
if (ModelState.IsValid)
{
using (var personRepository = new StudentsRepository<PersonalInformation>())
{
string userId = User.Identity.GetUserId();
var changeStudyDate = personRepository.Get()
.Where(c => c.UserId == userId)
.FirstOrDefault();
changeStudyDate.StudyDate = studyDate;
personRepository.Update(changeStudyDate);
TempData["message"] = $"Well done. Your study date is {studyDate.Value.ToShortDateString()}. Don't forget to check email ";
}
}
else
{
return View(model);
}
return RedirectToAction("PersonalCabinet");
}
This is my partial view where we call our method:
#using (Html.BeginForm("AddDateToDatabase", "Home", FormMethod.Post, new { enctype = "multipart/form-data" , id = "dateForm" }))
{
<div class="input-group input-medium date date-picker" data-date-format="dd-mm-yyyy" data-date-start-date="+0d">
#Html.TextBoxFor(m => m.StudyDate, new { #class = "form-control", Value = Model.StudyDate })
<span class="input-group-btn">
<button class="btn default" type="button">
<i class="fa fa-calendar"></i>
</button>
</span>
</div>
<br />
<input type="submit" value="Choose" class="btn btn-info" />
}
And we call our partil view next:
#Html.Partial("AddDateToDatabase", new StudyDateViewModel())
So my question is how to get value from database in same input after form submit?? Because when I click submit value pass to server good but it dissapears from this input after reloading page? So What I should do in this case?

ASP.NET MVC – Use Html.BeginForm to pass model data and non-model hidden field value

I’m using BeginForm to pass model data (i.e. last_coffe_time) which works fine. However I also wanted to pass to controller ClientDateTime value stored in hidden field which is not a part of the model.
I don’t know how do do it, at best I can pass ClientDateTime as static string but I can't figure out how to dynamically read hidden field for value and pass that value to controller.
Someone please help. Thank you
View:
#model SleepNotes.Models.Diary
#using (Html.BeginForm("Edit", "Diary", new { ClientDateTime = "ClientDateTime" }, FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.Hidden("ClientDateTime", new { id = "ClientDateTime" })
<div class="form-group">
#Html.LabelFor(model => model.last_coffe_time, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.last_coffe_time, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.last_coffe_time, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<!--Set ClientDateTime-->
<script>
var a = new Date()
var month = a.getMonth() + 1;
document.getElementById('ClientDateTime').value = a.getDate() + "/" + month + "/" + a.getFullYear() + " " + a.getHours() + ":" + a.getMinutes() + ":" + a.getSeconds();
</script>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "id,last_coffe_time")] Diary Diary, string ClientDateTime)
{
if (ModelState.IsValid)
{
//ClientDateTime from view ...do something here
db.Entry(Diary).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "Dashboard");
}
return View(Diary);
}
Remove the new { ClientDateTime = "ClientDateTime" } from the BeginForm() method so the vale is not added as a route parameter (and therefore not bound to your string ClientDateTime parameter in the Edit() method.
Side note: since your wanting to submit a DateTime value, your parameter should be DateTime ClientDateTime (not string) and your script can be simplified to
document.getElementById('ClientDateTime').value = new Date().toISOString();
There are some solutions,
I suggest you to have a ModelView between your Model and View. That
modalview should have the ClientDateTime.
You can use ajax post and send 2 parameters (yourmodal, string) to controller or you
can pass the ClientDateTime as querystring. There are lots of
examples about it.
Hope helps.

Resources