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);
}
Related
#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 trying to find the best solution so that on any given page I always have a login model, a register model and another model (or more). The login and register models are found in the navbar and the footer respectively on each page.
Specifically I have a situation whereby I have a course page which populates from a table depending on which course has been looked up via the url inputted. So the page loads the course page model. On the same page in the header and footer I need to have the login and register forms which both require their own models.
The course page is populated using a foreach loop:
COURSE PAGE VIEW (SHORTENED):
#model IEnumerable<oltinternational_mvc.Models.Course_page>
#{
Layout = "~/Views/Shared/_courselayout.cshtml";
foreach (var cpage in Model) { ViewBag.Title = #cpage.page_title; }
}
#foreach (var cpage in Model)
{
if (cpage.template_type == 2)
{
<div id="main_container">
<article class="content">
<h1>
#cpage.Title
</h1>
<section>
#Html.Raw(cpage.main_image)
<h3>
#cpage.Country
</h3>
<p>#cpage.intro_1</p>
#if (!string.IsNullOrEmpty(cpage.intro_2))
{
<p>#cpage.intro_2</p>
}
#if (!string.IsNullOrEmpty(cpage.intro_3))
{
<p>#cpage.intro_3</p>
}
View sample pages
#if (!string.IsNullOrEmpty(cpage.website_button))
{
#Html.Raw(cpage.website_button)
}
else {
Licensing options
}
#Html.Raw(cpage.popup_script)
<div class="clearfloat"></div>
</section>
</article>
</div>
The controller is as follows:
public ActionResult Course_page(string id)
{
string abbrev = id;
var cpage = from c in db.Course_page
select c;
if (!String.IsNullOrEmpty(abbrev))
{
cpage = cpage.Where(x => x.abbrev.Contains(abbrev));
}
return View(cpage);
}
and the model:
[Table("course_page")]
public class Course_page
{
[Key]
public int CourseID { get; set; }
public string Meta { get; set; }
public string Title { get; set; }
public string Country { get; set; }
public string main_image { get; set; }
public string list_1 { get; set; }
public string list_2 { get; set; }
public string list_3 { get; set; }
public string list_4 { get; set; }
public string list_5 { get; set; }
public string list_6 { get; set; }
public string list_7 { get; set; }
public string list_8 { get; set; }
public string list_9 { get; set; }
public string list_10 { get; set; }
public string testim_1 { get; set; }
public string testim_2 { get; set; }
public string testim_3 { get; set; }
public string course_site { get; set; }
public string popup_script { get; set; }
public string abbrev { get; set; }
public string page_title { get; set; }
public int template_type { get; set; }
public string intro_1 { get; set; }
public string intro_2 { get; set; }
public string intro_3 { get; set; }
public string website_button { get; set; }
}
In the navbar I have the following list item which references my ajax logging in form:
<li class="login">
<span>Login</span>
#using (Ajax.BeginForm("login", "Account", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "login_box"
}, new { id = "login_box" }))
{
#Html.Partial("_login")
}
</li>
Which loads this form:
#model myproject_mvc.Models.LoginViewModel
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div id="login_box">
<div class="sign_up_box"> Sign up in seconds </div>
#Html.ValidationSummary(true)
#Html.AntiForgeryToken()
<div class="login_box_lower">
<p class="login_box_or">or</p>
<p class="login_sign_in">Sign in</p>
<div style="position:relative;">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { placeholder = "Email", maxlength = "18", #class = "login_username clearable" } })
<span class="login_username_icon"></span>
</div>
<div style="position:relative;">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { placeholder = "Password", maxlength = "18", #class = "login_pw clearable" } })
<span class="login_pw_icon"></span>
</div>
Login
<div class="clearfloat"></div>
Forgot password?
</div>
</div>
With the following model:
public class LoginViewModel
{
[Required]
[Display(Name = "Email")]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
The same situation is such for the Register form in the footer, which uses the RegisterViewModel. Bearing in mind the actual form above for logging in isn't completed yet, it just directs to a /account url for now.
I've tried a few solutions I've found online but can't seem to make any of them work, I think in part because I am using foreach to populate the view from the course page model. I don't see how I can use a viewmodel because I am using a foreach loop on the page.
What I would like to know is what is the best way to deal with this situation?
You should create and use viewmodel(s) instead of directly referencing your objects. Perhaps something like this.
Create a new class, MyViewModel.cs (or whatever name you prefer)
public class MyViewModel
{
public IEnumerable<oltinternational_mvc.Models.Course_page> CoursePages { get; set; }
public myproject_mvc.Models.LoginViewModel { get; set; }
}
Now in your view, instead of referencing the models directly, you would reference the view model. Something like #model myproject_mvc.ViewModels.MyViewModel
In your foreach loop you would so something like this #foreach (var cpage in Model.CoursePages)
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 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())