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
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?
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);
}
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>
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");
}
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>