Pass IEnumerable<SomeModel> and SomeModel to View - asp.net-mvc

I'm using:
#model IEnumerable<SomeModel1>
in my view. I cannot change that because multiple controllers in our application are returning some variable with the type:
List<SomeModel1>
I also need to pass the same model (SomeModel1) without the IEnumerable for a modal window:
#model WebApplication8.Models.ManageUserViewModel
Is there a way that I can achieve that without putting the models into a parent model?
UPDATE:
View Page:
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
Active
</th>
<th class="text-center">
Email Address
</th>
<th class="text-center">
First name
</th>
<th class="text-center">
Last Name
</th>
<th class="text-center">
Company
</th>
<th class="text-center">
permissions
</th>
<th class="text-center">
Machine<p>Limit</p>
</th>
<th class="text-center">
Machines<p>Consumed</p>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td style="display:none" >#Html.DisplayFor(model => item.UserId)</td>
<td align="center">
<div class="btn-group btn-toggle">
#if (item.ActiveUser)
{
<button class="btn btn-sm btn-success active">ON</button>
<button class="btn btn-sm btn" onclick="DeActivateUser('#item.UserId')">OFF</button>
}
else
{
<button class="btn btn-sm btn" onclick="ActivateUser('#item.UserId')">ON</button>
<button class="btn btn-sm btn-success active">OFF</button>
}
</div>
</td>
<td>#Html.DisplayFor(model => item.EmailAddress)</td>
<td>#Html.DisplayFor(model => item.FirstName)</td>
<td>#Html.DisplayFor(model => item.LastName)</td>
<td>#Html.DisplayFor(model => item.Company)</td>
<td>
#Html.DisplayFor(model => item.UserPermission)
<b class="dropdown-menu"></b>
<ul class="dropdown-menu">
<li><a onclick="ChangePermission('#item.UserId', '3')">View Only</a></li>
<li><a onclick="ChangePermission('#item.UserId', '4')">View - Print</a></li>
<li><a onclick="ChangePermission('#item.UserId', '5')">View - One Print</a></li>
<li><a onclick="ChangePermission('#item.UserId', '6')">Expire by Use - 5 Opens</a></li>
<li><a onclick="ChangePermission('#item.UserId', '7')">Expire After 5 Days</a></li>
</ul>
</td>
<td align="center">#Html.DisplayFor(model => item.MachineLimit)</td>
<td align="center">#Html.DisplayFor(model => item.MachineCount)</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<section id="addUser">
#using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h2>Add Authorized User(s): </h2>
<hr style="height:7pt;" />
<!-- <hr style="height:0pt; visibility:hidden;" /> -->
<button class="btn btn-default btn-success btn-lg" data-target="#modalId" data-toggle="modal" type="button">
<span class="glyphicon glyphicon-plus"></span> ADD NEW USER
</button>
<div class="modal fade" id="modalId" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add Authorized User(s)</h4>
</div>
<div class="modal-body">
#Html.ValidationSummary()
<!-- <div class="col-md-4"> -->
<div class="form-group">
#Html.LabelFor(m => m. ().FirstName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().FirstName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().LastName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().LastName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().EmailAddress, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().EmailAddress, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().Company, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().Company, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().UserPermission, new { #class = "col-md-2 control-label" })
<div class="col-md-3 control-label">
#Html.DropDownListFor(m => m.FirstOrDefault().UserPermission, new SelectList(new List<Object>
{
new { value = "2" , text = "View Only"},
new { value = "3" , text = "View - Print" },
new { value = "4" , text = "View - One Print" },
new { value = "5" , text = "Expire by 5 Use" },
new { value = "6" , text = "Expire by 5 Date" }
},
"value", "text", "ViewOnly"))
</div>
#Html.LabelFor(m => m.FirstOrDefault().MachineLimit, new { #class = "col-md-2 control-label" })
<div class="col-md-2 control-label">
#Html.DropDownListFor(m => m.FirstOrDefault().MachineLimit, new SelectList(new List<Object>
{
new { value = "1" , text = "1"},
new { value = "2" , text = "2" },
new { value = "3" , text = "3" },
new { value = "4" , text = "4" },
new { value = "5" , text = "5" }
},
"value", "text", 1))
</div>
</div>
</div>
<div class="modal-footer">
<div class="col-md-3 col-md-10 control-label">
<input type="submit" class="btn btn-default" value="Select/Add" name="Action:Insert" />
</div>
</div>
</div>
</div>
</div>
}
</section>

Passing multiple types into a single view is not really recommended and probably means you are misusing the view in some way. You have 3 options:
Distinct Views
Change what you are doing and make a view for each type.
dynamic Type
Use dynamic as your model type, but this means your view code is littered with if statements - not a good design.
Wrap in a List
Wrap the SomeModel object in a List like this:
SomeModel myModel;
return View(new List<SomeModel> { myModel };

In the case where you have to use SomeModel1,
you can use #Model.firstordefault().{class properties} by keeping IEnumerable declaration above.

Use ViewBag.
// controller
ViewBag.SomeModel = someModel;
// view
#ViewBag.SomeModel.SomeProperty

Related

How to reference a view model property in Asp.Net MVC - Razor view

In my razor view, in the "Panel area - to hold the comment button", I am trying to referencing the view models property BlogPublishedByBlogId.BlogId but I get - "the name BlogPublishedByBlogId does not exist in the current context".
However, I am able to reference the other properties fine using Lamda: model => model.BlogPublishedByBlogId.CreatedDateTime
How do I reference the 'blogId' in the "Panel area - to hold the comment button" area?
#model GbngWebClient.Models.BlogPublishedByBlogIdVM
<h2 class="page-header"><span class="blogtitle">#Session["BlogTitle"]</span></h2>
#{
Layout = "~/Views/Shared/_LayoutUser.cshtml";
}
#if (Model != null)
{
<div class="panel panel-default toppanel">
<div class="panel-body">
<div class="row">
<div class="col-md-2">
#Html.LabelFor(model => model.BlogPublishedByBlogId.CreatedDateTime)
#Html.TextBoxFor(model => model.BlogPublishedByBlogId.CreatedDateTime, new { #class = "form-control", #disabled = "disabled" })
</div>
<div class="col-md-2">
#Html.LabelFor(model => model.BlogPublishedByBlogId.ModifiedDateTime)
#Html.TextBoxFor(model => model.BlogPublishedByBlogId.ModifiedDateTime, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<br />
<div class="row">
<div>
#Html.TextAreaFor(model => model.BlogPublishedByBlogId.BlogContent, new { #class = "form-control blogContent", #disabled = "disabled" })
</div>
</div>
</div>
#* Panel area - to hold the comment button. *#
<div class="panel-footer">
<button type="button" class="btn btn-default Comment" data-id="BlogPublishedByBlogId.BlogId" value="Comment">
<span class="glyphicon glyphicon-comment" aria-hidden="true"></span> Get Comment(s)
</button>
</div>
<div id="#string.Format("{0}_{1}","commentsBlock", BlogPublishedByBlogId.BlogId)" style="border: 1px solid #f1eaea; background-color: #eaf2ff;">
<div class="AddCommentArea" style="margin-left: 30%; margin-bottom: 5px; margin-top: 8px;">
<input type="text" id="#string.Format("{0}_{1}", "comment", BlogPublishedByBlogId.BlogId)" class="form-control" placeholder="Add a Comment about the blog..." style="display: inline;" />
<button type="button" class="btn btn-default addComment" data-id="BlogPublishedByBlogId.BlogId"><span class="glyphicon glyphicon-comment" aria-hidden="true"></span></button>
</div>
</div>
</div>
}
The view model:
namespace GbngWebClient.Models
{
public class BlogPublishedByBlogIdVM
{
public BlogPublishedByBlogIdVM()
{
this.BlogPublishedByBlogId = new BlogPublishedByBlogId();
}
public BlogPublishedByBlogId BlogPublishedByBlogId { get; set; }
}
}
I added #Model to the front of:
BlogPublishedByBlogId.BlogId.

Calling a Partialview with table on the main view

I'm trying to call a partial view with details table for some items. However, the partial view does not show any record in the main view. How I can call the Patrial view successfully? the partial view as follows:
#model IDECOHealthInsurance.Models.Pharmacy
#using (Html.BeginForm("pharmacyDetials", "Pharmacy"))
{
<h4>تفاصيل الصيدلية</h4>
<div id="dvPatientNotice" class="MainGridContainer pb-5">
#if (Model.dtItemsDetails != null)
{
<table dir="rtl" id="Paitents" class="MainGrid">
<thead>
<tr style="text-size-adjust:auto">
<th>
رقم الموظف
</th>
<th>
التاريخ
</th>
<th>
الوقت
</th>
<th>
المستفيدون
</th>
<th>
ملاحظات
</th>
<th>
الباركورد
</th>
<th>
أسم العينة
</th>
<th>
الكمية
</th>
<th>
السعر
</th>
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.dtItemsDetails.Rows)
{
<tr style="width:100%">
<td>
#row["EMPLOYEE_NUMBER"]
</td>
<td>
#row["ENTRY_DATE"]
</td>
<td>
#row["ENTRY_TIME"]
</td>
<td>
#row["BENEFICIARIES"]
</td>
<td>
#row["NOTE"]
</td>
<td>
#row["ITEM_CODE"]
</td>
<td>
#row["ITEM_NAME"]
</td>
<td>
#row["QTY"]
</td>
<td>
#row["PRICE"]
</td>
</tr>
}
</tbody>
</table>
}
</div>
}
The controller as follows:
[HttpGet]
public ActionResult pharmacyDetials(Pharmacy model)
{
var masterID = Convert.ToInt32(Session["login"]);
if (masterID == 0)
{
return RedirectToAction("Login");
}
else
{
Models.Pharmacy objPharamcyMode = new Pharmacy();
IDECOServiceReference.IdecoAPIServiceClient idecoAPI = new IDECOServiceReference.IdecoAPIServiceClient();
DataTable dataTable = idecoAPI.GETPHARMACYEMPLOYEEMASTER("", 1);
model.dtItemsDetails = dataTable;
return PartialView("_PharmacyDetails", model);
}
}
And the Main view as follows:
#model IDECOHealthInsurance.Models.Pharmacy
#{
ViewBag.Title = "PharmacyApplication";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table style="height:680px; width:1280px; border:hidden">
<tr>
<td>
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
</td>
<td>
#using (Ajax.BeginForm("PharmacyApplication", "Pharmacy", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "updatePnl", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, LoadingElementId = "Loading", OnBegin = "" }))
{
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.PHARMACY_NAME, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.PHARMACY_NAME)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EMPLOYEE_NUMBER, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EMPLOYEE_NUMBER, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EMPLOYEE_NUMBER, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTRY_DATE, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.ENTRY_DATE, new { htmlAttributes = new { #class = "form-control", #Value = DateTime.Today.ToString("dd/MM/yyyy"), #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTRY_TIME, new { htmlAttributes = new { #class = "form-control", #Value = DateTime.Today.ToString("HH:mm:ss"), #readonly = "readonly" } })
<div class="col-md-10">
#Html.DisplayFor(model => model.ENTRY_TIME)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BENEFICIARIES, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
زوجة #Html.RadioButtonFor(m => m.BENEFICIARIES, 1)
أبن #Html.RadioButtonFor(m => m.BENEFICIARIES, 2)
أبنة #Html.RadioButtonFor(m => m.BENEFICIARIES, 3)
الموظف #Html.RadioButtonFor(m => m.BENEFICIARIES, 4)
#Html.ValidationMessageFor(model => model.BENEFICIARIES, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Note, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<textarea name="NOTE" id="comments" style="font-family:'Times New Roman';font-size:1.2em; width: 280px; height:auto" placeholder="أكتب ملاحظاتك هنا"></textarea>
#Html.ValidationMessageFor(model => model.Note, "", new { #class = "text-danger" })
</div>
</div>
<div id="showPnl">
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="#("window.location.href='" + #Url.Action("pharmacyDetials", "Pharmacy") + "'");" />
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="panel" value="أضافة" class="btn btn-default" />
</div>
<input class="btn btn-default" type="button" value="خروج" onclick="#("window.location.href='" + #Url.Action("LogOut", "Pharmacy") + "'");" />
</div>
</div>
}
</td>
</tr>
</table>
<div id="updatePnl">
#Html.Partial("_PartialPharmacyDetails", Model)
</div>
<br />
<br />
<br />
<div id="pnlItemsDetails">
#Html.Partial("_PartialItemsDetails", Model)
</div>
When I click on the pharmacy details (in Arabic) = "تفصيل الصيدلية" button it redirects me to another page which contains the desired table that I want to show in the main view. However, I don't want this to happen I want to show the table without clicking on the button. Could you explain why this problem happened?
The Result at the run time appears as follows:
Result of the application at run time
If you want to prevent your page from redirecting, you've to use an ajax request. Replace below line :
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="#("window.location.href='" + #Url.Action("pharmacyDetials", "Pharmacy") + "'");" />
with :
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="getPharmacyDetails();" />
and in your javascript section, add below code :
function getPharmacyDetails()
{
$.ajax({
url : '#Url.Content("~/Pharmacy/pharmacyDetials")',
type: "GET",
success: function (result) {
$("#pDetail").html(result);
}
});
}
Also, replace below HTML :
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
With :
<div id="pDetail"></div>
The above ajax request will execute the partial view and fill the pDetial div with the required result. Try it and Let me know if you've any query.

Change modal form depending on the button clicked

I have a table showing the information of the users, with an edit button for each one.
I want to show a modal form with the details for the user I want to edit, but I don't know how to get the details from the list, and passing them to the modal as a model.
Here is my View:
#model MyApp.Models.User
#{
ViewBag.Title = "Users";
var roles = new List<string> { "Manager", "Admin" };
var userRoles = (List<string>)ViewData["userRoles"];
}
<h2>#ViewBag.Title</h2>
#if (userRoles.Any(u => roles.Contains(u)))
{
using (Html.BeginForm("Update", "Admin", FormMethod.Post, new { id = "update-form", value = "" }))
{
<div class="modal fade" id="user-editor" >
<div class="modal-header">
<a class="close" data-dismiss="modal"><h3>×</h3></a>
<h3 id="modal-title">Edit User</h3>
</div>
<div class="modal-body">
<div class="form-group">
#Html.Label("Name", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.Label("Age", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Age, new { #class = "form-control" })
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn" data-dismiss="modal">Close</a>
<input type="submit" class="btn btn-primary" value="Save Changes" />
</div>
</div>
}
}
<table class="table-bordered table-hover" id="tbusers">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
#if (userRoles.Any(u => roles.Contains(u)))
{
<th>Edit</th>
}
</tr>
</thead>
<tbody>
#foreach (var u in users)
{
<tr id="#u.Id">
<td>#u.Name</td>
<td>#u.Age</td>
#if (userRoles.Any(u => roles.Contains(u)))
{
<td><a type="button" class="btn edit-btn" href="#user-editor" data-toggle="modal">Edit</a></td>
}
</tr>
}
</tbody>
</table>
I've created a testing sample which will help you understand how can you achieve this.
Index.cshtml which will show a list of employees
#model IEnumerable<MvcApplication1.Models.Employee>
#using MvcApplication1.Models;
<h2>Index</h2>
<table>
#foreach (Employee item in Model)
{
<tr>
<td>#Html.ActionLink(#item.EmployeeName, "Name", new { id = item.ID })</td>
<td>
<button type="button" data-id='#item.ID' class="anchorDetail btn btn-info btn-sm" data-toggle="modal"
data-target="#myModal">
Open Large Modal</button></td>
</tr>
}
</table>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
At the same page, reference the following scripts
<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
JQuery AJAX call for getting/setting the data of individual employee from ActionMethod at the same page
<script>
$(document).ready(function () {
var TeamDetailPostBackURL = '/Employee/Details';
$(document).on('click', '.anchorDetail', function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: TeamDetailPostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
datatype: "json",
success: function (data) {
debugger;
$('.modal-body').html(data);
$('#myModal').modal(options);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
});
$("#closbtn").click(function () {
$('#myModal').modal('hide');
});
});
Now Create a class of Employee(because i'm not using EF)
public class Employee
{
public int ID { get; set; }
public string EmployeeName { get; set; }
}
Create controller named Employee and 2 ActionMethods like these:
public ActionResult Index()
{
return View(emp);//sends a List of employees to Index View
}
public ActionResult Details(int Id)
{
return PartialView("Details",
emp.Where(x=>x.ID==Convert.ToInt32(Id)).FirstOrDefault());
}
I'm returning PartialView because I need to load a page within a page.
Details.cshtml
#model MvcApplication1.Models.Employee
<fieldset>
<legend>Employee</legend>
<div class="display-label">
#Html.DisplayNameFor(model => model.ID)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.ID)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.EmployeeName)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.EmployeeName)
</div>
</fieldset>
<p>#Html.ActionLink("Back to List", "Index")</p>
When you execute and visit the Index page of Employee, you'll see screen like this:
And the Modal Dialog with results will be shown like this:
Note: You need to add reference of jquery and Bootstrap and you can further design/customize it according to your needs
Hope it helps!

Using Bootstrap Modal how to Render

I've got a big problem. I just want to have my Create - View for new VacationRequests in my Index-View
It's not possible for me to have two different models in one view.
#*#model System.Collections.Generic.IEnumerable<AppEule.Models.VacationRequest>*#
#model System.Collections.Generic.IEnumerable<GUIManagement.EmployeeVacationRequestViewItem>
#using System.Collections
#using System.Collections.Generic
#using AppEule.Models
#using TestAjax.Helpers
<h2>
#{ViewBag.Title = "Urlaubsanträge";}
</h2>
#*<p>
#Html.ActionLink("Create New", "Create")
</p>*#
<div class="table-responsive">
<table id="mytable" class="table table-bordred table-striped">
<thead>
<th>Zeitraum</th>
<th>Urlaubstage</th>
<th>Vertreter</th>
<th>Status</th>
<th></th>
<th></th>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td class="col-md-4">
#Html.DisplayFor(modelItem => item.VacationStartDateViewString) - #Html.DisplayFor(modelItem => item.VacationEndDateViewString)
</td>
<td class ="col-md-1">
#Html.DisplayFor(modelItem => item.NetVacationDaysViewString)
</td>
<td class="col-md-3">
#Html.DisplayFor(modelItem => item.ShiftPartnerFullName)
</td>
<td class="col-md-2">
#Html.DisplayFor(modelItem => item.VacationRequestProcessingStateViewString)
</td>
<td class="col-md-1">
#Html.NoEncodeActionLink("<span class='fa fa-info'></span>", "Details aneigen", "Details", "VacationRequests", routeValues: new { id = item.VacationRequestID }, htmlAttributes: new { #class = "btn btn-primary btn_small btn-sm" })
</td>
<td class="col-md-1">
#Html.NoEncodeActionLink("<span class='fa fa-ban'></span>", "Urlaubsantrag stornieren", "Delete", "VacationRequests", routeValues: new { id = item.VacationRequestID }, htmlAttributes: new { #class = "btn btn-danger btn_small btn-sm" })
</td>
</tr>
}
</tbody>
</table>
#Html.RenderPartial("~/Views/VacationRequests/_CreateVacationRequest.cshtml", VacationManagement.VacationRequest() Vac);
</div>
How can i access or render the partial view?
#Html.RenderPartial("~/Views/VacationRequests/_CreateVacationRequest.cshtml", VacationManagement.VacationRequest() Vac);
This is the partial view.
#using System
#using System.Activities.Expressions
#model VacationManagement.VacationRequest
#{
Layout = null;
}
<div class="modal fade" id="add" tabindex="-1" role="dialog" aria-labelledby="edit" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
<div class="modal-header">
<img src="~/Content/images/logo_dash.png" class="img-responsive center-block" alt="Responsive image">
<h4 class="modal-title custom_align" id="Heading">Urlaubsantrag stellen</h4>
</div>
<div class="modal-body">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#* #Html.AntiForgeryToken()*#
#Html.EditorFor(model => model.EmployeeID, new { htmlAttributes = new { #class = "form-control datepicker" } })
<div class="form-horizontal">
#Html.LabelFor(model => model.VacationStartDate, "Urlaubsbeginn", htmlAttributes: new { #class = "control-label" })
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.VacationStartDate, new { htmlAttributes = new { #class = "form-control datepicker" } })
#Html.ValidationMessageFor(model => model.VacationStartDate, "", new { #class = "text-danger" })
</div>
</div>
#Html.LabelFor(model => model.VacationEndDate, "Urlaubsende", htmlAttributes: new { #class = "control-label" })
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.VacationEndDate, new { htmlAttributes = new { #class = "form-control datepicker" } })
#Html.ValidationMessageFor(model => model.VacationEndDate, "", new { #class = "text-danger" })
</div>
</div>
</div>
<input type="submit" value="Create" class="btn btn-default" />
}
</div>
<div class="modal-footer ">
<button type="submit" value="Create" class="btn btn-success"> Speichern</button>
</div>
</div>
</div>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
You need to pass an instance of VacationManagement.VacationRequest to the partial view. Change this
#Html.RenderPartial("~/Views/VacationRequests/_CreateVacationRequest.cshtml", VacationManagement.VacationRequest() Vac);
to this
#{ Html.RenderPartial("_CreateVacationRequest", new VacationManagement.VacationRequest()); }

MVC 5 - Information in partial view is null after submit

I have a large form and it's becoming too big so I want to start using partial view to keep it cleaner.
Here is a little part of the form that shows the main contact and a list of alternative contacts. The user can add more contacts (the buttons shows a popup to insert new contact) and the user can change the contact from active to inactive (through the checkbox on the table). Right now this is working but like i said i want to be able to use a partial view for the table.
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Contacts</h3>
</div>
<div class="box-body">
<div class="form-group">
<div class="col-xs-4">
<label>Phone:</label>
#Html.EditorFor(model => model.Persons.Phone, new { htmlAttributes = new { #class = "form-control", #id = "phone" } })
#Html.ValidationMessageFor(model => model.Persons.Phone, "", new { #class = "text-danger" })
</div>
<div class="col-xs-8">
<label>Email:</label>
#Html.EditorFor(model => model.Persons.Email, new { htmlAttributes = new { #id = "email", #class = "form-control", #placeholder = "Introduza o email..." } })
#Html.ValidationMessageFor(model => model.Persons.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<label>Address:</label>
#Html.TextAreaFor(model => model.Persons.Address, new { #class = "form-control", #placeholder = "Introduza a morada...", #rows = 3 })
#Html.ValidationMessageFor(model => model.Persons.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
#if (Model.Contacts != null && Model.Contacts.Count > 0)
{
<table id="example2" class="table table-bordered table-hover dataTable" aria-describedby="example2_info">
<thead>
<tr role="row">
<th class="sorting_asc" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending">Contact</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Contact Type</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Active</th>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
#{
string cssClass = string.Empty;
string activo = string.Empty;
}
#for (var i = 0; i < Model.Contacts.Count; i++)
{
cssClass = i % 2 == 0 ? "even" : "odd";
<tr class="´#cssClass">
<td class=" ">#Html.DisplayFor(model => Model.Contacts[i].Contact)</td>
<td class=" ">#Html.DisplayFor(model => Model.Contacts[i].contacttypes.Name)</td>
<td class=" ">#Html.CheckBoxFor(model => Model.Contacts[i].IsActive, new { #class = "flat-green" })</td>
</tr>
#Html.HiddenFor(model => Model.Contacts[i].ContactsId)
}
</tbody>
</table>
}
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<input type="button" value="Add New Contact" class="buttonCreate btn btn-primary btn-sm" />
</div>
</div>
</div>
So here is the same HTML using the partial view
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Contacts</h3>
</div>
<div class="box-body">
<div class="form-group">
<div class="col-xs-4">
<label>Phone:</label>
#Html.EditorFor(model => model.Persons.Phone, new { htmlAttributes = new { #class = "form-control", #id = "phone" } })
#Html.ValidationMessageFor(model => model.Persons.Phone, "", new { #class = "text-danger" })
</div>
<div class="col-xs-8">
<label>Email:</label>
#Html.EditorFor(model => model.Persons.Email, new { htmlAttributes = new { #id = "email", #class = "form-control", #placeholder = "Introduza o email..." } })
#Html.ValidationMessageFor(model => model.Persons.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<label>Address:</label>
#Html.TextAreaFor(model => model.Persons.Address, new { #class = "form-control", #placeholder = "Introduza a morada...", #rows = 3 })
#Html.ValidationMessageFor(model => model.Persons.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
#Html.Partial("ContactListControl", Model.Contacts)
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<input type="button" value="Add New Contact" class="buttonCreate btn btn-primary btn-sm" />
</div>
</div>
</div>
and here is the Partial view:
#model List<RecruitmentWeb.Models.contacts>
<table id="example2" class="table table-bordered table-hover dataTable" aria-describedby="example2_info">
<thead>
<tr role="row">
<th class="sorting_asc" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending">Contato</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Tipo de Contato</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Activo</th>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
#{
string cssClass = string.Empty;
string activo = string.Empty;
}
#for (var i = 0; i < Model.Count; i++)
{
cssClass = i % 2 == 0 ? "even" : "odd";
<tr class="´#cssClass">
<td class=" ">#Html.DisplayFor(model => Model[i].Contact)</td>
<td class=" ">#Html.DisplayFor(model => Model[i].contacttypes.Name)</td>
<td class=" ">#Html.CheckBoxFor(model => Model[i].IsActive, new { #class = "flat-green" })</td>
</tr>
#Html.HiddenFor(model => Model[i].ContactsId)
}
</tbody>
The Problem
If the user changes a contact from active to inactive or vice-versa, when I submit the form the changes don't go through. In fact, the list is null and contains no information. It works if i don't use partial view.
So what I'm I missing?
You passing only a property of your model to the partial so the the hidden inputs you are generating have the name attribute name="[0].ContactsId", name="[1].ContactsId" etc. whereas they needs to be name="Contacts[0].ContactsId", name="Contacts[1].ContactsId" etc (ditto for the checkboxes).
Change the partial view model to the same as the main view (you haven't indicated what it is), and then pass the model as
#Html.Partial("ContactListControl", Model)
and adjust the Html helpers to suit. However I would recommend you consider using a custom EditorTemplate for RecruitmentWeb.Models.Contacts rather than a partial view for this.

Resources