ViewModel array shows empty value (ASP.Net MVC 5) - asp.net

I am using ASP.Net MVC, I am trying to get values using a ViewModel.
FAQ class have (Name,Description)
FAQ_Detail class is List of Question and Answer which I am passing as PartialView
I have attached front end page and controller page, in controller I can get the Name,Description but always return NULL FAQ_Detail property
View Model
public class FAQViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IList<Details> FAQ_Details { get; set; }
}
public class Details
{
public int Id { get; set; }
public int FAQId { get; set; }
public string Question { get; set; }
public string Answer { get; set; }
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>FAQ</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<br />
<br />
<br />
#for (int i = 0; i <= 2; i++)
{
var m = new FAQ.Models.ViewModels.Details()
{
Id = i,
FAQId = 11,
Question = string.Format("Quesiton {0}",i),
Answer = string.Format("Ans. {0}",i)
};
#Html.Partial("_AddFAQ",m)
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Controller
[HttpPost]
public ActionResult Create(Models.ViewModels.FAQViewModel model) //The model.FAQ_Details array always empty
{
try
{
//
return RedirectToAction("Index");
}
catch
{
return View();
}
}

The problem is you are just displaying the question/answer pair as form fields and there is nothing to bind them to the array in the model you expect. Usually, the name HTML attribute maps the client-side field to the property name of the model on the server.
The better thing you can do is to have some JavaScript, collect the data and pass that through an AJAX call to the server.

I found a solution, I pass master model in controller and use Detail model as collection
public ActionResult Create(string name,string description, ICollection<Models.ViewModels.Details> data)
{
try
{
//
return RedirectToAction("Index");
}
catch
{
return View();
}
}

Related

Subclass is not returned to controller from view

The structure is:
public class SchoolsInformationFooViewModel
{
[Display(Name = "Параметры отчета")]
public Options options { get; set; }
[Display(Name = "Секции строк")]
public IEnumerable<box> boxes { get; set; }
}
public class Options
{
[Display(Name = "Период")]
public DateTime date { get; set; }
}
Controller - send:
// GET: SchoolsInformation
[HttpGet]
public ActionResult Index()
{
Options options = new Options { date = DateTime.Today };
SchoolsInformationFooViewModel model = new SchoolsInformationFooViewModel { options = options };
return View(model);
}
Controller-receipt:
// POST: SchoolsInformation
[HttpPost]
public ActionResult Index([Bind(Include = "date")] Options options)
{
// Here options.date == null
}
View:
<div class="form-group">
#Html.LabelFor(model => model.options.date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.options.date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.options.date, "", new { #class = "text-danger" })
</div>
</div>
Html:
<input class="form-control text-box single-line" data-val="true" data-val-date="Поле Период должно содержать дату." data-val-required="Требуется поле Период." id="options_date" name="options.date" type="datetime" value="23.08.2021 0:00:00">
The date is passed to the view successfully. But an empty class is returned - all properties are empty (null). Why this is so - I cannot understand. I tried adding prefixes to the bind, but in this case, instead of an empty class, the variable contains null
Didn't work because I inserted my control:
using (Html.BeginForm("index", "SchoolsInformation", FormMethod.Post))
{...}

Updating Master-Detail / Parent-Child data in MVC

Have a view with a master-detail style view for an invoice. Master is invoice, detail is invoice lines. I'm trying to get detail data items to save on upon an edit post but the detail data is lost upon reaching the post Edit on the controller. So the master data saves fine but the detail is obviously not saved.
Invoice Class:
public class Invoice
{
public Invoice()
{
}
[Required]
[Key]
public int InvoiceID { get; set; }
[Required]
[StringLength(30)]
[DisplayName("Invoice Number")]
public string InvoiceNumber { get; set; }
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DataType(DataType.Date)]
[Column(TypeName = "Date")]
[DisplayName("Invoice Date")]
public DateTime InvoiceDate { get; set; }
public List<InvoiceLine> InvoiceLines { get; set; }
[ForeignKey("Client")]
public int OwnerClientIDFK { get; set; }
[DisplayName("Client")]
public Client Client { get; set; }
}
Invoice Line class:
public class InvoiceLine
{
public InvoiceLine()
{
}
[Key]
[Required]
public int InvoiceLineId { get; set; }
[Required]
[StringLength(255)]
[DisplayName("Item")]
public string ItemName { get; set; }
[DisplayName("Description")]
public string ItemDescription { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
public decimal Value { get; set; }
[ForeignKey("ParentInvoice")]
public int InvoiceID { get; set; }
public Invoice ParentInvoice { get; set; }
}
Controller Edit (get):
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// Invoice invoice = db.Invoices.Find(id);
Invoice invoice = db.Invoices.Include(i => i.InvoiceLines)
.Include(i => i.Client)
.Where(c => c.InvoiceID == id).FirstOrDefault();
if (invoice == null)
{
return HttpNotFound();
}
ViewBag.OwnerClientIDFK = new SelectList(db.Clients, "ClientId", "CompanyName", invoice.OwnerClientIDFK);
return View(invoice);
}
Controller Edit (post):
public ActionResult Edit([Bind(Include = "InvoiceID,InvoiceNumber,InvoiceDate,OwnerClientIDFK")] Invoice invoice)
{
if (ModelState.IsValid)
{
db.Entry(invoice).State = EntityState.Modified;
foreach (var invLine in invoice.InvoiceLines)
{
db.Entry(invLine).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.OwnerClientIDFK = new SelectList(db.Clients, "ClientId", "CompanyName", invoice.OwnerClientIDFK);
return View(invoice);
}
So in the above, when it reaches the foreach, it throws an exception because InvoiceLines is null.
View:
#model DemoApp.Entities.Invoice
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Invoice</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.InvoiceID)
<div class="form-group">
#Html.LabelFor(model => model.InvoiceNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.InvoiceNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InvoiceNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.InvoiceDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.InvoiceDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InvoiceDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OwnerClientIDFK, "OwnerClientIDFK", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("OwnerClientIDFK", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.OwnerClientIDFK, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<h2>Invoice Lines</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
<div class="col-md-8">
<table class="table">
<thead>
<tr>
<th>Item</th>
<th>Description</th>
<th>Qty</th>
<th>Unit Value</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.InvoiceLines.Count; i++)
{
<tr>
<td>#Html.EditorFor(x => x.InvoiceLines[i].ItemName, new { htmlAttributes = new { #class = "form-control" } })</td>
</tr>
}
</tbody>
</table>
</div>
</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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
How do I get it to update the detail / child data?
Any help appreciated. Thanks in advance.
You are not binding InvoiceLines on edit post action method
public ActionResult Edit([Bind(Include = "InvoiceID,InvoiceNumber,InvoiceDate,OwnerClientIDFK,InvoiceLines")] Invoice invoice)
{
What you probably need is to load the Invoice Lines when you get the parent entity.
db.Entry(invoice).Collection(i=>i.InvoiceLines).Load() should do that.
First off, this is kind of a tricky scenario. There are a lot of moving parts. I got really interested in this and wrote a sample application. :)
Here's the link to the repo on GitHub:
https://github.com/benday/asp-mvc-invoice-sample
There are a handful of things going on that are conspiring to cause problems in your code.
1) ironically, the Bind[] that you have in your Edit(Invoice model) method is getting in your way. If you remove it entirely, ASP MVC will attempt to bind everything. Right now, it's only binding what you tell it to bind and since you don't include the InvoiceLines collection, then it's coming up null.
2) if you want ASP MVC to attempt to bind data into your model, you need to POST that data back to the server. If those invoice lines aren't in an html form and aren't represented as form fields, then that data is just going to be missing.
The code you have to draw your invoice lines is missing most of the fields that would be required to populate your InvoiceLine objects.
#Html.EditorFor(x => x.InvoiceLines[i].ItemName, new {
htmlAttributes = new { #class = "form-control" } })
Editor Template for the InvoiceLine class
In my sample code, I created an editor template for the InvoiceLine class. This allows me to easily create bindable html for the InvoiceLines by calling #Html.EditorFor(model => model.Invoice.InvoiceLines) asdf
I know this isn't the simplest answer ever but I hope this helps you over the hump.

WYSIWYG Text Editor SummerNote Entered data is not persisting

Above is a picture of my edit page. The issue I have is that this editor (summernote) does not persist it's data when I save
**I have however, narrowed down the problem. **
Fields on the form persist the data in the value field on the HTML elements
SummerNote does not store the text I've written into the editor in the value element
If I use the default editor and put a value in (which is stored in the value element), then use summernote, the value in the value field will be there, but not displayed.
Editing this value field in the inspector will then cause the value to be persisted on save.
The line containing the value field:
<input class="form-control text-box single-line" id="Content_Content" name="Content.Content" type="text" value="I am the text that is not shown but would be persisted!" style="display: none;">
The note-editing-area div:
<div class="note-editing-area"><div class="note-handle"><div class="note-control-selection" style="display: none;"><div class="note-control-selection-bg"></div><div class="note-control-holder note-control-nw"></div><div class="note-control-holder note-control-ne"></div><div class="note-control-holder note-control-sw"></div><div class="note-control-sizing note-control-se"></div><div class="note-control-selection-info"></div></div></div><textarea class="note-codable"></textarea><div class="note-editable panel-body" contenteditable="true" style="height: 320px;"><h1>Help!</h1><p>What I type here will not be persisted when i click the <b>save </b>button.</p></div></div>
My question therefore is this:
How can I Either
Have the html between the ::before and ::after of the summernote editor (The value that the user types into the control) be put into the value tag aswell so that it is persisted
Do something else to make it work.
Additional Information:
Here is My Model:
Article.cs:
public class Article
{
#region Constructors
public Article(string title, string subTitle = "")
{
InitializeCollections();
Title = title;
SubTitle = subTitle;
}
public Article(string title, Article parentArticle, string subTitle = "")
{
InitializeCollections();
Title = title;
SubTitle = subTitle;
ParentArticles.Add(parentArticle);
}
public Article()
{
InitializeCollections();
}
void InitializeCollections()
{
ParentArticles = new List<Article>();
ChildArticles = new List<Article>();
}
#endregion
[Key]
public int ArticleId { get; set; }
public virtual ArticleContent Content { get; set; }
[StringLength(GUIConstants.MaxCharactersInMenuItemText)]
public string Title { get; set; }
[StringLength(100)]
public string SubTitle { get; set; }
public int? Sequence { get; set; }
public bool Published { get; set; }
public DateTime? PublishedDate { get; set; }
public virtual ICollection<Article> ParentArticles { get; set; }
public virtual ICollection<Article> ChildArticles { get; set; }
public string Notes { get; set; }
Article Content (It's the Content's Content property that has the WYSIWYG Editor, however if i use the WYSIWYG for a property dirrectly on the article model (like Title) I get the same issue.
public class ArticleContent
{
[Key, ForeignKey("Article")]
public int ArticleId { get; set; }
public virtual Article Article { get; set; }
[AllowHtml]
public string Content { get; set; }
}
}
Controller:
// GET: Articles/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var article = db.Article.Include(a => a.Content).SingleOrDefault(a => a.ArticleId == id);
if (article == null)
{
return HttpNotFound();
}
return View(article);
}
// POST: Articles/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[ValidateInput(false)]
[HttpPost, ActionName("Edit")]
public ActionResult EditPost(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var articleToUpdate = db.Article.Include(a => a.Content).SingleOrDefault(a => a.ArticleId == id);
if (TryUpdateModel(articleToUpdate, "",
new string[] { "Title", "SubTitle", "Sequence", "Content" }))
{
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
return View(articleToUpdate);
}
View:
**#model Catalyst.Models.Article
#{
ViewBag.Title = "Edit Article";
}
#section styles{
#Styles.Render("~/Content/summernote")
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ArticleId)
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SubTitle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SubTitle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SubTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Sequence, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Sequence, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Sequence, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Content.Content, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Content.Content, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Content.Content, "", 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>
}
<div>
#Html.ActionLink("Back to List", "Index", "Articles", new { #class = "btn btn-default" })
</div>
#section scripts {
#Scripts.Render("~/bundles/SummerNote", "~/bundles/SummerNoteArticleContentEditor")
}**
The Javascript turning the content textbox into summernote
(function ($) {
function HomeIndex() {
var $this = this;
function initialize() {
$('#Content_Content').summernote({
focus: true,
height: 320,
codemirror: {
theme: 'united'
}
});
}
$this.init = function () {
initialize();
}
}
$(function () {
var self = new HomeIndex();
self.init();
})
}(jQuery))
I followed this guide:
http://www.c-sharpcorner.com/UploadFile/3d39b4/bootstrap-wysiwyg-editor-in-Asp-Net-mvc/

Couldn't bind properly from view to model using BeginCollectionItem with nested collection

I am following this blog Editing a variable length list, ASP.NET MVC 2-style by Steven Anderson and started using Html.BeginCollectionItem() for my ASP.NET MVC project.
The project is about associating multiple permissions to roles. It will have a Role page(view) where user will have option to add permissions by selecting one of the permissions from drop-down list. User will also be able to add these permissions drop-down list by clicking on 'Add' button. 'Add' would dynamically add new drop-down list control on the page. Remove would remove the last drop-down list.
The issue I am facing is with binding nested collection. I have used RolePermissions list below which inturn is a list of RolePermissionViewModel.
See below for screenshots.
Role Controller: I have hardcoded sample data for testing.
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using MUtilities.Model.Entities;
using MUtilities.Web.Areas.Admin.Models;
using MUtilities.Web.Controllers;
using HtmlHelpers.BeginCollectionItem;
namespace MUtilities.Web.Areas.Admin.Controllers
{
public class RoleController : BaseController
{
public ActionResult Index()
{
return View();
}
public ViewResult BlankPermission()
{
return View("_PermissionPartial", GetPermissions());
}
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var role = MRepository.AllRoles.Find(id);
if (role == null)
{
return HttpNotFound();
}
return View(role);
}
private List<List<RolePermissionViewModel>> GetPermissionList() {
var rolePermissions = new List<List<RolePermissionViewModel>>();
rolePermissions.Add(GetPermissions());
rolePermissions.Add(GetPermissions());
return rolePermissions;
}
private List<RolePermissionViewModel> GetPermissions()
{
var permissions = new List<RolePermissionViewModel>();
permissions.Add(new RolePermissionViewModel
{
PermissionId = -1,
PermissionName = "--Select a Permission--"
});
permissions.Add(new RolePermissionViewModel
{
PermissionId = 1,
PermissionName = "Create of Utility1"
});
permissions.Add(new RolePermissionViewModel
{
PermissionId = 2,
PermissionName = "Update of of Utility1"
});
return permissions;
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Description,RolePermissions")] RoleViewModel roleModel)
{
if (ModelState.IsValid)
{
var role = new Role();
role.Name = roleModel.Name;
//some logic here
return RedirectToAction("Index");
}
return View();
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//some logic to edit view
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Name,Permissions")] RoleViewModel roleModel)
{
if (ModelState.IsValid)
{
var role = MRepository.AllRoles.First(r => r.Id == roleModel.Id);
role.Name = roleModel.Name;
//some logic to commit
return RedirectToAction("Index");
}
return View();
}
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Role role = MRepository.AllRoles.Find(id);
if (role == null)
{
return HttpNotFound();
}
return View(role);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
var role = MRepository.AllRoles.Find(id);
MRepositoryAllRoles.Remove(role);
MRepository.Commit();
return RedirectToAction("Index");
}
}
}
Role View:
#model MUtilities.Web.Areas.Admin.Models.RoleViewModel
#{
ViewBag.Title = "Create";
}
#section scripts{
<script type="text/javascript">
$(function () {
$("#addPermissionBtn").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) {
$("#addPermissionDdl").append(html);
//The call to Sys.Mvc.FormContext._Application_Load() refreshes
//the validation on the page to include the new fields.
Sys.Mvc.FormContext._Application_Load();
}
});
return false;
});
$("#deletePermissionBtn").on("click", function () {
var pDdls = $("select[id$='__PermissionList']");
if (pDdls && pDdls.length > 1) {
pDdls.last().remove();
//$(this).parents("div.addPermissionDdl:last").remove();
}
return false;
});
});
</script>
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Role</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RolePermissions, htmlAttributes: new { #class = "control-label col-md-2" })
#using (Html.BeginForm())
{
<div id="addPermissionDdl" class="col-md-10">
#foreach (var rolePermission in Model.RolePermissions)
{
Html.RenderPartial("_PermissionPartial", rolePermission);
}
</div>
<div class="col-md-10">
#Html.ActionLink("Add", "BlankPermission", null, new { id = "addPermissionBtn", #class = "glyphicon glyphicon-plus-sign" })
Delete
</div>
}
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
RoleViewModel: RolePermissions is a list of RolePermissionViewModel list.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MUtilities.Web.Areas.Admin.Models
{
public class RoleViewModel
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
[Display(Name="Permissions")]
public List<List<RolePermissionViewModel>> RolePermissions { get; set; }
}
public class RolePermissionViewModel
{
public int PermissionId { get; set; }
public string PermissionName { get; set; }
}
}
_PermissionPartial.cshtml
#{
Layout = null;
}
#using HtmlHelpers.BeginCollectionItem;
#model IEnumerable<MUtilities.Web.Areas.Admin.Models.RolePermissionViewModel>
#using (Html.BeginCollectionItem("RolePermissions"))
{
var permissionDdl = new SelectList(Model.Select(m => m), "PermissionId", "PermissionName", "--Select a Permission--");
#Html.DropDownList("PermissionList", permissionDdl, new { #class = "form-control" });
}
But when I click Create button Name, Description would bind ok but not the Permissions. See below.
Any idea what might be happening?

EnumDropDownList MVC 5

I have class
public partial class Team
{
public int Id { get; set; }
public Shifts Shift { get; set; }
}
public enum Shifts : int
{
First = 1,
Second = 2
}
and a MVC view code
<div class="form-group">
#Html.LabelFor(model => model.Shift, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.Shift, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Shift, "", new { #class = "text-danger" })
</div>
</div>
and a controller post code...
public ActionResult Create([Bind(Include = "Shift")] Team team)
{
if (ModelState.IsValid)
{
db.TeamSet.Add(team);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(team);
}
In my DB, Shift is int type and I'm trying to get values from Enum, but in post from form I get text ("First" or "Second"). I tried to find some documentation EnumDropDownListFor but without success, so if someone have any idea I'll be thankful..
public enum Shifts : int
{
[Display(Name = "First")]
First = 1,
[Display(Name = "Second")]
Second = 2
}

Resources