MVC display foreign key from another table - asp.net-mvc

Controller:
public ActionResult Details(int id)
{
ViewBag.AccountType = new BusinessLayer.AccountTypeManager().GetAccountTypes();
return View(new BusinessLayer.AccountManager().getAccount(id));
}
View:
<div class="display-label">Account Type</div>
<div class="display-field">#Html.DisplayFor(modelItem => modelItem.AccountType)</div><br />
This current view displays the AccountType ID. How can I display the AccountType Name which is being passed by the ViewBag.AccountType (IEnumerable)

something like following
<div class="display-label">Account Type</div>
<div class="display-field">#Html.DisplayFor(modelItem => modelItem.AccountType)</div>
#{
var TypeNames = ViewBag.AccountType as IEnumerable<string>;
foreach(var item in TypeNames)
{
<div>item</div>
}
}
Mode elegant way
public class AccountTypeVewModel
{
public IEnumerable<string> typeNames { get; set; }
public Account account { get; set; }
}
controller
public ActionResult Details(int id)
{
AccountTypeVewModel model = new AccountTypeVewModel();
model.typeNames = new BusinessLayer.AccountTypeManager().GetAccountTypes();
model.account = new BusinessLayer.AccountManager().getAccount(id);
return View(model);
}
view
<div class="display-label">Account Type</div>
<div class="display-field">#Html.DisplayFor(modelItem => modelItem.account.AccountType)</div>
#{
foreach(var item in Model.typeNames)
{
<div>item</div>
}
}

Related

How to post view model to controller

I am trying to create a view that takes a view model, simply has an int property and a list of child model, with int; string; string properties.
What i am trying to do is everytime user clicks an "add line" button, i am creating a new child model in my view model list, letting user edit the properties and then want to post back to my controller but no matter what, it is always empty.
I know this must be simple but has me stumped for hours today? Is there some magic that needs to happen?
Any help appreciated.
My Controller:
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class EmployeeUploadController : Controller
{
// GET: EmployeeUpload
public ActionResult EmployeeUpload()
{
var vm = new EmployeeBulkUpload { UploadedBy = 12345 };
vm.Employees.Add(new EmployeeBulkUploadItem { Id = 1, JobTitle = "Labourer", Name = "Jimmy" });
return View(vm);
}
[HttpPost]
[ActionName("EmployeeUpload")]
public ActionResult EmployeeUploadPost(EmployeeBulkUpload vm)
{
return View(vm);
}
}
}
My Model:
using System.Collections.Generic;
namespace WebApplication1.Models
{
public class EmployeeBulkUpload
{
public EmployeeBulkUpload()
{
Employees = new List<EmployeeBulkUploadItem>();
}
public int UploadedBy { get; set; }
public List<EmployeeBulkUploadItem> Employees { get; set; }
}
public class EmployeeBulkUploadItem
{
public int Id { get; set; }
public string Name { get; set; }
public string JobTitle { get; set; }
}
}
My "Container" view:
#using WebApplication1.Models
#model WebApplication1.Models.EmployeeBulkUpload
#{
ViewBag.Title = "EmployeeUpload";
}<div>
#using (Html.BeginForm("EmployeeUpload", "EmployeeUpload", FormMethod.Post))
{
<h2>EmployeeUpload</h2>
<button>Add New</button>
foreach(EmployeeBulkUploadItem emp in Model.Employees)
{
Html.RenderPartial("_EmployeeUploadItem", emp);
}
<input type="submit" name="SaveButton" value="Save" />
}
</div>
My Item Partial view:
#model WebApplication1.Models.EmployeeBulkUploadItem
<li>
#Html.LabelFor(x => x.Id)
#Html.EditorFor(x => x.Id)
#Html.LabelFor(x => x.Name)
#Html.EditorFor(x => x.Name)
#Html.LabelFor(x => x.JobTitle)
#Html.EditorFor(x => x.JobTitle)
</li>
I can load with one record and post straight back but is always empty in my Controller EmployeeUploadPost method?

How to update list withing viewmodel in view? Passing data from view to controller

I am passing viewmodel to create view where I select few properties from dropdown list and then I create new model in database. The problem is that I have to select a product from dropdown list and after button click add product to list(which is defined in model). You can see the code bellow, I am having the problem of passing id of product as it is always null
SellsViewModel:
public class SellsViewModel
{
public List<Center> center { get; set; }
public List<Leader> leader { get; set; }
public List<Member> member { get; set; }
public List<Group> group { get; set; }
public Sell sell { get; set; }
public Guid productSelection { get; set; }
public IEnumerable<Product> product { get; set; }
public IEnumerable<Product> selectedProducts { get; set; }
}
Create.cshtml
#model Medical.ViewModels.SellsViewModel
#{
var addproduct = Model.product.Select(product => new SelectListItem
{
Text = product.Name,
Value = product.Id.ToString()
});
}
...
<div class="form-group">
<div align="right" class="col-md-2">
<b>Delivery</b>
</div>
<div align="center" class="col-md-2">
#Html.DropDownListFor(m => m.productSelection, addproduct, "-- Choose product --")
</div>
<div class="col-md-2">
<a asp-action="AddProducttoSell" method="post" asp-route-id="#Model.productSelection" class="btn btn-primary">Add</a>
</div>
</div>
Controller:
[HttpGet]
public IActionResult AddProducttoSell(Guid id)
{
var sProduct = _context.Products.FirstOrDefault(p => p.Id == id);
svm.selectedProducts.ToList().Add(sProduct);
return RedirectToAction(nameof(Create));
}
Basically, I want that when I choose product in view, I add it to selectedProducts list in viewmodel, and than return it to view. Afterwards, I will submit new model to database.
I got your example to work in Core.
First, I followed this tutorial, making appropriate changes:
https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro?view=aspnetcore-2.2
This is the code, starting with my Model-codeFirst and my ViewModel:
namespace SOPassDataViewToController.Models
{
public class Sell
{
public int ID { get; set; }
public string Name { get; set; }
}
}
namespace SOPassDataViewToController.Models
{
public class Product
{
public int Value { get; set; }
public string Text { get; set; }
}
public class SellsViewModel
{
public List<Product> Products { get; set; }
public int productSelection { get; set; }
}
}
Here is my Controller code:
[HttpPost]
public IActionResult AddProducttoSell(SellsViewModel sellsviewmodel)
{
//put breakpoint here to interrogate sellsviewmodel-productSelection
var viewModel = PrepViewModel();
return View(viewModel);
}
// GET: Sells
// I'm using this method instead of AddProducttoSell
//public async Task<IActionResult> Index()
public IActionResult Index()
{
var viewModel = PrepViewModel();
//return View(await _context.Sells.ToListAsync());
return View(viewModel);
}
public SellsViewModel PrepViewModel()
{
//prepping view model
//sending view model to view
SellsViewModel viewModel = new SellsViewModel();
viewModel.Products = new List<Product>();
var products = _context.Sells.ToList();
foreach (Sell product in products)
{
var eachProduct = new Product();
eachProduct.Value = product.ID;
eachProduct.Text = product.Name;
viewModel.Products.Add(eachProduct);
}
return viewModel;
}
Here is my view Index.cshtml:
#model SOPassDataViewToController.Models.SellsViewModel
#*need the form tag*#
<form asp-action="AddProducttoSell">
<div class="form-group">
<div align="right" class="col-md-2">
<b>Delivery</b>
</div>
<div align="center" class="col-md-2">
#*#Html.DropDownListFor(m => m.productSelection, addproduct, "-- Choose product --")*#
#Html.DropDownListFor(m => m.productSelection, new SelectList(Model.Products, "Value", "Text"))
</div>
<div class="col-md-2">
#*took out will need to put back asp-route-id="#Model.productSelection"*#
#*<a asp-action="AddProducttoSell" method="post" asp-route-id="#Model.productSelection" class="btn btn-primary">Add</a>*#
<div class="form-group">
<input type="submit" value="AddProducttoSell" class="btn btn-primary" />
</div>
</div>
</div>
</form>
#section scripts
{
#*//the natural progression for what you are doing is to change the href not the asp-route-id, because
//href is what gets rendered. So you can do the following--and tighten it up--
//you can also use FormCollection, or even possibly window.location, but the best way from Microsoft's
//tutorial is to use a model like my previous post*#
<script>
$(document).ready(function () {
$("#DropDownElement").change(function () {
$("#PostingElement").attr("href", "/Sells/Edit/" + $("#DropDownElement").val());
})
});
</script>
}
My Action looks like the following. I use Edit instead of AddProducttoSell
// GET: Sells/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var sell = await _context.Sells.FindAsync(id);
if (sell == null)
{
return NotFound();
}
return View(sell);
}

Pass 2 parameters into view

I've got a view where I create new object and pass it to another view:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,carID,DateFrom,DateTo,UserID")] Reservation reservation)
{
if (ModelState.IsValid)
{
return RedirectToAction("ChooseCars",reservation);
}
return View(reservation);
}
in "ChooseCars" I have:
public ActionResult ChooseCars(Reservation reservation)
{
var reservations = db.Reservations.ToList();
var cars = db.Cars.ToList();
var reservationsResult = reservations.Where(res => res.DateFrom <= reservation.DateFrom && res.DateTo >= reservation.DateTo);
if (reservationsResult != null)
{
emptyCars = cars.Where(c => !reservationsResult.Any(y => y.carID == c.ID));
cars = emptyCars.ToList();
}
return View(cars);
}
and in that "ChooseCars" view I populate table with list of Cars that haven't been reserved.. Now I need to somehow pass that reservation and chosen car (by id) to some method where I create new "reservation" object containing carId.
What is the best way to do that?
I wrote a method, but I have no idea how to route those parameters to it:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddReservation([Bind(Include = "ID,carID,DateFrom,DateTo,UserID")] Reservation reservation, int? id)
{
Reservation finalReservation = new Reservation(id, reservation.DateFrom, reservation.DateTo, reservation.UserID);
db.Reservations.Add(finalReservation);
return View();
}
How it looks:
Your editing data, so the first thing is to create a view model(s) representing want you want to edit/display in the view. In your case you need the start and end dates, a collection of Car and the selected car.
public class ReservationVM // add validation and display attributes as appropriate
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int? SelectedCar { get; set; }
public IEnumerable<Car> AvailableCars { get; set; }
}
And your controller methods will be
[HttpGet]
public ActionResult Create()
{
ReservationVM model = new ReservationVM();
return View(model);
}
[HttpPost]
public ActionResult Create(ReservationVM model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var availableCars = ... // your query to load the collection of cars basd on the dates
if (!availableCars.Any())
{
ModelState.AddModelError("", "There are no cars available for these dates");
return View(model);
}
model.AvailableCars = availableCars;
return View("SelectCar", model);
}
[HttpPost]
public ActionResult Confirm(ReservationVM model)
{
// Initialize new Reservation, save and redirect
Reservation reservation = new Reservation()
{
StartDate = model.StartDate,
EndDate = model.EndDate,
CarId = model.SelectedCar.Value,
UserId = ... // current user?
};
db.Reservations.Add(reservation);
db.SaveChanges();
return RedirectToAction(....);`
}
And the views will be
Create.cshtml
#model ReservationVM
...
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.StartDate)
#Html.TextBoxFor(m => m.EndDate)
<input type="submit" value="Next" />
}
SelectCar.cshtml
#model ReservationVM
....
<table>
#foreach(var car in Model.AvailableCars)
{
<tr>
<td>#car.Make</td>
<td>#car.Model</td>
....
<td>
#using (Html.BeginForm("Confirm", "Home", new { StartDate = Model.StartDate, EndDate = Model.EndDate, SelectedCar = car.ID }))
{
<input type="submit" value="Reserve" />
}
</td>
</tr>
}
</table>

Create ActionResult for save throws error saying The model item passed into the dictionary is of type

Although this error is very common in the forum, but i am not able to understand how to fix it in my project. I am new to MVC framework.
View code:-
#model ClassifiedProject.Models.CreateAdvertVM
<div class="editor-label">#Html.LabelFor(model => model.AdvTitle) <i>(E.g. Old Samsung Galaxy Tab 2)</i></div>
<div class="editor-field">
#Html.EditorFor(model => model.AdvTitle)
#Html.ValidationMessageFor(model => model.AdvTitle)
</div>
<div class="editor-label">#Html.LabelFor(model => model.AdvDescription)</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.AdvDescription)
#Html.ValidationMessageFor(model => model.AdvDescription)
</div>
<div class="editor-label">#Html.Label("Advertisement Category")</div>
<div class="editor-label">
#Html.DropDownListFor(model => model.SelectedCategoryId, Model.Categories, new { #class = "ddlcs" })
#Html.ValidationMessageFor(model => model.SelectedCategoryId)
</div>
<p><input type="submit" value="Save" /></p>
Controller code of Save button actionresult:-
[HttpPost]
public ActionResult Create(TR_ADVERTISEMENT tr_advert)
{
if (ModelState.IsValid)
{
tr_advert.CreatedDate = tr_advert.ModifiedDate = DateTime.Now;
if (tr_advert.IsPriceOnRequest)
{
tr_advert.CurrencyID = 0;
tr_advert.Price = 0;
}
db.ADVERTISEMENT.Add(tr_advert);
db.SaveChanges();
return RedirectToAction("Index");
}
Controller code for the form in render stage:-
// GET: /Advert/Create
public ActionResult Create()
{
var model = new CreateAdvertVM();
ViewBag.Message = "Post New Advertisement.";
////Render Category DDL
var cat = from s in db.CategoryDbSet
where s.IsActive == true
orderby s.CatName
select new { s.CatID, s.CatName };
var catListItems = cat.ToList().Select(c => new SelectListItem
{
Text = c.CatName,
Value = c.CatID.ToString()
}).ToList();
catListItems.Insert(0, new SelectListItem { Text = "[--Select the category--]", Value = "" });
model.Categories = catListItems;
return View(model);
ViewModel inherited from EF class:-
[NotMapped]
public class CreateAdvertVM : TR_ADVERTISEMENT
{
[DisplayName("Category")]
[Required]
public int? SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
EF Model:-
public class TR_ADVERTISEMENT
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int AdvID { get; set; }
[Required]
[DisplayName("Sub Category")]
public int SubCatID { get; set; }
public int CurrencyID { get; set; }
[DisplayName("Price on request")]
public bool IsPriceOnRequest { get; set; }
[DisplayName("Posted Date")]
[DisplayFormat (DataFormatString="{0:dd-MM-yyyy}")]
public Nullable<System.DateTime> CreatedDate { get; set; }
public Nullable<System.DateTime> ModifiedDate { get; set; }
}
On the save button click, i have to save the data into the tr_advertisement table using the EF model.
Please suggest the solution to this problem.
It is the model type you are passing into your Create ActionMethod.
public ActionResult Create(TR_ADVERTISEMENT tr_advert)
should be
public ActionResult Create(CreateAdvertVM tr_advert)
I am assuming that if your model is not valid, you are passing it back further down in your action result (which you are not showing), such as
Return View(tr_advert)
But, you are passing the wrong model type at that point for that view.
EDIT
I would also update your view model so that instead of inheriting from the EF class, simply include the EF class as a property.
public class CreateAdvertVM
{
[DisplayName("Category")]
[Required]
public int? SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
public TR_ADVERTISEMENT tr_advert{get;set;}
}
This will make it so that your save code in the Create method can still be used with only minor modifications
[HttpPost]
public ActionResult Create(CreateAdvertVM model)
{
if (ModelState.IsValid)
{
model.tr_advert.CreatedDate = model.tr_advert.ModifiedDate = DateTime.Now;
if (model.tr_advert.IsPriceOnRequest)
{
model.tr_advert.CurrencyID = 0;
model.tr_advert.Price = 0;
}
db.ADVERTISEMENT.Add(model.tr_advert);
db.SaveChanges();
return RedirectToAction("Index");
}

how can get data in drop down list from data base in mvc3.?

I am designing a simple webpage using MVC3 in asp.net. I prepared a database using Sql Server, and i have attached this database in App_Data. There is a table employee in that database.
i want to get name of employee in a drop down list. so i can select name of employee.
so please suggest me what will be model,view and controller code for accessing employee name in drop down list.
I would start by designing a view model which will hold the data:
public class EmployeeViewModel
{
public string SelectedEmployeeName { get; set; }
public IEnumerable<SelectListItem> Employees { get; set; }
}
then a controller:
public class HomeController: Controller
{
public ActionResult Index()
{
IEnumerable<Employee> employees = GetEmployeesFromDb();
var model = new EmployeeViewModel
{
Employees = employees.Select(x => new SelectListItem
{
Value = x.Name,
Text = x.Name
})
};
return View(model);
}
[HttpPost]
public ActionResult Index(EmployeeViewModel model)
{
return Content("Selected employee name: " + model.SelectedEmployeeName, "text/plain");
}
}
and finally the strongly typed view:
#model EmployeeViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(
x => x.SelectedEmployeeName,
new SelectList(Model.Employees, "Value", "Text")
)
<input type="submit" value="OK" />
}
1) Create a Method to populate the list from DB
2) Set a ViewModel to hold the List and selected value
//MODEL
public List<SelectListItem> CategoriesSelectList()
{
var query = from c in _yourRepository.GetAll()
select c;
List<SelectListItem> obj = new List<SelectListItem>();
foreach (var item in query)
{
var result = new SelectListItem();
result.Text = item.name;
result.Value = item.id.ToString();
obj.Add(result);
}
return obj;
}
//VIEWMODEL
public class ViewModel
{
[DisplayName("Category")]
public int categoryId { get; set; }
public List<SelectListItem> CategoryList()
{
return new Model().CategoriesSelectList();
}
}
//CONTROLLER
public ActionResult Create()
{
//set the id for the VIEWMODEL property, if necesary
var e = new ViewModel();
e.categoryId = 1;//set the selected value
return View(e);
}
//VIEW
<div class="editor-label">
<%: Html.LabelFor(model => model.categoryId) %>
</div>
<div class="editor-field">
<%: Html.DropDownListFor(model => model.categoryId,Model.CategoryList()) %>
<%: Html.ValidationMessageFor(model => model.categoryId) %>
</div>

Resources