I am using nopcommerce 2.2 & trying to use the partial view ProductVariant_SKU_Man_Stock in the _Productbox.cshtml but it comes up with the error:
The model item passed into the dictionary is of type
'System.Collections.Generic.List`1[Nop.Web.Models.Catalog.ProductModel+ProductVariantModel]',
but this dictionary requires a model item of type
'Nop.Web.Models.Catalog.ProductModel+ProductVariantModel'.
Below is the _Productbox.cshtml:
#model Nop.Web.Models.Catalog.ProductModel
<div class="product-item">
<h2 class="product-title">
#Model.Name
</h2>
<div class="description">
#Html.Partial("_ProductVariant_SKU_Man_Stock",Model.ProductVariantModels)
#Html.Raw(Model.FullDescription) <br />
#Model.Size
</div>
<div class="add-info">
<div class="prices">
#Html.Partial("_ProductPrice", Model.ProductPrice)
</div>
<div class="buttons">
#* <input type="button" value="#T("Products.Details")" class="productlistproductdetailbutton" onclick="setLocation('#Url.RouteUrl("Product", new { productId = Model.Id, SeName = Model.SeName })')" />
*# #if (!Model.ProductPrice.DisableBuyButton)
{
<br />
<input type="button" value="#T("ShoppingCart.AddToCart")" class="productlistaddtocartbutton" onclick="setLocation('#(#Url.RouteUrl("AddProductToCart", new { productId = Model.Id }))')" />
}
</div>
</div>
</div>
Is there any other way of doing it coz i need some fields within that partial view to display in this view.
productmodel.cs:
public class ProductModel : BaseNopEntityModel
{
public ProductModel()
{
ProductPrice = new ProductPriceModel();
// ProductSku = new ProductSkuModel();
DefaultPictureModel = new PictureModel();
PictureModels = new List<PictureModel>();
ProductVariantModels = new List<ProductVariantModel>();
SpecificationAttributeModels = new List<ProductSpecificationModel>();
}
public string Name { get; set; }
public string ShortDescription { get; set; }
public string FullDescription { get; set; }
public string ProductTemplateViewPath { get; set; }
public string MetaKeywords { get; set; }
public string MetaDescription { get; set; }
public string MetaTitle { get; set; }
public string SeName { get; set; }
public string Size { get; set; }
public ProductPriceModel ProductPrice { get; set; }
public bool DefaultPictureZoomEnabled { get; set; }
public PictureModel DefaultPictureModel { get; set; }
public IList<PictureModel> PictureModels { get; set; }
public IList<ProductVariantModel> ProductVariantModels { get; set; }
public IList<ProductSpecificationModel> SpecificationAttributeModels { get; set; }
public class ProductVariantModel : BaseNopEntityModel
{
public ProductVariantModel()
{
ProductSku = new ProductSkuModel();
GiftCard = new GiftCardModel();
ProductVariantPrice = new ProductVariantPriceModel();
PictureModel = new PictureModel();
AddToCart = new AddToCartModel();
ProductVariantAttributes = new List<ProductVariantAttributeModel>();
}
public string Name { get; set; }
public bool ShowSku { get; set; }
public string Sku { get; set; }
public string Description { get; set; }
public bool ShowManufacturerPartNumber { get; set; }
public string ManufacturerPartNumber { get; set; }
public string DownloadSampleUrl { get; set; }
public GiftCardModel GiftCard { get; set; }
public string StockAvailablity { get; set; }
public ProductVariantPriceModel ProductVariantPrice { get; set; }
public AddToCartModel AddToCart { get; set; }
public PictureModel PictureModel { get; set; }
public ProductSkuModel ProductSku { get; set; }
public IList<ProductVariantAttributeModel> ProductVariantAttributes { get; set; }
public class ProductVariantPriceModel : BaseNopModel
{
public string OldPrice { get; set; }
public string Price { get; set; }
public string PriceWithDiscount { get; set; }
public decimal PriceValue { get; set; }
public decimal PriceWithDiscountValue { get; set; }
public bool CustomerEntersPrice { get; set; }
public bool CallForPrice { get; set; }
public int ProductVariantId { get; set; }
public bool HidePrices { get; set; }
public bool DynamicPriceUpdate { get; set; }
}
public class ProductSkuModel : BaseNopModel
{
public string Sku { get; set; }
public bool ShowSku { get; set; }
}
Want to use this partial view :
#model Nop.Web.Models.Catalog.ProductModel.ProductVariantModel
#if (!String.IsNullOrWhiteSpace(Model.StockAvailablity))
{
<div class="stock">
#Model.StockAvailablity
</div>
}
<div class="clear">
</div>
#if (!String.IsNullOrWhiteSpace(Model.Sku) && Model.ShowSku)
{
<div class="sku">
#Model.Sku
</div>
}
<div class="clear">
</div>
#if (!String.IsNullOrWhiteSpace(Model.ManufacturerPartNumber) && Model.ShowManufacturerPartNumber)
{
<div class="manufacturerpartnumber">
#Model.ManufacturerPartNumber
</div>
}
There is an alternative way in which you can bring the attributes like stock quantity in ProductVariant_SKU_Man_Stock into the _Productbox.cshtml,without using partial view.
The way is as follows:
Add the following set of code
In Productmodel.cs,there is a nested class called
public class ProductPriceModel : BaseNopModel
{
//here declare stockquantity
public int stockqty { get; set; }
}
In catalogcontroller.cs,
there is a function called
private ProductModel.ProductPriceModel PrepareProductPriceModel(Product product)
{
//ADD THIS CODE BELOW
model.stockqty=productvariants[0].StockQuantity;
}
In _Productbox.cshtml add
#if (Model.ProductPrice.stockqty <= 0)
{
<div class="innerrtcarts">
insert out of stock message or image
</div>
}
The _ProductVariant_SKU_Man_Stock view is expected a single ProductVariantModel and you are giving it a list of them. If you know you will only have one Variant then just change that line to
#Html.Partial("_ProductVariant_SKU_Man_Stock",Model.ProductVariantModels.First())
Related
I am new to programming, I am trying to create a shopping site like users sell their products.
I have products and a user's table. There is a "userId" column in the products table which is referenced by "ID" in the user's table. Only logged users can add product and I want to show products in each user's profile which they added. My code is below.
But here is the Error:Value cannot be null.Parameter name: source.
What is wrong with this code or is there any other way to do it.
My view:
<section class="page-section" id="relatedprod">
<div class="container">
<div class="row middle">
#foreach (Product prd in Model.Prod.Where(i=>i.userid==Model.userr.ID))
{
<div class="col-md-4">
<figure class="card card-product mehsul">
<div class="img-wrap"> <img class="img-fluid mehsulimg" src="~/PublicFront/images/30off6ec8.jpg" alt=""> </div>
<div class="handhover">
<img class="img-fluid" src="~/PublicFront/images/serv2b712.jpg" alt="">
</div>
<figcaption class="info-wrap">
<h4 class="title">#prd.ProdName</h4>
<p class="#prd.Price"></p>
</figcaption>
<div class="bottom-wrap">
Order Now
<div class="price-wrap h5">
<span class="price-new">$1280</span> <del class="price-old">$1980</del>
</div> <!-- price-wrap.// -->
</div> <!-- bottom-wrap.// -->
</figure>
</div> <!-- col // -->
}
</div>
</div>
</section>
Controller
public ActionResult MainAccount(int?id)
{
User us = Session["ActiveUser"] as User;
var vm = new HMViewM()
{
homesec1 = _context.homesec1slider.ToList(),
userr=us,
};
return View(vm);
}
namespace HandMShop.ViewModel
{
Models:
public class HMViewM
{
public List<homesec1slider> homesec1 { get; set; }
public User userr { get; set; }
public List<Category> catg { get;set; }
public List<Colour> colrs { get; set; }
public List<PhotoProduct> Photopr { get; set; }
public List<Product> Prod { get; set; }
}
}
public partial class Product
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Product()
{
this.PhotoProducts = new HashSet<PhotoProduct>();
}
public int id { get; set; }
public string ProdName { get; set; }
public string Price { get; set; }
public string Discount { get; set; }
public Nullable<int> CategoryId { get; set; }
public Nullable<int> AvailableID { get; set; }
public string Description { get; set; }
public string Material { get; set; }
public Nullable<byte> Enable { get; set; }
public Nullable<int> userid { get; set; }
public Nullable<System.DateTime> prodpostDate { get; set; }
public string ProdGenderId { get; set; }
public string sifarishle { get; set; }
public Nullable<int> LanguageId { get; set; }
public Nullable<int> colourId { get; set; }
public string Olcusu { get; set; }
public virtual AvailableTb AvailableTb { get; set; }
public virtual Category Category { get; set; }
public virtual Colour Colour { get; set; }
public virtual LanguageTb LanguageTb { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PhotoProduct> PhotoProducts { get; set; }
public virtual User User { get; set; }
}
}
Oh okay, it seems that your product list property is empty, use the code below to fill it.
public ActionResult MainAccount(int?id)
{
User us = Session["ActiveUser"] as User;
// add Prod = _context.Product.Where(p=>p.User.ID == us.ID).ToList()
var vm = new HMViewM()
{
homesec1 = _context.homesec1slider.ToList(),
userr = us,
Prod = _context.Product.Where(p=>p.User.ID == us.ID).ToList()
};
return View(vm);
}
#Html.ValidationMessageFor(model => model.DeliverySchedule.d_date, "Please fill up.", new { #class = "text-danger" })
for my validation. However it keep showing on page load.
after adding the css below. it disappear on first load but when i submit the form with empty field. The message does not come out.
.field-validation-valid
{display: none;}
Javascript ref also added
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
Controller
public ActionResult ArrangeDelivery() {
var list = service.GetNotDeliveryScheduleList();
return View(list);
}
[HttpPost]
public ActionResult ArrangeDelivery(OrderViewModel model)
{
var result = service.SetDeliverySchedule(model);
if (result==true)
{
return RedirectToAction("ArrangeDelivery");
}
var list = service.GetNotDeliveryScheduleList();
return View(list);
}
HTML
<div class='input-group date' id='datetimepicker2'>
#Html.EditorFor(model => model.DeliverySchedule.d_date, new { htmlAttributes = new { #class = "form-control bootdatepicker" } })
#Html.ValidationMessageFor(model => model.DeliverySchedule.d_date, "Please fill up.", new { #class = "text-danger" })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
View model
public class OrderViewModel
{
public OrderViewModel()
{
DeliveryScheduleList = new List<DeliverySchedule>();
DeliveryPartList = new List<DeliveryPart>();
}
public List<DeliverySchedule> DeliveryScheduleList { get; set; }
public DeliverySchedule DeliverySchedule { get; set; }
public List<DeliveryPart> DeliveryPartList { get; set; }
}
Actual Model with DB first
public partial class DeliverySchedule
{
public long ID { get; set; }
public Nullable<long> DL_ID { get; set; }
public Nullable<System.DateTime> datum { get; set; }
public Nullable<System.DateTime> zeit { get; set; }
public string customer_id { get; set; }
public string customer { get; set; }
public string area { get; set; }
public string address_1 { get; set; }
public string address_2 { get; set; }
public string postal { get; set; }
public string person_look_for { get; set; }
public string contact_look_for { get; set; }
public string PO_Number { get; set; }
public string staff { get; set; }
public string invoice { get; set; }
public string service { get; set; }
public string remarks { get; set; }
public string d_type { get; set; }
public string d_arranged { get; set; }
public string i_return { get; set; }
public string d_done { get; set; }
public Nullable<System.DateTime> d_date { get; set; }
public string d_time { get; set; }
public string d_by { get; set; }
public Nullable<int> DO_Number { get; set; }
}
I am making gallery for real estates. I save data for it in table named "Imot" and additional information like regions in table named "Region". I try to show all items in "Imot" and in each div for it in the View to add some of additional information. Example : im my table "Imot" I have imot.ID=1 and imot.RegionID=2 . In the View I must see that the region for this real estate is Sofia, which is saved in table region in field regionName with RegionID=2.
A lot is written for this topic, but nothing works for me.
Here is my code:
Model:
public class Imot
{
public int ID { get; set; }
public string ShortName { get; set; }
public string LongName { get; set; }
public int VDID { get; set; }
public int VOID { get; set; }
public int OblastID { get; set; }
public int ObshtinaID { get; set; }
public int VillageID { get; set; }
public int RegionID { get; set; }
public int TypeOfConID { get; set; }
public int StatusImotID { get; set; }
public string MainImage { get; set; }
public int Price { get; set; }
public int Square { get; set; }
public int Floor { get; set; }
public virtual VD VD { get; set; }
public virtual VO VO { get; set; }
public virtual Oblast Oblast { get; set; }
public virtual Obshtina Obshtina { get; set; }
public virtual Village Village { get; set; }
public virtual Region Region { get; set; }
public virtual TypeOfCon TypeOfCon { get; set; }
public virtual StatusImot StatusImot { get; set; }
public virtual ICollection<MyImages> MyImages { get; set; }
}
public class Region
{
public int RegionID { get; set; }
public string RegionName { get; set; }
public virtual ICollection<Imot> Imots { get; set; }
}
Context:
public class MyProjectContext: DbContext
{
public MyProjectContext() : base("MyProjectContext") {}
public DbSet<VD> VDs { get; set; }
public DbSet<VO> VOs { get; set; }
public DbSet<Oblast> Oblasts { get; set; }
public DbSet<Obshtina> Obshtinas { get; set; }
public DbSet<Village> Villages { get; set; }
public DbSet<Region> Regions { get; set; }
public DbSet<TypeOfCon> TypeOfCons { get; set; }
public DbSet<StatusImot> StatusImots { get; set; }
public DbSet<Imot> Imots { get; set; }
public DbSet<MyImages> MyImageses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}}
Seed:
public class MyProjectInitializer :System.Data.Entity.
DropCreateDatabaseIfModelChanges<MyProjectContext>
{protected override void Seed(MyProjectContext context){
var Regions = new List<Region>
{
new Region{RegionName="Sofia"},
};
var Imots = new List<Imot>
{
new Imot {ShortName="",LongName="",VDID=1,VOID=5,OblastID=1,
ObshtinaID=1,VillageID=1,RegionID=4,TypeOfConID=1,
StatusImotID=1,MainImage="",Price=10000,Square=100,Floor=6}
};}}
Controller:
public class SalesController : Controller
{
private MyProjectContext db = new MyProjectContext();
// GET: ImotsAdmin
public ActionResult Index()
{
ViewBag.RegionID = new SelectList(db.Regions, "RegionID", "RegionName");
var imots = db.Imots.Include(i => i.Oblast).Include(i => i.Obshtina)
.Include(i => i.Region).Include(i => i.StatusImot).Include(i =>i
.TypeOfCon).Include(i => i.VD).Include(i => i.Village).Include(i => i.VO);
return View(imots.ToList());
}
}
View:
#model IEnumerable<MyProject.Models.Imot>
#using MyProject.Models
#{ViewBag.Title = "For Sale";}
#using (Html.BeginForm("Index", "Sales", FormMethod.Get))
{
#Html.AntiForgeryToken()
#Html.DropDownList("RegionID", (SelectList)ViewBag.RegionId, "Region",
new { #class = "form-control" })
<input type="submit" value="Search" class="btn btn-primary" />
}
<div>
#foreach (var item in Model)
{
<div class="img">
<div class="desc">#item.Price</div>
<a target="_blank" href='#Url.Action("Details", "Sales", new {id=item.ID})'>
<img src="#item.MainImage" alt="Имот" width="110" height="90"></a>
<div class="desc">#item.RegionID</div>
<div class="desc">#item.OblastID , #item.Square , #item.Floor </div>
<div class="desc">#item.ShortName</div>
#Html.ActionLink("More info...", "Details", new { id = item.ID }) |
</div>
}
</div>
Here is a link of what I get in View: http://prntscr.com/995gio
Next to the "Region: " must be the name of region: "Sofiq" but instead is just the ID.
Thanks :)
You are printing the RegionID property on the Imot object. If you want to print the Region name, You should access the Region navigation property and access it's RegionName property.
So inside your foreach loop, replace
<div class="desc">#item.RegionID</div>
With
<div class="desc">#item.Region.RegionName </div>
I'm creating new product belonging to the category model.When i execute my Create method, the error invoke that
"Object Reference not set to instance of object" on "model" object
My Controller class:
public ActionResult CreateProduct()
{
SetCateProductViewBag();
return View(new CateProdViewModel());
}
[HttpPost]
public ActionResult CreateProduct(CateProdViewModel model)
{
var ValidImageTypes = new String[]
{
"image/gif",
"image/jpeg",
"image/jpg",
"image/pjpeg",
"image/png"
};
if (model.ImageUpload == null || model.ImageUpload.ContentLength == 0)
{
ModelState.AddModelError("ImageUpload", "This Field is required.");
}
else if (!ValidImageTypes.Contains(model.ImageUpload.ContentType))
{
ModelState.AddModelError("ImageUload", "Please choose either a GIF,jpg or png type of file.");
}
if (ModelState.IsValid)
{
var prod = new Product
{
// CategoryName =model.category.CategoryName,
//CategoryDescription=model.category.CategoryDescription,
//CategoryId=model.CategoryId,
ProductName = model.ProductName,
ProductDescription = model.ProductDescription,
Model = model.Model,
ProductPrice = model.ProductPrice,
AvailableForSale = model.AvailableForSale,
Shippable = model.Shippable,
AvailableStock = model.AvailableStock,
ProductPicture = model.ProductPicture
};
SetCateProductViewBag(prod.CategoryId);
if (model.ImageUpload != null && model.ImageUpload.ContentLength > 0)
{
var UploadDir = "~/Uploads";
var ImagePath = Path.Combine(Server.MapPath(UploadDir), model.ImageUpload.FileName);
var ImageUrl = Path.Combine(UploadDir, model.ImageUpload.FileName);
model.ImageUpload.SaveAs(ImagePath);
prod.ProductPicture = ImageUrl;
}
productContext.product.Add(prod);
productContext.SaveChanges();
return RedirectToAction("CategoryIndex");
}
return View(model);
}
CateProdViewModel class:
public class CateProdViewModel
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string CategoryDescription { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public int AvailableStock { get; set; }
public decimal ProductPrice { get; set; }
public string Model { get; set; }
public bool AvailableForSale { get; set; }
public bool Shippable { get; set; }
[DataType(DataType.ImageUrl)]
public string ProductPicture { get; set; }
public int SelectedValue { get; set; }
[DataType(DataType.Upload)]
public HttpPostedFileBase ImageUpload { get; set; }
public virtual Category category { get; set; }
[Display(Name="Product Categories")]
public virtual ICollection<Category> categories { get; set; }
}
Entity classes for Category and Product:
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public int AvailableStock { get; set; }
public decimal ProductPrice { get; set; }
public string Model { get; set; }
public bool AvailableForSale { get; set; }
public bool Shippable { get; set; }
public string ProductPicture { get; set; }
public int CustomerId { get; set; }
public int CategoryId { get; set; }
public virtual Category category { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string CategoryDescription { get; set; }
public virtual ICollection<Product> product { get; set; }
}
My View:
#model SmartShoppingCart.Models.CateProdViewModel
#{
ViewBag.Title = "CreateProduct";
}
<h2>Create Product</h2>
<form action="" method="post" enctype="multipart/form-data">
<div>
#Html.LabelFor(m=>m.CategoryId,"Category")
#Html.DropDownList("CategoryId",ViewBag.categories as SelectList, string.Empty)
#Html.ValidationMessageFor(m=>m.CategoryId)
</div>
<div>
#Html.HiddenFor(m=>m.CategoryId)
</div>
<div>
#Html.LabelFor(m=>m.ProductName)
#Html.TextBoxFor(m=>m.ProductName)
#Html.ValidationMessageFor(m=>m.ProductName)
</div>
<div>
#Html.LabelFor(m=>m.ProductDescription)
#Html.TextBoxFor(m=>m.ProductDescription)
#Html.ValidationMessageFor(m=>m.ProductDescription)
</div>
<div>
#Html.LabelFor(m=>m.Model)
#Html.TextBoxFor(m=>m.Model)
#Html.ValidationMessageFor(m=>m.Model)
</div>
<div>
#Html.LabelFor(m=>m.ProductPrice)
#Html.TextBoxFor(m=>m.ProductPrice)
#Html.ValidationMessageFor(m=>m.ProductPrice)
</div>
<div>
#Html.LabelFor(m=>m.AvailableForSale)
#Html.TextBoxFor(m=>m.AvailableForSale)
#Html.ValidationMessageFor(m=>m.AvailableForSale)
</div>
<div>
#Html.LabelFor(m=>m.Shippable)
#Html.TextBoxFor(m=>m.Shippable)
#Html.ValidationMessageFor(m=>m.Shippable)
</div>
<div>
#Html.LabelFor(m=>m.AvailableStock)
#Html.TextBoxFor(m=>m.AvailableStock)
#Html.ValidationMessageFor(m=>m.AvailableStock)
</div>
<div>
#Html.LabelFor(m=>m.ImageUpload)
#Html.TextBoxFor(m => m.ImageUpload, new {type="file" })
</div>
<div>
<button type="submit" value="Add" ></button>
</div>
</form>
private void SetCateProductViewBag(int? CateId = null)
{
if (CateId == null)
{
ViewBag.Categories = new SelectList(productContext.category, "CategoryId", "CategoryName");
}
else
{
ViewBag.Categories = new SelectList(productContext.category.ToArray(),"CategoryId","CategoryName",CateId);
}
}
Your error occurs because your model is null on post back. The model is null because it contains a property named Model and the parameter name of the action method is also named model which is confusing the poor DefaultModelBinder. Either change the name of the property to something else or change the parameter name in your post action method to something else.
Why don't you change the first action to:
public ActionResult CreateProduct(CateProdViewModel model)
{
SetCateProductViewBag();
return View(model);
}
And your DefaultModelBinder will instantiate the model so it's never null.
Other than that, I need to know what you mean by saying When i execute my Create method. Since you don't have a Create method there. You have CreateProduct and you got 2 of them. Is this a POST or GET request?
I am new to MVC so here is my issue. I have a parent view and a partial view which is rendered inside it.
As a model I pass an IEnumerable to the parent view. I iterate thru the list and for each item i render the partial view having the list item as model. On the partial view I have a form which on a submit triggers a child action which accepts as parameter the type of the list. My issue is that the param comes always with it's values null.
These are my domain entities.
public class Contact
{
[Key]
public int IdContacts { get; set; }
public int UserId { get; set; }
public int CreatedByUserId { get; set; }
public int UpdatedByUserId { get; set; }
public int AddressId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public long HomePhone { get; set; }
public long? WorkPhone { get; set; }
public bool IsRelated { get; set; }
public bool IsEmergency { get; set; }
public bool IsDeceased { get; set; }
public string Relationship { get; set; }
public DateTime EntryDate { get; set; }
public DateTime? ChangeDate { get; set; }
}
public class Address
{
[Key]
public int IdAddresses { get; set; }
public int CountryId { get; set; }
public int StateId { get; set; }
public int CreatedByUserId { get; set; }
public int UpdatedByUserId { get; set; }
public string Street { get; set; }
public string City { get; set; }
public long PostalCode { get; set; }
public string OfficeOrApt { get; set; }
public int AreaGroup { get; set; }
public int? SuperUserId { get; set; }
public DateTime EntryDate { get; set; }
public DateTime? ChangeDate { get; set; }
}
This is my view model
public class ContactModel
{
public Contact Contact { get; set; }
public Address Address { get; set; }
public bool IsEditMode { get; set; }
}
This is my parent view
#model IEnumerable<Cricket.WebUI.Models.ContactModel>
#{
ViewBag.Title = "Contacts";
}
<h2 align="center">
Contacts</h2>
<div class="iggr_container">
<div class="iggr_clear">
</div>
#foreach (var contact in Model)
{
ViewDataDictionary dictionary = new ViewDataDictionary();
string guid = (Guid.NewGuid()).ToString();
dictionary.Add("prefix", guid);
#Html.Hidden("Contact.Index", guid)
#Html.Hidden("Address.Index", guid)
#Html.Partial("ContactSummary", contact, dictionary)
<hr style="width: 385px;" align="left" />
}
</div>
This is my partial view
#model Models.ContactModel
<div class="iggr_clear">
</div>
#if (!Model.IsEditMode)
{
var prefixContact = "Contact[" + ViewData["prefix"] + "].";
var prefixAddress = "Address[" + ViewData["prefix"] + "].";
using (Html.BeginForm("Edit", "Contacts", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
TempData["ContactModelObject"] = Model;
<div>
<b>
#Html.Hidden(prefixContact + "FirstName", Model.Contact.FirstName);
#Html.Hidden(prefixContact + "LastName", new { name = "Contact" + ViewData["prefixContact"] + ".LastName" })
#Html.LabelFor(m => m.Contact.FirstName, Model.Contact.FirstName)
#Html.LabelFor(m => m.Contact.LastName, Model.Contact.LastName)
</b>
<div>
<span>Home Phone:</span>
#Html.Hidden(prefixContact + "HomePhone", Model.Contact.HomePhone)
#Html.LabelFor(m => m.Contact.HomePhone, Model.Contact.HomePhone.ToString())</div>
<div>
<span>Work Phone:</span>
#Html.Hidden(prefixContact + "WorkPhone", Model.Contact.WorkPhone)
<span>
#if (Model.Contact.WorkPhone == null)
{
#:N/A
}
else
{
#Html.LabelFor(m => m.Contact.WorkPhone, Model.Contact.WorkPhone.ToString())
}
</span>
</div>
<div>
#Html.Hidden(prefixAddress + "Street", Model.Address.Street)
#Html.LabelFor(m => m.Address.Street, Model.Address.Street)
</div>
<div>
#Html.Hidden(prefixAddress + "City", Model.Address.City)
#Html.Hidden(prefixAddress + "PostalCode", Model.Address.PostalCode)
#Html.LabelFor(m => m.Address.City, Model.Address.City) #Html.LabelFor(m => m.Address.PostalCode, Model.Address.PostalCode.ToString())
</div>
#Html.Hidden(prefixContact + "IsRelated", Model.Contact.IsRelated)
#if (Model.Contact.IsRelated)
{
<b>Family</b>
if (Model.Contact.IsEmergency || Model.Contact.IsDeceased)
{
<b>/</b>
}
}
#Html.Hidden(prefixContact + "IsEmergency", Model.Contact.IsEmergency)
#if (Model.Contact.IsEmergency && !Model.Contact.IsDeceased)
{
<b>Emergency</b>
}
#Html.Hidden(prefixContact + "IsDeceased", Model.Contact.IsDeceased)
#if (Model.Contact.IsDeceased)
{
<b>Deceased</b>
}
<input type="submit" name="button" value="Edit" class="iggr_button_edit" style="margin-left: 150px;" />
</div>
}
}
And finally my controller class
public class ContactsController : Controller
{
[HttpGet]
public ActionResult Index()
{
ContactsRepository repository = new ContactsRepository();
CDE.User user = (from u in repository.Users where u.IdUsers == 1 select u).FirstOrDefault();
var contacts = (from u in repository.Users
join c in repository.Contacts on new { UserId = u.IdUsers } equals new { UserId = c.UserId }
join a in repository.Addresses on new { AddressId = c.AddressId } equals new { AddressId = a.IdAddresses }
select new ContactModel()
{
Contact = c,
Address = a
}).AsEnumerable();
return View("Contacts", contacts);
}
[HttpPost]
[ActionName("Edit")]
[#ActionFilter(ActionInvokerType = "button", ActionInvokerValue = "Edit")]
public ViewResult Edit(ContactModel contact)
{
//Here contact.Contact comes as null same for contact.Address
return View("Contacts", null);//Ignore this line
}
}
I have a feeling that your prefix structure is interfering with the binding that normally happens in MVC. You could use a custom model binding implementation, or find a way to do without your prefixes.