In my MedicalProductController I am trying to convert a MedicalProduct (model class) named "product" into IEnumerable<MedicalProduct> so it can be passed to GetMedicalProductViewModelList, which will return an IEnumerable<MedicalProductViewModel> (viewModel class).
I am trying to keep SQL calls to a minimum. as per advice of other stackoverflow members.
But "product" fails to turn into IEnumerable<MedicalProduct> in my MedicalProductController Class
MedicalProductController
public class MedicalProductController : Controller
{
private MvcMedicalStoreDb _db = new MvcMedicalStoreDb();
// other CRUD code omitted for brevity.
// =============
// Edit HttpGet
// =============
public ActionResult Edit(int id = 0)
{
MedicalProduct product = _db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
var productList = product as IEnumerable<MedicalProduct>;
var viewModelList = GetMedicalProductViewModelList(productList);
return View(viewModelList);
}
// =============
// Edit HttpPost
// =============
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MedicalProduct product)
{
if (ModelState.IsValid)
{
_db.Entry(product).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
var productList = product as IEnumerable<MedicalProduct>;
var viewModel = GetMedicalProductViewModelList(productList);
return View(viewModel);
}
// =====================
// Mapper Class Helper
// =====================
public IEnumerable<MedicalProductViewModel> GetMedicalProductViewModelList(IEnumerable<MedicalProduct> productList)
{
var brandList = _db.Brands.ToArray();
var mapper = new MedicalProductMapper();
return mapper.MapMedicalProductViewModel(productList, brandList);
}
And just in case it is helpful, here is the mapping class:
MedicalProductMapper
public class MedicalProductMapper
{
// =====================
// Model to ViewModel
// =====================
public IEnumerable<MedicalProductViewModel> MapMedicalProductViewModel(IEnumerable<MedicalProduct> medicalProductList, IEnumerable<Brand> brandList)
{
var brandSelectListItem = brandList.Select(b => new SelectListItem()
{
Text = b.Name,
Value = b.Name
});
var viewModelList = medicalProductList.Select(p => new MedicalProductViewModel()
{
BrandID = p.BrandID,
BrandName = brandList.SingleOrDefault(b => b.ID == p.BrandID).Name,
BrandSelectListItem = brandSelectListItem,
ID = p.ID,
Price = p.Price,
Name = p.Name
});
return viewModelList;
}
// =====================
// ViewModel to Model
// =====================
public MedicalProduct MapMedicalProduct(MedicalProductViewModel VM)
{
var model = new MedicalProduct()
{
Name = VM.Name,
Price = VM.Price,
BrandID = VM.BrandID
};
return model;
}
}
Instead of
var productList = product as IEnumerable<MedicalProduct>;
Try
var productList = new List<MedicalProduct> { product };
You can't cast to IEnumerable<MedicalProduct> if it's not an IEnumerable, what I did in this example is first create a new List of type MedicalProduct and then add the product to the List.
List is one of the types that implement IEnumerable
Related
I'm able to return a list from controller below to view:
public ActionResult FillSegment(int siteid)
{
var segment = db.Segment.Where(c => c.SiteID == siteid).Select(x => new
{
SegmentID = x.SegmentID,
SegmentName = x.SegmentName
});
return Json(segment, JsonRequestBehavior.AllowGet);
}
But if i want to do the query operation in other classes, and i call the class from FillSegment Action, how it should return?
Controller:
public ActionResult FillSegment(int siteid)
{
SegmentHelper segmenthelper = new SegmentHelper();
return Json(segmenthelper.FillSegment(siteid), JsonRequestBehavior.AllowGet);
}
segmenthelper Class:
public List<string> FillSegment(int siteid)
{
using (DBConnection db = new DBConnection())
{
var segment = db.Segment.Where(c => c.SiteID == siteid).Select(x => new
{
SegmentID = x.SegmentID,
SegmentName = x.SegmentName
});
return segment.ToList(); <-- Cannot convert generic list to generic list?
}
}
In such cases it is probably better to introduce a ViewModel class and return it. You might want to use some mapping library.
public class SegmentViewModel
{
public string SegmentID { get; set; } //not sure if it of string type
public string SegmentName { get; set; }
}
public IEnumerable<SegmentViewModel> FillSegment(int siteid)
{
using (DBConnection db = new DBConnection())
{
return db.Segment.Where(c => c.SiteID == siteid).Select(x => new SegmentViewModel
{
SegmentID = x.SegmentID,
SegmentName = x.SegmentName
});
}
}
// you can also use JsonResult instead of ActionResult
public JsonResult FillSegment(int siteid)
{
SegmentHelper segmenthelper = new SegmentHelper();
return Json(segmenthelper.FillSegment(siteid), JsonRequestBehavior.AllowGet);
}
The Select statement will return you a sequence of anonymous objects with properties SegmentID and SegmentName and they cannot be converted to list of strings.
You had to change return type of FillSegment.
Im not 100% sure but i think this should work
Controller:
public ActionResult FillSegment(int siteid)
{
SegmentHelper segmenthelper = new SegmentHelper();
return Json(segmenthelper.FillSegment(siteid), JsonRequestBehavior.AllowGet);
}
Segmenthelper Class:
public list<Segment> FillSegment(int siteid)
{
using (DBConnection db = new DBConnection())
{
var segment = db.Segment.Where(c => c.SiteID == siteid).Select(x => new
{
SegmentID = x.SegmentID,
SegmentName = x.SegmentName
}).toList();
return segment;
}
}
Hi,
I'am pretty new in ASP.NET MVC, and I have some problem.
I make some program that searching product in data base, if click
button "end", program show me list of my previously searched products.**
This is my code from controler:
private ProductManager pm = new ProductManager();
private PointOfSaleContext db = new PointOfSaleContext();
public ActionResult Detail(SearchProduct productCode)
{
if (!ModelState.IsValid)
{
return RedirectToAction("Index", "Home");
}
else
{
//searching product in data base
var searchingProduct = db.Products.Where(p => p.ProductId == productCode.Code).Single();
int id = searchingProduct.ProductId;
//add searched product to model
SingleProduct product = new SingleProduct();
product.product = searchingProduct;
//I send product Id to ProductManager method
pm.AddToList(id);
return View(product);
}
}
public ActionResult List()
{
//object of model
AllItems all = new AllItems();
//
all.productList = pm.list;
return View(all);
}
This is my class, where I created Product list
public class ProductManager
{
private PointOfSaleContext db = new PointOfSaleContext();
public List<product> list;
public ProductManager()
{
list = new List<product>();
}
public void AddToList(int id)
{
var product = db.Products.Where(p => p.ProductId == id).SingleOrDefault();
list.Add(product);
}
}
View of controller List:
#model PointOfSale.ViewModel.AllItems
<ul>
#foreach (var p in Model.productList)
{
<li> #p.ProductName <li>
}
</ul>
My ViewModel:
public class AllItems
{
public List<Product> productList { get; set; }
}
public class SingleProduct
{
public Product product;
}
Problem is those, that I can't read data from ICollection in AddToList View.
More precisely- Model in View List is empty and I don't know why.
I'm new with MVC Razor. I'm trying to insert to de DB but I get this expection:
There is no ViewData item of type 'IEnumerable' that has the key "Projects"
I'm using EntityFramework (DB First) as my MVC model. I get this error in my DropDownList, I retrieve data with Linq to populate my DropDwonList, this is my code:
Controller:
// GET: /Actividad/
public ActionResult AgregarActividad()
{
var db = new WTMEntities();
var proyectos = (from pro in db.Proyecto
select new
{
Id = pro.Id,
Nombre = pro.Nombre
}).ToList();
ViewData["Projects"] = new SelectList(proyectos.Select(i => i.Nombre));
return View();
}
[HttpPost]
public ActionResult AgregarActividad(Actividades act)
{
if (ModelState.IsValid)
{
var db = new WTMEntities();
var proyectos = (from pro in db.Proyecto
select new
{
Id = pro.Id,
Nombre = pro.Nombre
}).ToList();
ViewData["Projects"] = new SelectList(proyectos.Select(i => i.Nombre));
var actividad = db.Set<Actividades>();
actividad.Add(act);
db.SaveChanges();
return View();
}
else
{
return View();
}
}
View
<div>
<p>Proyecto</p>
#Html.DropDownList(
"Projects", null, string.Empty, new { style = "width: 200px;" })
</div>
If someone could give me a hand, I will really appreciate!!
Your post method isn't repopulating the ViewData.
I've modified your code... find below.
[HttpPost]
public ActionResult AgregarActividad(Actividades act)
{
var db = new WTMEntities();
var proyectos = (from pro in db.Proyecto
select new
{
Id = pro.Id,
Nombre = pro.Nombre
}).ToList();
ViewData["Projects"] = new SelectList(proyectos.Select(i => i.Nombre));
if (ModelState.IsValid)
{
var actividad = db.Set<Actividades>();
actividad.Add(act);
db.SaveChanges();
return View();
}
else
{
return View();
}
}
I'm new to MVC5,I had troubles with the ViewBag
I want to display the ViewBag.products.Doc_Title,ViewBag.products.Doc_Content,ViewBag.products.Doc_Id and so on
but i don't know how to do it
it display what i don't want
can anybody help me?
Here is my controller
public class DocProductController : Controller
{
private IDocProductRepository repository;
private IDocMainRepository repositoryMain;
public DocProductController(IDocProductRepository docProductRepository, IDocMainRepository docMainRepository)
{
this.repository = docProductRepository;
this.repositoryMain = docMainRepository;
}
public ActionResult List()
{
var products = from docProduct in repository.DocProduct
join docMain in repositoryMain.DocMain
on docProduct.Doc_Id equals docMain.Doc_Id
select new { DocMainTitle = docMain.Doc_Title, DocProductContent = docProduct.DocProduct_Content };
ViewBag.products = products;
//DocProductListView model = new DocProductListView
//{
// DocProduct = repository.DocProduct
// .Join(repositoryMain.DocMain,
// docProduct => docProduct.Doc_Id,
// docMain => docMain.Doc_Id,
// (docProduct, docMain) => new { a = docMain.Doc_Id, b = docProduct.Doc_Id })
// .OrderByDescending(n => n.)
//};
return View();
}
}
//if my view is this
<div>
#foreach (dynamic p in ViewBag.products)
{
<div>
#*#p.Doc_Id*#
#p
</div>
}
</div>
//The page display:
{ DocMainTitle = name1, DocProductContent = content1 }
{ DocMainTitle = name2, DocProductContent = content2 }
//=====================================
//I want to display it like this
//#p.DocMainTitle #p.DocProductContent
//but it works error
<ul>
<li><h1>name1</h1>content1</li>
<li><h1>name2</h1>content2</li>
</ul>
Controller:
public class DocProductController : Controller
{
private IDocProductRepository repository;
private IDocMainRepository repositoryMain;
public DocProductController(IDocProductRepository docProductRepository,
IDocMainRepository docMainRepository)
{
this.repository = docProductRepository;
this.repositoryMain = docMainRepository;
}
public ActionResult DocProductList()
{
var model = new DocProductViewModel(repository);
//link tables(entities) part will be in the repository functions
//from docProduct in repository.DocProduct
//join docMain in repositoryMain.DocMain
//on docProduct.Doc_Id equals docMain.Doc_Id
//select new { DocMainTitle = docMain.Doc_Title,
//DocProductContent = docProduct.DocProduct_Content };
return View(model);
}
}
ViewModel:
public class DocProductViewModel
{
private IDocProductRepository repository;
public DocProductViewModel(IDocProductRepository docProductRepository)
{
this.repositoryMain = docMainRepository;
}
public IList<DocProduct> DocProductList
{
get
{
return repository.GetList();
}
}
}
Views in ~/views/DocProduct folder add view DocProductList.cshtml:
#model DocProductViewModel
<ul>
#foreach(var v in model.DocProductList)
{
<li><h1>#v.Doc_Title</h1>#v.Doc_Id</li>
}
</ul>
you can simply pass it to view like this:
return View(products);
and in your view define model of this type.
First you make a view model and strongly type you view with that model:
public class DocumentViewModel
{
public int Doc_Id {get;set;}
public string DocMainTitle { get; set;}
public string DocProductContent {get; set;}
}
In your action do like this:
public ActionResult List()
{
var products = (from docProduct in repository.DocProduct
join docMain in repositoryMain.DocMain
on docProduct.Doc_Id equals docMain.Doc_Id
select new DocumentViewModel { DocMainTitle = docMain.Doc_Title, DocProductContent = docProduct.DocProduct_Content }).ToList<DocumentViewModel>(;
ViewBag.products = products;
return View(products );
}
then in your view:
#model List<DocumentViewModel>
#foreach(var item in Model)
{
<h1>#item.DocMainTitle</h1>
<a>#item.Doc_Id</a>
}
UPDATE
IN your scenario, you want to pass multiple view models to a view, so you have to make another view model and create your two viewmodels as properties in it and pass this custom view model to view,
do like this:
public class CustomViewModel
{
public DocumentViewModel docViewModel {get;set;}
public SceondViewModel sceond {get;set;}
}
and in action:
var products = (from docProduct in repository.DocProduct
join docMain in repositoryMain.DocMain
on docProduct.Doc_Id equals docMain.Doc_Id
select new DocumentViewModel { DocMainTitle = docMain.Doc_Title, DocProductContent = docProduct.DocProduct_Content }).ToList<DocumentViewModel>();
CustomViewModel custom = new CustomViewModel();
custom.docViewModel =products ;
custom.sceond = secondviewmodel;
return View(custom);
In view, you model will be:
#model CustomViewModel
#
{
var firstViewModel = Model.docViewModel;
var secondViewModel = Model.sceond;
}
Why wont my changes persist to db after I click save.
Product Repository:
public class ProductRepository
{
NorthwindDataContext context = new NorthwindDataContext();
public IList<EditableProduct> All()
{
return (from product in context.Products
select new EditableProduct {
ProductID = product.ProductID,
ProductName = product.ProductName,
UnitPrice = product.UnitPrice.HasValue ? product.UnitPrice.Value : default(decimal),
UnitsInStock = product.UnitsInStock.HasValue ? product.UnitsInStock.Value : default(int),
Discontinued = product.Discontinued,
LastSupply = DateTime.Today
}).ToList();
}
public EditableProduct One(Func<EditableProduct, bool> predicate)
{
return All().Where(predicate).FirstOrDefault();
}
public void Update(EditableProduct product)
{
EditableProduct target = One(p => p.ProductID == product.ProductID);
if (target != null)
{
target.ProductName = product.ProductName;
target.UnitPrice = product.UnitPrice;
target.UnitsInStock = product.UnitsInStock;
target.Discontinued = product.Discontinued;
target.LastSupply = product.LastSupply;
}
}
public void Insert(EditableProduct product)
{
product.ProductID = All().OrderByDescending(p => p.ProductID).First().ProductID + 1;
All().Insert(0, product);
}
public void Delete(EditableProduct product)
{
EditableProduct target = One(p => p.ProductID == product.ProductID);
if (target != null)
{
All().Remove(target);
}
}
}
Controller:
public partial class GridController : Controller
{
ProductRepository productRepository = new ProductRepository();
public ActionResult EditingBatch()
{
return View();
}
[HttpPost]
[GridAction]
public ActionResult _SelectBatchEditing()
{
return View(new GridModel(productRepository.All()));
}
[HttpPost]
[GridAction]
public ActionResult _SaveBatchEditing([Bind(Prefix = "inserted")]IEnumerable<EditableProduct> insertProducts,
[Bind(Prefix = "updated")]IEnumerable<EditableProduct> updatedProducts,
[Bind(Prefix = "deleted")]IEnumerable<EditableProduct> deletedProducts)
{
if (insertProducts != null)
{
foreach (var product in insertProducts)
{
productRepository.Insert(product);
}
}
if (updatedProducts != null)
{
foreach (var product in updatedProducts)
{
var target = productRepository.One(p => p.ProductID == product.ProductID);
if (target != null)
{
target.ProductName = product.ProductName;
target.UnitPrice = product.UnitPrice;
target.UnitsInStock = product.UnitsInStock;
target.LastSupply = product.LastSupply;
target.Discontinued = product.Discontinued;
productRepository.Update(target);
}
}
}
if (deletedProducts != null)
{
foreach (var product in deletedProducts)
{
productRepository.Delete(product);
}
}
return View(new GridModel(productRepository.All()));
}
}
You seem to be using the code from our sample application which indeed does not update the database. It merely updates the data in memory so every single user browsing the demos sees only his changes.
To make it work you need to update the database. The actual implementation depends on the framework you are using for data access. For example for Linq To SQL you should use the SubmitChanges method. You can check this code library project which updates the underlying database.