Update Values in Database - MVC - c#

im using the sortable jquery plugin, because i want that the user can choice the order of the images are showing in my view.
For this i have a Get Controller which sends the data to my PartialView.
How can i make the now the Post Controller to update my table in my database?
Note: In this moment the controller don´t receive any data. i haven´t figured out what is wrong
Someone can help me with this?
Thanks in advance:
Here is my code:
In My PartialView:
#(Html.BeginForm("UpdateOrder", "Admin", FormMethod.Post)){
<div id="Order">
<ul id="sortable">
#foreach (var p in ViewBag.Images)
{
<li id="#Html.AttributeEncode(p.FileName)">
<img src="~/Files/#p.FileName"/>
</li>
}
</ul>
</div>
}
Controller:
if (ModelState.IsValid)
{
using (SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
SqlCommand cmd;
System.Text.StringBuilder sql = new System.Text.StringBuilder();
sql.Append("Update Image Set MyFileName=??? Order By ASC");
cn.Open();
cmd = new SqlCommand(sql.ToString(), cn);
cmd.Parameters.Add(??????????).Value = ;
cmd.ExecuteNonQuery();
cn.Close();
}
}
return View();

Are you looking for something like this?
SqlCommand comm = new SqlCommand("UPDATE Customers SET Name=#name WHERE ID=#id", con;
comm.Parameters.AddWithValue("#name", "John");
comm.Parameters.AddWithValue("#id", id);
For passing data from view to controller take a look at the following links: ASP.NET MVC 3 Razor: Passing Data from View to Controller
ASP.Net MVC Passing multiple parameters to a view
I have created a backend for a website, where i e.g. can add, edit, delete events. So the snippet in the view for the events looks like this:
<div id="tabs-2" class="ui-widget-content">
<h2>
Events</h2>
<p>
#Html.ActionLink("Create new Event", "EventCreate")
</p>
<table id="tableEvent">
<tr>
<th>
Event
</th>
<th>
Date
</th>
<th>
Day of the Week
</th>
<th>
</th>
</tr>
#foreach (var e in ViewBag.Events)
{
<tr id="#e.EventID">
<td>
<h4>#e.EventName</h4>
</td>
<td>
<h4>#string.Format("{0:d}", e.Datum)</h4>
</td>
<td>
<h4>#e.Tag</h4>
</td>
<td>
#Html.ActionLink("Löschen", "EventDelete", new { id = e.EventID })
</td>
</tr>
}
</table>
</div>
I pass the id to the controller in the ActionLink and call the EventDelete:
[Authorize]
public ActionResult EventDelete(int id)
{
repevent.Delete(id);
return RedirectToAction("Main");
}
Now i have the id of the event and can do whatever i want. (In my case, i delete the event with the associated id.
public void Delete(int id)
{
using (KiGaDBEntities db = new KiGaDBEntities())
{
Event event = db.Event.SingleOrDefault(e => e.EventID == id);
if (event != null)
{
db.Event.Remove(event);
db.SaveChanges();
}
}
}
I hope that helps you!

Related

Update table in foreach loop with filtered model with Ajax (asp.net mvc c#)

I've developed an asp.net MVC web app where I have a table that shows some items in a model.
I can filter it now with a dropdown list using ajax
The model that i pass to the table is correct (if i go to the model before the foreach there are 3 rows instead of 10 thanks to the filter)
The problem is that the table doesn't change, it always shows all the rows as the initial request.
It look like it works but the table won't update...
There's my jquery ajax call:
$("#Dropdown1Id").on('change', function () {
//console.log("onchange");
//console.log($("#Dropdown1Id").val());
var drpdown1 = $("#Dropdown1Id").val();
var submit = $("#submitButton");
$.ajax({ // crea una chiamata AJAX
data: { data: drpdown1 }, // prendi i dati del form in questo caso del primo dropdown
type: "GET", // GET o POST
url: "/Select/Filter", // li passa al controller
success: function () { // se va con successo esegue il codice seguente
submit.click();
$("#frmId").submit();
},
error: function (error) {
console.log("error")
}
});
});
There's my controller action:
public ActionResult Filter(string data)
{
List<Card> cards = new List<Card>();
ViewBag.stato = new SelectList(myApi.GetState(), "Name", "Name");
if (data != null && data != "")
{
foreach (var card in model)
{
if (card.IdList == data || data == "")
cards.Add(card);
}
return View(cards);
}
return View(model);
}
There's my view with the daple and the dropdown:
#using (Html.BeginForm(new { id = "frmId"}))
{
#Html.AntiForgeryToken()
<table id="tb2">
<tr>
<th>
<h4> LIST : #Html.DropDownList("stato", null, new { #id = "Dropdown1Id" })</h4>
</th>
#*<th>
<h4>ARCHVIED : #Html.DropDownList("closed", null, new { #id = "Dropdown2Id" })</h4>
</th>*#
<th>
<input type="submit" value="Filter" class="btn btn-info" id="submitButton" />
</th>
</tr>
</table>
<br />
<div id="risultato"></div>
<table class="table" id="tb1">
<tr>
<th style="text-align:center">
TRELLO'S CARDS LIST
</th>
<th>LIST</th>
<th>ARCHVIED</th>
<th>Expiration date</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.IdList)
</td>
#if (item.Closed == "True")
{
<td>YES</td>
}
else
{
<td>NO</td>
}
#if (item.Due != null)
{
<td>
#Html.DisplayFor(modelItem => item.Due)
</td>
}
else
{
<td>
Not Present
</td>
}
</tr>
idList.Add(item.Id);
}
</table>
Let me get you through the execution stack and you'll understand why:
Your MVC view is loaded. When the view is returned to the frontend it is already in Html format. Check Server side rendering here
Basically it means that #foreach (var item in Model) will only execute on the server side and will not re-run when you hit an ajax call. This will only happen on a full post.
While in your page you fire up change dropdown event and the following happens:
An ajax call hit your controller
Data are being returned to the success function
Your success: function () is being executed.
A new form post occurs. See that you didn't do anything with the return data that was returned in the success: function(). You just posted back to the controller
After the post, the full view has returned ignoring any changes in the dropdown and in the data returned.
There are 2 solutions for your problem:
Do a full post and return a new view with the proper data
Write some more javascript to change the DOM inside your sucess function

List View / Details View without Entity Framework

I have a MVC view that has a table that contains a list of all users within a specific OU within Active Directory. I am trying to add a column to the table that takes you to a Details view that shows the details of the user (shows additional details) but I am having a hard time figuring out how to do this without using Entity Framework and passing the id of the object to the details view. Any thoughts on how I could accomplish this? Right now when I click on the Details actionlink, I am taken to the Details view but there is no data being passed. Any help would be greatly appreciated!
public ActionResult NonComputerUsers(User model)
{
List<User> user = new List<User>();
using (var context = new PrincipalContext(ContextType.Domain, "XXX", "OU=XXX,DC=XXX,DC=com"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry entry = result.GetUnderlyingObject() as DirectoryEntry;
user.Add(new User()
{
FirstName = (String)entry.Properties["givenName"].Value,
LastName = (String)entry.Properties["sn"].Value,
});
}
}
}
return View(user.ToList());
}
public ActionResult Details(User model)
{
?????????
return View(model);
}
**List View**
#model ADUserManagement.Models.User
<table class="table">
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.ActionLink("Details", "Details", "Users", new { item = item.FirstName })
</td>
</tr>
}
**Details View**
#model ADUserManagement.Models.User
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<table class="table table-bordered table-striped">
<tr>
<td>First Name</td>
<td>#Model.FirstName</td>
</tr>
<tr>
<td>Last Name</td>
<td>#Model.LastName</td>
</tr>
<tr>
<td>SAM Account Name</td>
<td>#Model.SamAccountName</td>
</tr>
There are a couple ways to do this. One of which is the way you are already doing it. You can add all the properties you want to display on your details page to your User model. Use that list to build your table, then pass the applicable User object back to your Details view to display the extra details.
That method is good because it saves you having to do a second lookup to AD for your Details view (essentially, your ????????? can be removed - you don't need any code there).
I was going to say that the down side is that, in your search, you're asking for more details for most of the accounts than you'd actually use, but the UserPrincipal objects that PrincipalSearcher returns already pulls in all the AD attributes for each user account anyway. If you used DirectorySearcher directly, you'd have more control of that. But that's probably not a big deal, unless you have performance problems with that search.
The other way to do it, which I think is unnecessary in your current example, is to store some unique identifier from AD (e.g. distinguishedName, sAMAccountName, userPrincipalName, objectGuid, objectSid) and pass just that back to your Details action where you can look up just that account again and get all the details you need for your Details view.

Bootstrap table sorting works inconsistently with LINQ

I have a bootstrap datatable in my view in a MVC application. I use the sorting functionality provided to sort it by a column called CreatedOn and load it on the screen.
<div class="container">
<div class="no-more-tables">
<table id="tblTemplate" class="table table-advance dataTable">
<thead>
<tr>
<th style="display:none">
ID
</th>
<th style="width:14%">
Type
</th>
<th style="width:25.5%;">
Subject
</th>
<th style="width:15%;">
Created By
</th>
<th style="width:15%;">
Created on
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.lstBoxes)
{
<tr>
<td class="text-left" style="display:none">#item.Id</td>
<td class="text-left">#item.Type</td>
<td class="text-left">#item.Subject</td>
<td class="text-left">#item.CreatedBy</td>
<td class="text-left">#item.CreatedOn</td>
</tr>
}
</tbody>
</table>
</div>
</div>
The sorting functionality script on load:
function initialSortCommon(tblName,colNo) {
$("#tblTemplate").dataTable(
{
"bDestroy": true
}
).fnDestroy();
$(document).ready(function () {
$("#tblTemplate").dataTable({
"bDestroy": true,
"aaSorting": [[4, 'desc']],
"oLanguage":
{
"sSearch": "Search all columns:",
},
});
});
}
The issue is the sorting behaves differently when fed a list using SQL Statements and when using Linq
var lstBoxes = new List<Record>();
var con = new SqlConnection(cs);
con.Open();
var command = new SqlCommand("SELECT ID,Type,Subject,CreatedBy,CreatedOn FROM Box", con);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
lstBoxes.Add(new Record { Type = Convert.ToString(reader["Type"]), Id = Convert.ToString(reader["ID"]), Subject = Convert.ToString(reader["Subject"]), CreatedBy = Convert.ToString(reader["CreatedBy"]), CreatedOn = Convert.ToString(reader["CreatedOn"]) });
}
con.Close();
return lstBoxes;
Using Linq:
var lstBoxes = db.Boxs.Select(s => new Record
{ Type = s.Type, Id = s.ID.ToString(), Subject = s.Subject, CreatedBy = s.CreatedBy, CreatedOn = s.CreatedOn.ToString() }).ToList();
return lstEvents;
Even though both tables return same data, the sorting on the Created on works perfectly with SQL Server but not with LINQ. Is this a known issue?
EDIT : Removed the descending by in LINQ to make both code consistent.
EDIT 2 : I checked the results of both lists. There is a difference in the way the date is being retrieved.
For example : In SQL, the field Convert.ToString(reader["CreatedOn"]) is being retrieved as 11/7/2017 9:51:26 AM where as in LINQ CreatedOn = s.CreatedOn.ToString() gives Nov 7 2017 9:51 AM. This might be the cause of the issue. Is there a way the LINQ string be formatted similar to SQL result string?

Sort DateTime object in DD/MM/YYYY format in .cshtml file

I currently have a for-loop in my .cshtml file which iterates through items inside a ViewBag. I want to sort these objects based on a DateTime property called orderDate in the Order.cs file. The for loop in the .cshtml file looks like the following:
<table id="order-history-table" class="table table-hover">
<thead>
<tr>
<th>
Order Number
</th>
<th>
Order Date
</th>
<th>
Order Total
</th>
</tr>
</thead>
<tbody>
#foreach (var item in ViewBag.list)
{
<tr>
<td>
<a class="orderNumber" data-toggle="modal" data-target="#modal-container" href="#Url.Action("orderDetails", "Orders", new { orderNumber = item.order.OrderNumber })">#item.order.OrderNumber</a>
<br />
#Html.ActionLink("Re-Order", "ReOrder", new { orderNumber = #item.order.OrderNumber }, new { onclick = "return confirm('Are you sure you wish to re-order?');" })
</td>
<td>#item.order.OrderDate.ToString("dd/MM/yyyy")</td>
<td style="text-align: center">$#(Math.Round(item.order.OrderTotal, 2))</td>
</tr>
}
</tbody>
I want this table to be sorted so that the most recent orders are shown at the top of the table. Since the data is being pulled from a database, and the tables values are generated dynamically, where do I perform this sorting? is it done through jQuery? How do I do this?
Thank you in advance
You can use LINQ OrderBy to do that.
So in your action method where you set the ViewBag.list, You can use OrderByDescending method on the collection.
var yourOrderList=new List<Order>();
// to do : Load Order items to yourOrderList
yourOrderList=yourOrderList.OrderByDescending(f=>f.OrderDate).ToList();
ViewBAg.list=yourOrderList;
I also recommend using a view model to pass data from your action method to view.
var yourOrderList=new List<Order>();
// to do : Add orders to yourOrderList
yourOrderList=yourOrderList.OrderByDescending(f=>f.OrderDate).ToList();
return View(yourOrderList);
And in your view
#model List<Order>
<h3>Orders</h3>
#foreach(var o in Model)
{
<p>#o.OrderDate.ToString()</p>
}
Since your view is strongly typed, you can do the same ordering in your razor view also as needed.
#model List<Order>
<h3>Orders</h3>
#foreach(var o in Model.OrderByDescending(g=>g.OrderDate))
{
<p>#o.OrderDate.ToString()</p>
}

Updating Multiple Records in one view; "Not all code paths return a value" error

I'm really new to programming and stuck on a problem.
I'm trying to edit and update multiple rows of a database in one view, using mvc and asp.net.
I think I'm somewhere along the right tracks but keep getting an error saying "not all code paths return a value".
My Conroller looks like this:
[HttpGet]
public ViewResult AnotherListEdit()
{
var chosenClass = from c in db.ClassInstanceDetails.Include("ClassInstance").Include("Student")
where c.ClassInstance.ID == 1
select c;
return View(chosenClass.ToList());
}
[HttpPost]
public ActionResult AnotherListEdit(IList<ClassInstanceDetail> list)
{
if (ModelState.IsValid)
{
foreach (ClassInstanceDetail editedClassInstanceDetail in list)
{
var tempBook = (from classInstDet in db.ClassInstanceDetails
where (teacher.ClassInstanceID == editedClassInstanceDetail.ClassInstanceID)
&& (classInstDet.StudentID == editedClassInstanceDetail.StudentID)
select teacher).First();
db.ApplyCurrentValues(tempBook.EntityKey.EntitySetName, editedClassInstanceDetail);
}
db.SaveChanges();
return View(db.Teachers.ToList());
}
}
My View looks like this:
#model IList<FYPSchoolApp.DAL.ClassInstanceDetail>
#{
ViewBag.Title = "AnotherListEdit";
}
#using (Html.BeginForm())
{
<table>
<tr>
<th>
Name
</th>
<th>
Second Name
</th>
<th>
attendance
</th>
<th>
Comment
</th>
</tr>
#for (var i = 0; i < Model.Count(); i++) {
<tr>
<td>
#Html.DisplayFor(m => Model[i].StudentID)
</td>
<td>
#Html.DisplayFor(m => Model[i].Attendance)
#Html.EditorFor(m => Model[i].Attendance)
</td>
<td>
#Html.DisplayFor(m => Model[i].CommentNote)
#Html.EditorFor(m => Model[i].CommentNote)
</td>
</tr>
}
</table>
<input type="submit" value="save" />
}
The "not all code paths return a value error" is being highlighted with AnotherListEdit function, the second one thats after HttpPost. If I run the project without that whole function, the display works, and the correct information is passed to the display.
Any help would be very much appreciated!!
What should happen in the AnotherListEdit method if the modelstate is invalid? That is what is missing ... The action does not return a "ActionResult" if the modelstate is invalid
[HttpPost]
public ActionResult AnotherListEdit(IList<ClassInstanceDetail> list)
{
if (ModelState.IsValid)
{
foreach (ClassInstanceDetail editedClassInstanceDetail in list)
{
var tempBook = (from teacher in db.ClassInstanceDetails
where (teacher.ClassInstanceID == editedClassInstanceDetail.ClassInstanceID)
&& (teacher.StudentID == editedClassInstanceDetail.StudentID)
select teacher).First();
db.ApplyCurrentValues(tempBook.EntityKey.EntitySetName, editedClassInstanceDetail);
}
db.SaveChanges();
return View(db.Teachers.ToList());
}
//HERE!!What view should return? any error messages?
return View("View with no valid modelstate?");
//Maybe?
//return RedirectToAction("AnotherListEdit");
}
if (ModelState.IsValid)
{ //you return something here }
but if the modelstate is not valid, nothing is returned. The error must come from there

Categories