I am trying to pass an item with the type "EmployeeDocument" to my action but all of values are coming back as nulls and I am not sure why. I have tried passing the entire model as well as just pieces and they are all null and I am not sure why this is happening.
Here is what my view looks like:
<table id="results-table" class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>
<u>#Html.DisplayName("Title")</u>
</th>
<th>
<u>#Html.DisplayName("Document Type")</u>
</th>
<th>
<u>#Html.DisplayName("Created By")</u>
</th>
<th>
<u>#Html.DisplayName("Created Date")</u>
</th>
<th style="width: 180px;"></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.DocumentType)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedDate)
</td>
<td>View | #Html.ActionLink("Replace", "ReplaceEmployeeDocument", "Employee",new {title = item.Title, doctype = item.DocumentType, createdDate = item.CreatedDate,createdBy = item.CreatedBy, fullUrl = item.FullUrl}) | #Html.ActionLink("Delete", "DeleteEmployeeDocument",new {fileName = item.FullUrl, employeeNo = item.EmployeeNumber})</td>
</tr>
}
</tbody>
</table>
I am focusing on the replace action link in the table.
This is what my action looks like:
[HttpGet]
public ActionResult ReplaceEmployeeDocument(string title, string doctype, DateTime createdDate, string createdBy, string fullUrl)
{
var doc = new EmployeeDocument();
return PartialView(doc);
}
All of the parameters in the action are null. Is there a reason why these are like that?
You are trying to post back a collection of objects, in order for this to work you need to use a for loop and index the properties with hidden inputs as follows:
#using (Html.BeginForm("ReplaceEmployeeDocument", "Controller"))
{
#for(var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.HiddenFor(m => m[i].Title)
#Html.DisplayFor(m => m[i].Title)
</td>
<td>
#Html.HiddenFor(m => m[i].DocumentType)
#Html.DisplayFor(m => m[i].DocumentType)
</td>
<td>
#Html.HiddenFor(m => m[i].CreatedBy)
#Html.DisplayFor(m => m[i].CreatedBy)
</td>
<td>
#Html.HiddenFor(m => m[i].CreatedDate)
#Html.DisplayFor(m => m[i].CreatedDate)
</td>
<td>View | <input type="submit" value="Replace"/></td>
</tr>
}
}
You also need a corresponding post method that accepts the model being passed back:
[HttpPost]
public ActionResult ReplaceEmployeeDocument(EmployeeDocument model)
{
var doc = new EmployeeDocument();
return PartialView(doc);
}
You dont seem to be using any #Html.EditorFor which would generate input fields, and you dont have any form or javascript that would send your arguments in either GET or POST method. Therefore none of your fields are sent to the method in the controller. You should wrape the code inside the foreach in a
#Html.BeginForm() {}
Related
Hello I'm new to MVC and I'm trying to do a filtering for my index page, I want to be able to filter the graduation Status.
So when I go into the index I will see every status and I want to filter for example only the person with the graduated Status or the Pass/failed Status
Thank you in advance!
Index Page
Controller:
var graduates = db.Graduated_Students;
return View(graduates.ToList());
View:
<div class="content-body">
<div class="row">
<form action="#" method="post">
<div class="col-xs-12 col-sm-9 col-md-12">
<table class="table">
<tr>
<th>
#Resource.FirstName
</th>
<th>
#Resource.LastName
</th>
<th>
#Resource.CohortNumber
</th>
<th>
Placements
</th>
<th>
#Resource.GraduationStatus
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem =>
item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem =>
item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem =>
item.PartnerName)
</td>
<td>
#Html.DisplayFor(modelItem =>
item.GraduationStatus)
</td>
You could use linq in the View to filter the data
In the View
#foreach (var item in Model.Where(t=> t.GraduationStatus == <the graduation status selected in the dropdown> );
This approach Gets all the data from the database and then performs the filtering
That approach would work however a better approach would be to send the Selected GraduationStatus to the controller as a parameter and then perform the filtering directly on the db variable
In the Controller
public IActionResult GeStudents(GraduationStatus selectedGraduationStatus)
{
var graduates = db.Graduated_Students.Where(t=> t.GraduationStatus == selectedGraduationStatus);
return View(graduates.ToList());
}
This way you don't get all of the students from the database but only the ones which match the filter
Is it possible to add a where clause in the view rather than the controller as I don't want to change the retrieval of information in the controller. I currently am retrieving a list of restaurants but want to only show restaurants where the logged in users email is the same as the restaurants email.
<div class="col-xs-12">
<table class="table table-condensed table-striped">
<tr>
<th>
#Html.DisplayNameFor(model => model.Rating)
</th>
<th>
#Html.DisplayNameFor(model => model.RestaurantName)
</th>
<th>
#Html.DisplayNameFor(model => model.County)
</th>
<th>
#Html.DisplayNameFor(model => model.RestaurantType)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Rating)
</td>
<td>
#Html.DisplayFor(modelItem => item.RestaurantName)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
<td>
#Html.DisplayFor(modelItem => item.RestaurantType)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.RestaurantID }) |
#Html.ActionLink("Details", "Details", new { id = item.RestaurantID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.RestaurantID })
</td>
</tr>
}
</table>
</div>
If you really don't want to change the logic for retrieving the list, you could use a ViewModel with a List property, returning the specified list using the Getter.
public List<Restaurant> MyRestaurants
{
get { return Restaurants.Where(x => x.RestaurantEmail == UserEmail); }
}
This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 6 years ago.
Why i can't pass this model to a controller in ASP.NET MVC?
This is my View:
#model Pro.WebUI.ViewModels.DataItemVm
<div>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstSetList.FirstOrDefault().Name)
</th>
<th>
#Html.DisplayNameFor(model => model.FirstSetList.FirstOrDefault().Amount)
</th>
</tr>
#foreach (var item in Model.FirstSetList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.TextBoxFor(modelItem => item.Amount)
</td>
</tr>
}
</table>
<hr/>
<div>
#using (Html.BeginForm())
{
#Html.HiddenFor(model => model.FirstSetList)
<input type="submit" value="Confirm"/>
}
</div>
</div>
After I click Confirm button - this method receives model with Count = 0;
public ActionResult FirstSet(DataItemVm model)
{
...
}
Of course my ViewModel DataItemVm has list:
public class DataItemVm
{
public List<FirstSetViewModel> FirstSetList { get; set; }
}
So it looks like that problem is only at view. Maybe BeginForm should be in other place? However HiddenFor should send be enough to send this model.
Change #foreach cycle to for - ASP.NET MVC uses indexers to generate correct ids and names for elements, so you should use #Html.TextBoxFor(x=>x.Array[index]) to correctly generate html for your collections.
This cycle:
#foreach (var item in Model.FirstSetList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.TextBoxFor(modelItem => item.Amount)
</td>
</tr>
}
Should instead look like this:
#for (var i = 0; i < Model.FirstSetList.Length; i++)
{
<tr>
<td>
#Html.DisplayFor(model => model.FirstSetList[i].Name)
#Html.HiddenFor(model => model.FirstSetList[i].Name) //otherwise name won't be returned to controller
</td>
<td>
#Html.TextBoxFor(model=> model.FirstSetList[i].Amount)
</td>
</tr>
}
Another issue is - markup for the data that you want to be sent to the controller should be put inside #using (Html.BeginForm()){//put it here} block.
Check out this post about model binding in ASP.NET MVC:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
I'm trying to retrieve data in a specific order (to establish a ranking) with the below code:
public ActionResult ShowRanking(int id = 0)
{
Tournament tournament = db.Tournament.Find(id);
var parti = (from p in db.Participe
where p.IdTournament == tournament.IdTournament
//orderby p.ArchTotalScore descending
select p).OrderByDescending(x => x.ArchTotalScore);
//objlist = parti;
foreach (var part in parti)
{
tournament.Participe.Add(part);
//objlist.Add(part);
}
tournament.Participe.OrderByDescending(x => x.ArchTotalScore);
return View(tournament.Participe);
}
The data is retrieved but whenever I pass the list ofdata to my view, the order criterias I used are ignored and the records are shown as they have been inserted in the DB.
Here is my view as well:
#model ArcheryComp.Tournament
#{
ViewBag.Title = "Classement";
}
<h2>Classement</h2>
<table>
<tr>
<th>
Nom
</th>
<th>
Prenom
</th>
<th>
Division
</th>
<th>
Categorie
</th>
<th>
Score 1
</th>
<th>
Score 2
</th>
<th>
Total Score
</th>
</tr>
#foreach (var item in Model.Participe)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Archers.Nom)
</td>
<td>
#Html.DisplayFor(modelItem => item.Archers.Prenom)
</td>
<td>
#Html.DisplayFor(modelItem => item.Divisions.DivDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.Categorie)
</td>
<td>
#Html.DisplayFor(modelItem => item.ArchScore1)
</td>
<td>
#Html.DisplayFor(modelItem => item.ArchScore2)
</td>
<td>
#Html.DisplayFor(modelItem => item.ArchTotalScore)
</td>
<br />
</tr>
var tmp = item.IdTournament;
}
</table>
Do you have any idea what is wrong ? and could I correct this ?
Thanks in advance for your help.
You ordered the tournament.Participe, but you did not use the result. You must change it to something like this(if tournament.Participe is a Listofcourse):
tournament.Participe =
tournament.Participe.OrderByDescending(x => x.ArchTotalScore).ToList();
return View(tournament);
The model used in the view is ArcheryComp.Tournament therefore you must return View(tournament) not View(tournament.Participe).
I'm trying to find a way to send an email to selected recipients based on whether or not their email has been checked. We have a database with the emails in, and I've manually added a checkbox to resultant table. On clicking "Send", I want the email to send to those people based on whether or not they've been checked.
I thought the best way to do this would be to create an ArrayList, and then use message.CC.Add(emailArray), but that gives invalid arguments.
I then tried
string Email = emailArray.ToString()
//and then
message.CC.Add(email)
which didn't give errors, but it only sends to whomever clicks the button, IE myself or another colleague, and doesn't add the CCs. SMTP etc is all correct, as the email will send, just not to the ticked recipients.
ArrayList emailArray = new ArrayList();
if (Request.Form["chkBox"].Equals(true))
{
emailArray.Add(db.tblMailRecipients.Include(t => t.Email));
}
string email = emailArray.ToString();
message.To.Add(email);
smtp.Send(message);
Response.Redirect("~/Home/Index");
The above code shows where I'm trying to get the emails and put it into the Arraylist.
Is it to do with how I'm getting the checkbox value and then relating (or not?) that to the row in the table?
We're using ASP.NET MVC with C#.
Any help would be appreciated :).
Thanks
Update
The following code is for the page listing recipients with the checkboxes:
#using (Html.BeginForm("SendEmail", "BulkMail", FormMethod.Post))
{
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.Company)
</th>
<th>
#Html.DisplayNameFor(model => model.LastEmailDate)
</th>
<th>
Check
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Company)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastEmailDate)
</td>
<td>
<input id="chkBox" name="chkBox" type="checkbox" />
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.MailRecipientId }) |
#Html.ActionLink("Details", "Details", new { id=item.MailRecipientId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.MailRecipientId })
</td>
</tr>
}
</table>
<input type="submit" value="Submit" />
}
The message is hardcoded in the send mail function at the moment.
You have:
<input id="chkBox" name="chkBox" type="checkbox" />
Inside a foreach loop, which will repeat the id="chkBox", generating invalid HTML.
What you should do is create a Property in your Model. e.g.
public bool isChecked {get;set;}
Then display your Model using forloop: MVC Model binder requires the fields to be in the form: [0].PropertyName
#for(var i =0; i < Model.Count(); i++) {
<tr>
<td>
#Html.DisplayFor(m => m[i].LastName)
</td>
...... Removed HTML
<td>
#Html.CheckBoxFor(m => m[i].isChecked)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=Model[i].MailRecipientId }) |
..... Removed HTML
</td>
</tr>
}
When you Submit the Form:
[HttpPost]
public ActionResult SendEmail(List<CLASS_NAME> model)
{
var emails = model.Where(s => s.isChecked).Select(s => s.Email).ToArray();
............/////
}
Apologies for the lack of interaction with this thread, had other stuff come up which was urgently needed. Firstly, thanks for all your help. I had a look today and came up with the following solution:
Add
<input type="checkbox" name="chkBox" value="#item.Email" />
into the view where emails etc can be selected. I then added:
message.Bcc.Add(Request.Form["chkBox"])
To the controller for the SMTP etc, and it seems to work pretty well :).
Thanks