How to show user comments in hierarchical fashion in asp.net mvc - c#

I'm beginner in asp.net mvc.
I have a product model and I want implement user comments for any product.
I want to show comments as tree for each level.
I use a recursive method in my view to show comments and reply comment but
it cant show reply comments in third level .
The first level terms when replyId is empty displayed. Reply to first comment are displayed first. But the answer of Previous reply does not show in the third level.
Please help me. Thank you so much.
This is my model
namespace Mvc_Shop.Models
{
public class Comment
{
public Comment()
{
this.Children = new HashSet<Comment>();
}
public int Id { set; get; }
public string Body { set; get; }
public System.DateTime CommentDate { get; set; }
public int? ReplyId { get; set; }
public ICollection<Comment> Children { get; set; }
public virtual Comment Reply { set; get; }
public string User_Id { get; set; }
[ForeignKey("User_Id")]
public virtual User User { get; set; }
public int Product_Id { get; set; }
[ForeignKey("Product_Id")]
public virtual Product Product { get; set; }
}
}
This is my view
#helper TreeView(IEnumerable<Mvc_Shop.Models.Comment> Comments)
{
foreach (var item in Comments)
{
<div class="media">
<div class="media-body" id="Comment_#(item.Id)" style="padding: 3px;width: 100%;">
<h4 class="media-heading">
#item.User.UserName
<label class="badge pull-left" style="font-weight: normal">#item.CommentDate.ToString("dddd, dd MMMM yyyy - HH:mm")</label>
</h4>
<div class="clearfix">
#item.Body
</div>
<fieldset id="reply-cmnt-form_#(item.Id)" class="spr-form-review" style="display:none">
<div class="spr-form-review-body">
#Html.LabelFor(model => model.Comment.Body, new { #class = "spr-form-label" })
#Html.TextAreaFor(model => model.Comment.Body, new { #class = "spr-form-input spr-form-input-text", id = "commentbody" + #item.Id })
#Html.ValidationMessageFor(model => model.Comment.Body)
</div>
</fieldset>
<a id="btn-hide-div_#(item.Id)" class="btn btn-xs pull-left btn-primary" style="clear: both; display:none" onclick="opencmntdiv(#item.Id);"> بستن</a>
<a id="btn-send-div_#(item.Id)" class="btn btn-xs pull-left btn-primary" style="clear: both;float:right;display:none" onclick="ReplyComment(#item.Id);"> ارسال پاسخ</a>
<a id="btn-show-div_#(item.Id)" class="btn btn-xs pull-left btn-primary" style="clear: both" onclick="opencmntdiv(#item.Id);"> پاسخ</a>
</div>
</div>
<hr class="clearfix" />
if (item.Children.Any())
{
#TreeView(item.Children)
}
}
}
#TreeView(Model.Comments)
and this is my action
public ActionResult ShowProducts(string ProductName)
{
_dbContext = HttpContext.GetOwinContext().Get<ShopContext>();
var model = new UserCommentViewModel();
if (string.IsNullOrEmpty(ProductName))
{
return RedirectToAction("Index");
}
else
{
model.Products = blproduct.Where(p => p.Name.Trim() == ProductName.Trim()).ToList();
model.Comments = (from u1 in _dbContext.Users
join u2 in _dbContext.Comments
on u1.Id equals u2.User.Id
where u2.ReplyId == null
select new {
Id = u2.Id, Body = u2.Body, CommentDate = u2.CommentDate, User = u1,Children = u2.Children
}).ToList().Select(x => new Comment
{
Id = x.Id, Body = x.Body, CommentDate = x.CommentDate, User = x.User,Children = x.Children
}).ToList();
if (model != null)
{
return View(model);
}
else
{
return RedirectToAction("Index");
}
}
}
Thanks a lot.

Related

How can I overcome this error CS1579 in ASP.net?

The error shows as below:
System.Web.HttpCompileException:
'C:\Users\MEDADUWA\source\repos\CapeXPro\CapeXPro\Views\FAWizard_AddAsset.cshtml(43):
error CS1579: foreach statement cannot operate on variables of type
'FAInfo' because 'FAInfo' does not contain a public definition for
'GetEnumerator''
My ViewModel Look like this:
namespace DAL.Entities
{
public class FAInfo
{
public int WizardId { get; set; }
public string WizardType { get; set; }
public Step2 Step2 { get; set; }
public List<Step2> ListStep2 { get; set; }
public int Status { get; set; }
}
public class Step2
{
public int assetId { get; set; }
public string assetCode { get; set; }
public int assetCategoryId { get; set; }
public int assetTypeId { get; set; }
public int branchId { get; set; }
public int? ccenterId { get; set; }
public string description { get; set; }
public double cost { get; set; }
public double? vat { get; set; }
public double? vatRec { get; set; }
public double? nbt { get; set; }
public double bookValue { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
public string ModifiedBy { get; set; }
public int Status { get; set; }
public InvoiceEntities Invoice { get; set; }
public List<Step2> ListAssets { get; set; }
public List<tbl_assetcategory> ListCategories { get; set; }
public List<tbl_branch> ListBranches { get; set; }
public List<tbl_costcenter> ListDepartments { get; set; }
}
}
This is my Controller:
namespace CapeXPro.Controllers
{
[SessionExpire]
public class FAWizardController : Controller
{
UnitOfWork _unitOfWork = new UnitOfWork();
readonly CommonUtilities _commonService = new CommonUtilities();
#region Main View
FAInfo FAInfoComponent(FAInfo model = null)
{
try
{
//var existjournaldepreciation = _unitOfWork.JournalDepreciationRepository.GetAll(x => x.Id == 1 && x.Status != (int)StatusEnum.Delete).FirstOrDefault();
if (model == null)
{
model = new FAInfo()
{
Status = (int)StatusEnum.Active,
};
}
return model;
}
catch (Exception ex)
{
throw ex;
}
}
// GET: FAWizard
public ActionResult FAWizard()
{
return View("FAWizard", FAInfoComponent());
}
#endregion
#region Add Or Edit Step2
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Step2(FAInfo AssetData, string BtnPrevious, string BtnNext)
{
try
{
var action = string.Empty;
var before = string.Empty;
var after = string.Empty;
AssetData = FAInfoComponent(AssetData);
if (BtnPrevious != null)
{
FAInfo InvObj = new FAInfo();
InvObj.Step1.InvoiceId = AssetData.Step2.Invoice.InvoiceId;
InvObj.Step1.InvoiceNo = AssetData.Step2.Invoice.InvoiceNo;
InvObj.Step1.PoNo = AssetData.Step2.Invoice.PoNo;
return PartialView("_AddInvoice", InvObj);
}
if (BtnNext != null)
{
if (ModelState.IsValid)
{
var existObj = _unitOfWork.AssetRepository.GetAll(x => x.assetId == AssetData.Step2.assetId && x.Status != (int)StatusEnum.Delete).FirstOrDefault();
if (existObj == null)
{
tbl_asset asset = new tbl_asset()
{
assetId = AssetData.Step2.assetId,
assetCode = AssetData.Step2.assetCode,
assetCategoryId = AssetData.Step2.assetCategoryId,
CreatedBy = System.Web.HttpContext.Current.Session[SessionsEnum.UserId.ToString()].ToString(),
CreatedOn = DateTime.Now,
Status = Convert.ToInt32(AssetData.Status)
};
_unitOfWork.AssetRepository.Insert(asset);
//_unitOfWork.Save();
//int id = department.CcId;
action = ActionType.Insert;
before = null;
after = asset.assetId + "," +
asset.assetCode + "," +
asset.assetCategoryId + "," +
asset.Status + "," +
asset.CreatedBy + "," +
asset.CreatedOn + "," +
asset.ModifiedBy + "," +
asset.ModifiedOn;
}
else
{
FAInfo AssetObj = new FAInfo();
AssetObj.Step2.assetId = AssetData.Step2.assetId;
AssetObj.Step2.assetCode = AssetData.Step2.assetCode;
AssetObj.Step2.assetCategoryId = AssetData.Step2.assetCategoryId;
AssetObj.Step2.ModifiedBy = System.Web.HttpContext.Current.Session[SessionsEnum.UserId.ToString()].ToString();
AssetObj.Step2.ModifiedOn = DateTime.Now;
AssetObj.Step2.Status = Convert.ToInt32(AssetData.Status);
_unitOfWork.AssetRepository.Update(existObj);
action = ActionType.Update;
before = null;
after = existObj.assetId + "," +
existObj.assetCode + "," +
existObj.assetCategoryId + "," +
existObj.Status + "," +
existObj.CreatedBy + "," +
existObj.CreatedOn + "," +
existObj.ModifiedBy + "," +
existObj.ModifiedOn;
}
if (_unitOfWork.Save() > 0)
{
//Update Log Table
AuditLog.SystemLog(Tables.AssetTable, action, before, after);
TempData["message"] = Messages.Success;
ModelState.Clear();
return View("AddDepreciation", new FADepreciationEntities());
}
else
{
TempData["message"] = Messages.Failed;
return PartialView("_AddAsset", AssetData);
}
}
return PartialView("_AddAsset", AssetData);
}
return View();
}
catch (Exception ex)
{
TempData["message"] = Messages.Exception + ex.Message;
return PartialView("_AddAsset", AssetData);
}
}
#endregion
}
}
This is my Partial View
#model DAL.Entities.FAInfo
#using DAL.Enums
#using (Html.BeginForm("Step2", "FAWizard", FormMethod.Post, new { #class = "form-horizontal form-label-left", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(m => m.Step2.assetId)
<!-- Editable table -->
<div class="card">
<div class="card-body">
<div id="table" class="table-editable">
<span class="table-add float-right mb-3 mr-2">
<a href="#!" class="text-success">
<i class="fas fa-plus fa-2x" aria-hidden="true"></i>
</a>
</span>
<table id=""
class="table table-striped table-hover table-sm table-bordered text-center">
<thead>
<tr>
<th class="text-center">Line No</th>
<th class="text-center">Asset Code</th>
<th class="text-center">Asset Class</th>
</tr>
</thead>
<tbody>
#foreach (DAL.Entities.FAInfo asset in Model)
{
<tr>
<td>1</td>
<td>#asset.Step2.assetCode</td>
<td>#asset.Step2.ListCategories</td>
<td>
<span class="table-remove">
<button type="button"
class="btn btn-danger btn-rounded btn-sm my-0">
Remove
</button>
</span>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
}
This is my MasterView:
#model DAL.Entities.FAInfo
#using DAL.Enums
#{
ViewBag.Title = "FAWizard";
}
<div class="right_col" role="main">
<div class="full-height">
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2>Fixed Assets Capitalization <small>CapeXPro</small></h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<form class="form-horizontal form-label-left" novalidate>
<p>
For Fixed asset registration - CapeXPro | Union Bank of Colombo
</p>
<span class="section">Fixed Asset Info</span>
<!-- Smart Wizard -->
<p>Proceed with the given steps</p>
<div id="wizard" class="form_wizard wizard_horizontal">
<ul class="wizard_steps">
<li>
<a href="#step-1">
<span class="step_no">1</span>
<span class="step_descr">
Step 1<br />
<small>Invoice and Insurance Details</small>
</span>
</a>
</li>
<li>
<a href="#step-2">
<span class="step_no">2</span>
<span class="step_descr">
Step 2<br />
<small>Asset Details</small>
</span>
</a>
</li>
</ul>
<div id="step-1">
#{Html.RenderPartial("_AddInvoice", Model);}
</div>
<div id="step-2">
#{Html.RenderPartial("_AddAsset", Model);}
</div>
</div>
<!-- End SmartWizard Content -->
</form>
</div>
</div>
</div>
</div>
</div>
</div>
System.Web.HttpCompileException: 'C:\Users\MEDADUWA\source\repos\CapeXPro\CapeXPro\Views\FAWizard_AddAsset.cshtml(43): error CS1579: foreach statement cannot operate on variables of type 'FAInfo' because 'FAInfo' does not contain a public definition for 'GetEnumerator''
This error is thrown because in your partial view FAWizard_AddAsset you're trying to iterate your model like this #foreach (DAL.Entities.FAInfo asset in Model). This assumes that Model is an enumerable of FAInfo, like a List<FAInfo> but apparently it's a FAInfo.
Judging by your code I think there's no multiples of FAInfo, but within your FAInfo there's a List<ListStep2>. If you want to iterate that then change your #foreach into this:
#foreach (DAL.Entities.Step2 asset in Model.ListStep2)
In your #model statement you are using a single instance. This is useful for Details and Edit views of single items. To iterate over entities in a view, you can make the model an IEnumerable of MyClass like so:
#model IEnumerable<DAL.Entities.FAInfo>

Dictionary<TEntity, string> and asp.net mvc how to?

I have:
public class Nomenclature
{
public virtual int NomenclatureId { get; set; }
public virtual NomenclatureType NomenclatureType { get; set; }
public virtual IDictionary<NomenclatureAttribute, string> Attributes { get; set; }
}
public class NomenclatureType
{
public virtual int NomenclatureTypeId { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Nomenclature> Nomenclatures { get; set; }
public virtual ICollection<NomenclatureAttribute> NomenclatureAttributes { get; set; }
public NomenclatureType()
{
Nomenclatures = new HashSet<Nomenclature>();
NomenclatureAttributes = new HashSet<NomenclatureAttribute>();
}
}
public class NomenclatureAttribute
{
public virtual int NomenclatureAttributeId { get; set; }
public virtual string AttributeName { get; set; }
public virtual string AttributeType { get; set; }
public virtual NomenclatureType NomenclatureType { get; set; }
}
it's all represents a nomenclature of goods in my application. I'am tryin create new Nomenclature in my app. I use NHibernate. I create controller and create action:
[HttpGet]
public ActionResult Create(string nomenclatureType)
{
if (nomenclatureType == null)
return RedirectToAction("List", "Nomenclature");
ViewData["NomenclatureAttributes"] =
_repositoryNomenclatureType.Get(w => w.Name == nomenclatureType).NomenclatureAttributes.ToList();
return View();
}
[HttpPost]
public IActionResult Create(Nomenclature nomenclature)
{
try
{
if (ModelState.IsValid)
{
_repositoryNomenclature.Create(nomenclature);
return RedirectToAction("List", "Nomenclature");
}
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists see your system administrator.");
}
return View(nomenclature);
}
I need to foreach all NomenclatureAttrributes specified for any Nomenclature Type and create editors for all values and add all to Model.Attributes.
#model Nomenclature
#{
ViewBag.Title = "New nomenclature";
Layout = "_Layout";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#foreach (var a in (List<NomenclatureAttribute>)ViewData["NomenclatureAttributes"])
{
<div class="form-group">
<label class="control-label col-md-2">#a.AttributeName</label>
<div class="col-md-10">
**What i should place to this???**
</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>
}
I use Asp.net core web application (.NET Framework)
First Create ViewModel.
public class CreateNomenclatureViewModel
{
//Add other properties if needed
public NomenclatureType SelectedNomenclatureType { get; set; }
public List<NomenclatureAttribute> Attributes { get; set;}
}
Second
[HttpGet]
public ActionResult Create(string nomenclatureType)
{
if (nomenclatureType == null)
return RedirectToAction("List", "Nomenclature");
var viewModel= new CreateMomenClatureViewModel
{
Attributes = _repositoryNomenclatureType.Get(w => w.Name == nomenclatureType).NomenclatureAttributes.ToList()
}
return View(viewModel);
}
Than fix your view
#model CreateNomenclatureViewModel
#{
ViewBag.Title = "New nomenclature";
Layout = "_Layout";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#if (Model != null && Model.Attributes != null)
{
for (int i = 0; i < Model.Attributes.Count; i++)
{
<div class="form-group">
#Html.DisplayFor(modelItem => Model.Attributes [i].AttributeName)
#Html.TextBoxFor(modelItem => Model.Attributes [i].AttributeType )
</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>
}
if you want to use Nomenclature as ViewModel you can create new Nomenclature on Get Method than pass to view in razor view.
<div class="form-group">
#Html.DisplayFor(modelItem => Model.Attributes.Keys.ElementAt(i).AttributeName)
#Html.TextBoxFor(modelItem => Model.Attributes.Keys.ElementAt(i).AttributeType )
</div>

c# ASP.NET MVC cannot pass model's collection field to controller [duplicate]

This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 7 years ago.
I have a class from EF.
public partial class Customer
{
public Customer()
{
this.Customer_CustomerSpecialConcern = new HashSet<Customer_CustomerSpecialConcern>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public virtual ICollection<Customer_CustomerSpecialConcern> Customer_CustomerSpecialConcern { get; set; }
}
When I pass the model from controller to view everything works fine (can access Customer_CustomerSpecialConcern values).
The problem is when I post back model to a controller to save the changes the property Customer_CustomerSpecialConcern is null.
Here is how I use it in view.
#foreach (var ccsc in Model.Customer_CustomerSpecialConcern)
{
<div class="form-group fields-container col-md-3">
<label class="field-label control-label col-md-10" for="">#ccsc.CustomerSpecialConcern.Title</label>
<div class="col-md-1 field-input">
#Html.EditorFor(model => ccsc.Value)
#Html.HiddenFor(model => ccsc.Value)
</div>
</div>
}
Please, I need help to get the values of this collection property to controller. Thank you.
Update - Customer_CustomerSpecialConcern class details
public partial class Customer_CustomerSpecialConcern
{
public int Id { get; set; }
public int Customer_Id { get; set; }
public int CustomerSpecialConcern_Id { get; set; }
public bool Value { get; set; }
public virtual Customer Customer { get; set; }
public virtual CustomerSpecialConcern CustomerSpecialConcern { get; set; }
}
Please try this,
#for (int i = 0; i < Model.Customer_CustomerSpecialConcern.Count(); i++)
{
<div class="form-group fields-container col-md-3">
<label class="field-label control-label col-md-10" for="">#Model.CustomerSpecialConcern[i].Title</label>
<div class="col-md-1 field-input">
#Html.EditorFor(model => model.Customer_CustomerSpecialConcern[i].Value)
#Html.HiddenFor(model => model.Customer_CustomerSpecialConcern[i].Value)
</div>
</div>
}
Check this article.
I tried your example, and this is how it looks
public ActionResult Index()
{
var customer = new Customer
{
Name = "Name",
Surname = "Surname",
Email = "email#email.com",
Mobile = "mobile...",
Customer_CustomerSpecialConcern = new List<Customer_CustomerSpecialConcern>
{
new Customer_CustomerSpecialConcern
{
Value = true
},
new Customer_CustomerSpecialConcern
{
Value = true
}
}
};
return View(customer);
}
View:
#model WebApplication1.Models.Customer
#{
ViewBag.Title = "Customer";
var customer_CustomerSpecialConcern = Model.Customer_CustomerSpecialConcern.ToList();
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
for (int i = 0; i < Model.Customer_CustomerSpecialConcern.Count(); i++)
{
<div class="form-group fields-container col-md-3">
<label class="field-label control-label col-md-10" for=""></label>
<div class="col-md-1 field-input">
#Html.CheckBoxFor(model => customer_CustomerSpecialConcern[i].Value)
</div>
</div>
}
<input type="submit" value="Save"/>
}

mvc view-unable to access nested list

I have a list of categories and each category may have subcategories. I am getting the list with correct records in my controller but if I try to use the list of subcategories in my view, it shows nothing.
Classes:
public class DashboardTile
{
public int ID { get; set; }
public int? CategoryID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class DashboardTileBO : DashboardTile
{
public bool IsChecked { get; set; }
public List<DashboardTileBO> DashboardTiles { get; set; }
}
public class AddTileVM
{
public List<DashboardTileBO> DashboardTiles { get; set; }
}
Controller:
public ActionResult AddTiles()
{
var allDashBoardTiles = BLL.PublicLayer.GetAllDashBoardTiles(SessionItems.UserId);
var addTileVm = new AddTileVM()
{
DashboardTiles = allDashBoardTiles,
};
return PartialView(addTileVm );
}
View:
#model Hugo.BusinessObjects.AddTileVM
<link href="~/Content/js/nestable/nestable.css" rel="stylesheet"/>
<script src="~/Content/js/nestable/jquery.nestable.js"></script>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Add/Remove Tiles to desktop</h4>
</div>
#using (Ajax.BeginForm("AddTiles", "Default",new AjaxOptions {OnSuccess = "OnSuccess" }))
{
#Html.AntiForgeryToken();
<div class="modal-body">
<div class="row">
<div class="col-lg-12">
#for (var i = 0; i < Model.DashboardTiles.Count; i++)
{
<div class="col-lg-5">
<label class="">
#Html.CheckBoxFor(a=> Model.DashboardTiles[i].IsChecked)
#Model.DashboardTiles[i].Description
</label>
</div>
#*if (#Model.DashboardTiles[i].DashboarTiles.Count > 0)
{
for (var j = 0; j < #Model.DashboardTiles[i].DashboarTiles.Count; j++)
{
<div class="col-lg-5">
<label class="">
#Html.CheckBoxFor(a => #Model.DashboardTiles[i].DashboarTiles[j].IsChecked)
#Model.DashboardTiles[i].DashboarTiles[j].Description
</label>
</div>
}
}*#
#Html.HiddenFor(a=> Model.DashboardTiles[i].ID)
}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-rounded btn-sm btn-tiles" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-rounded btn-sm btn-tiles" >Update</button>
</div>
}
</div><!-- /.modal-content -->
}
method to fetch list
public static List<BusinessObjects.DashboardTileBO> GetAllDashBoardTiles(long userId)
{
using (var context = new HugoInternalEntities())
{
var distincCategoryIds = context.DashboardTiles.Select(a => a.CategoryID).Distinct().ToList();
var allTiles = (context.DashboardTiles.Where(a => distincCategoryIds.Contains(a.ID)).Select(x=>
new BusinessObjects.DashboardTileBO
{
ID = x.ID,
Name = x.Name,
Description = x.Description,
})).ToList();
var list = context.DashboardUserTiles.Where(a => a.UserID == userId).Select(a => a.DashboardTileID).ToList();
allTiles.ForEach(a => a.IsChecked = list.Contains(a.ID));
allTiles.ForEach(a=>a.DashboardTiles=context.DashboardTiles.Where(b=>a.ID==b.CategoryID && b.ID != a.ID).Select(x=>
new BusinessObjects.DashboardTileBO
{
ID = x.ID,
Name = x.Name,
Description = x.Description,
}).ToList());
allTiles.ForEach(a => a.DashboardTiles.ForEach(b => b.IsChecked = list.Contains(b.ID)));
return allTiles;
}
}
In the above view my list of main categories is shown but if I uncomment my code for subcategories nothing is shown. Please see the screenshot of the list I am getting in addTileVm
List of tiles:

Model (complex type) won't submit to action

I have some problem posting a form with 'complex type' model:
I have a Model:
public class CircleEditViewModel
{
[Key]
public int CircleId { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
public bool IsSystem { get; set; }
public class UserInCircle
{
public UserInCircle(User user)
{
this.UserId = user.UserId;
FullName = user.FullName;
}
public int UserId { get; set; }
public byte[] Picture { get; set; }
public string FullName { get; set; }
public bool isInCircle { get; set; }
}
public List<UserInCircle> Users { get; set; }
}
My first problem was that at post event, my Users where null.. so i followed a few posts on here (like MVC- Model Binding on a Complex Type) to use a for instead of a foreach,but since i did so, my form won't post anymore:
View:
#model Wims.Website.ViewModels.CircleEditViewModel
<script type="text/javascript">
$(document).ready(function () {
$.validator.unobtrusive.parse('form');
});
</script>
#using (Ajax.BeginForm(Html.ViewContext.RouteData.Values["Action"].ToString(), null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "SaveDone(data)" }, new { id = "editform" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Circle</legend>
#Html.Label(DateTime.Now.ToString());
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</fieldset>
if (Model.Users != null)
{
for (int i = 0; i < Model.Users.Count; i++)
{
<div class="userDetail">
<div>
<div>
#Html.DisplayFor(model => Model.Users[i].isInCircle);
</div>
<div class="iconDiv">
#Html.Image("~/Content/Images/defaultUser.jpg", Model.Users[i].FullName, null);
</div>
<div>
#Html.TextBoxFor(model => Model.Users[i].FullName)
#Html.HiddenFor(model => Model.Users[i].UserId)
</div>
</div>
</div>
<div style="clear: both"></div>
}
}
#Html.GenerateSecureDataControls(model => model.CircleId)
<input type="submit" value="Save" />
}
My view is rendered as a partial loaded thru ajax (not sure it makes any difference here).
Any idea why it won't post? If i remove all the '[]' like 'Users[0].FullName' to Users0.FullName i will post, but of course it won't be bound.
Thanks for your help
Edit just in case needed: Action:
[HttpPost]
public ActionResult Edit(CircleEditViewModel circleData, FormCollection collection)
{
if (ModelState.IsValid)
{
using (var logic = new CircleLogic())
{
Circle circle = logic.GetCircleById(circleData.CircleId, WebMatrix.WebData.WebSecurity.CurrentUserId);
if (circle == null)
{
return HttpNotFound();
}
else
{
circle.Name = circleData.Name;
logic.UpdateCircle(circle, GetSelectedUser(collection));
}
return PartialView("_CircleAndUsers", GetData(logic, circle.CircleId));
}
}
return this.Json(new { success = false, viewdata = RenderRazorViewToString("_CircleAndUsers", circleData) });
}
Pablo Romeo was right, i added a default ctor and it worked.

Categories

Resources