I have been struggling to create a Dropdown list which will display Country names from database.
The situation is:
I have a Controller "AdvertisementController", a model"AdvertisementModel" and a View "Create.cshtml".
On the view I need to create a dropdown list which will display country names from database.
I know the good thing will be to create a Viewmodel. But how shall I do that?
A bunch of code will be much appreciated. :)
I have the following code but it shows 'null reference' error.
Viewmodel:
public class CommunicationViewModel
{
public string CategoryID { get; set; }
public IEnumerable<SelectListItem> CategoryList { get; set; }
}
Model:
public class CreateAdModel
{
[Required]
[Display(Name = "Title")]
public string Title { get; set; }
[Required]
[Display(Name = "Description")]
[DataType(DataType.MultilineText)]
public string Message { get; set; }
[Required]
[Display(Name = "Ad type")]
public string AdType { get; set; }
[Required]
[Display(Name = "Ad category")]
public string AdCategory { get; set; }
public CommunicationViewModel categories { get; set; }
}
Controller:
public ActionResult Index()
{
var query = db.AddCategory.Select(c => new SelectListItem
{
Value = c.ID.ToString(),
Text = c.Name
}
);
var model = new CommunicationViewModel { CategoryList = query.AsEnumerable() };
return View(model);
}
Razor:
#Html.DropDownListFor(m=>m.categories.CategoryID,Model.categories.CategoryList,"--Select one--")
This may help you. Drop down for roles when adding users. very simple tutorial
http://rtur.net/blog/post/2009/06/03/Quick-and-dirty-role-management-in-ASPNET-MVC.aspx
Related
I am building an e-store with ASP.NET Core. I've created CRUD operations to add my products and save it to the database, it is working fine. Then I wanted to save the orders from the customers to my database, sadly I couldn't manage to do so.
When I click a button, it saves the order to the database and sends the customer to the thank you page.
Can you please check my code and tell me where am going wrong.
This is my OrderController:
[HttpPost]
public async Task<IActionResult> PlaceOrder([FromBody] Order model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var order = new Order
{
OrderDate = DateTime.Now,
Name = model.Name,
Address = model.Address,
Email = model.Email,
PhoneNo = model.PhoneNo
};
var orderDetails = new List<OrderDetails>();
foreach (var item in model.OrderDetails)
{
orderDetails.Add(new OrderDetails
{
ProductId = item.ProductId,
// Quantity = item.Quantity,
// Price = item.Price,
Order = order
});
}
using (var context = new AppDbContext(_dbContextOptions))
{
context.Order.Add(order);
context.OrderDetails.AddRange(orderDetails);
await context.SaveChangesAsync();
}
// returns a HTTP 200 OK response to the client indicating that the operation was successful.
return Ok();
}
and this is the button from my view:
<p>
<a asp-controller="Order" asp-action="PlaceOrder" class="btn btn-primary addToCart">Place my order</a>
</p>
Order class:
public class Order
{
public Order()
{
OrderDetails = new List<OrderDetails>();
}
public int Id { get; set; }
[Display(Name = "Order No")]
public string OrderNo { get; set; }
[Required]
public string Name { get; set; }
[Required]
[Display(Name = "Phone Number")]
public string PhoneNo { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Address { get; set; }
[Display(Name = "Today's Date")]
public DateTime OrderDate { get; set; }
public virtual List<OrderDetails> OrderDetails { get; set; }
}
Order details class
public class OrderDetails
{
public int Id { get; set; }
[Display(Name = "Order")]
public int OrderId { get; set; }
[Display(Name = "Product")]
public int ProductId { get; set; }
[ForeignKey("OrderId")]
public Order Order { get; set; }
[ForeignKey("PorductId")]
public Product Product { get; set; }
}
I am new to MVC4, I want to implement WebGrid, When retrieving data for model.activity its working fine. For clarification i am combining two tables to get data.
Here its showing error like this
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List
Please help me to solve this problem. thanks in advance
public class MyViewModel
{
public List<Tbl_Activity> activity;
public List<Tbl_Clarification> clarification;
}
public class ClarificationEntities
{
public int ClrNo { get; set; }
public Nullable<int> DailyReportID { get; set; }
public string ReportingMgrComment { get; set; }
public Nullable<System.DateTime> CreatedOn { get; set; }
public string StaffComment { get; set; }
public Nullable<int> CreatedBy { get; set; }
public string Name { get; set; }
}
I am adding data to the model to display in WebGrid
MyViewModel model = new MyViewModel();
model.activity = db.Tbl_Activity.Where(x => x.DailyReportID == driD).ToList();
model.clarification = (from c in db.Tbl_Clarification
join u in db.Tbl_Users on c.CreatedBy equals u.CreatedBy
where c.DailyReportID == did
select new ClarificationEntities
{
ClrNo = c.ClrNo,
ReportingMgrComment = c.ReportingMgrComment,
StaffComment = c.StaffComment,
DailyReportID=c.DailyReportID,
Name=u.Name
}).ToList();
return View(model);
MyViewModel has the wrong type for the clarification field...
try the following instead
public class MyViewModel
{
public List<Tbl_Activity> activity;
public List<ClarificationEntities> clarification;
}
I have a class, which has 8 props / 8 columns in DB. But on a Edit page, i dont want to show the AddedDate or UserID field, since i dont want user to change it.
public class Voucher
{
public int ID { get; set; }
public string Title { get; set; }
public string SiteName { get; set; }
public string DealURL { get; set; }
public DateTime AddedDate { get; set; }
public DateTime? ExpirationDate { get; set; }
public string VoucherFileURL { get; set; }
public Guid UserID { get; set; }
}
Here is what I have for Edit controller:
// POST: /Voucher/Edit/5
[HttpPost]
public ActionResult Edit(Voucher voucher)
{
if (ModelState.IsValid)
{
string[] excludeProperties = { "AddedDate", "UserID" };
UpdateModel(ModelState, "", null, excludeProperties);
db.Entry(voucher).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(voucher);
}
On Edit page, once i click on submit, i got the following error: System.Data.SqlServerCe.SqlCeException: An overflow occurred while converting to datetime.
Seems like the AddedDate didn't get excluded from the view model and triggered the error.
Would you please let me know how to fix it? Thanks!
public ActionResult Edit([Bind(Exclude = "AddedDate")]Voucher voucher)
no luck either
You are still passing in Voucher which could contain that field in it. I'm not sure what you are trying to accomplish with the UpdateModel here if you are already passing in a Voucher object?
Pass in Voucher, set it to modified and save it. If you want to use whats in the database then you'll have to
Load the object from the database
UpdateModel and exclude the properties
Save your entity.
You could simply use a View Model and post that.
public class Voucher
{
public int ID { get; set; }
public string Title { get; set; }
public string SiteName { get; set; }
public string DealURL { get; set; }
public DateTime? ExpirationDate { get; set; }
public string VoucherFileURL { get; set; }
public Guid UserID { get; set; }
}
and then load up your object from the db":
var voucher = db.Vouchers.Where(o=>o.ID==voucherViewModel.Id);
//manually copy the fields here then save it
//copy
db.SaveChanges();
I could use some help implementing #Html.DropDownListFor. My objective is to filter the list of Products by Category.
This code will display a list box:
#model IEnumerable<Sample.Models.Product>
#{
List<Sample.Models.Category> list = ViewBag.Categories;
var items = new SelectList(list, "CategoryID", "CategoryName");
}
#Html.DropDownList("CategoryID", items)
But I'm having trouble getting #Html.DropDownListFor to work:
#model IEnumerable<Sample.Models.Product>
#{
List<Sample.Models.Category> list = ViewBag.Categories;
var items = new SelectList(list, "CategoryID", "CategoryName");
}
#Html.DropDownListFor(???, #items)
I could use some help constructing the Linq portion of #Html.DropDownListFor.
Here is the model:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public int CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public Decimal? UnitPrice { get; set; }
public short UnitsInStock { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Your view is strongly typed to a collection of products so I suppose that you need a drop down for each product. If this is the case an editor template would work:
#model IEnumerable<Sample.Models.Product>
#Html.EditorForModel()
And then inside ~/Views/Shared/EditorTemplates/Product.cshtml
#model Sample.Models.Product
#{
List<Sample.Models.Category> list = ViewBag.Categories;
var items = new SelectList(list, "CategoryID", "CategoryName");
}
#Html.DropDownListFor(x => x.CategoryID, #items)
My recommendation:
Extend your LINQ data context class with a static function to return a SelectList of all categories, and use Html.DropDownList() to display this list.
Then, add a controller for this same Action that accepts category ID and return the IEnumerable<Product> list that corresponds to that category.
here is another way to do what you want.
In the model I have two entries
public class Product
{
public int CategoryID { get; set; }
public IEnumerable<SelectListItem> Category { get; set; }
}
I then populate the SelectlestItem either from a database or statically.
In the Index.cs controller
product model = new product();
model.Category = <whereever you generated the data>;
return View(model);
In the View
#using (Html.BeginForm("Edit", "Subject", FormMethard.Post, new { id = "genform"}))
{
<div class="vertical-space spaced-field">#Html.DropDownListFor(m => m.CategoryID, model,Category)</div>
I found many articles on this but still I don´t know how exactly to do this. I am trying to create my own blog engine, I have View for create article (I am using EF and Code first) and now I must fill number of category in which article should be add but I want to change it to dropdownlist with names of categories. My model looks this:
public class Article
{
public int ArticleID { get; set; }
[Required]
public string Title { get; set; }
[Required]
public int CategoryID { get; set; }
public DateTime Date { get; set; }
[Required()]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }
public virtual Category Category { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
I know I must use Enum (or I think) but I am not exactly sure how. I don´t know which tutorial from that I found is best for me.
Edit:
Thanks for your answers but I found something else. I am trying this:
This is my model:
public class Article
{
[Key]
public int ArticleID { get; set; }
[Display(Name = "Title")]
[StringLength(30, MinimumLength = 5)]
[Required]
public string Title { get; set; }
public DateTime Date { get; set; }
public int CategoryID { get; set; }
[Required()]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }
public Category Category { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
public class Category
{
[Key]
public int CategoryId { get; set; }
[Required]
public string CategoryName { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
This is my controller to create article:
public ActionResult Vytvorit()
{
IEnumerable<Category> categories = GetCaregories();
var view = View(new Article() { Categories = categories });
view.TempData.Add("Action", "Create");
return view;
}
private static IEnumerable<Category> GetCaregories()
{
IEnumerable<Category> categories;
using (BlogDBContext context = new BlogDBContext())
{
categories = (from one in context.Categories
orderby one.CategoryName
select one).ToList();
}
return categories;
}
private Category GetCategory(int categoryID)
{
return db.Categories.Find(categoryID);
}
//
// POST: /Clanky/Vytvorit
[HttpPost]
public ActionResult Vytvorit(Article newArticle)
{
try
{
if (newArticle.CategoryID > 0)
{
newArticle.Category = GetCategory(newArticle.CategoryID);
}
if (TryValidateModel(newArticle))
{
db.Articles.Add(newArticle);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
newArticle.Categories = GetCaregories();
var view = View(newArticle);
view.TempData.Add("Action", "Create");
return view;
}
}
catch
{
return View();
}
}
And this is part of my view:
#Html.DropDownListFor(model => model.CategoryID, new SelectList(Model.Categories,"CategoryID","CategoryName"))
#Html.ValidationMessageFor(model => model.CategoryID)
I have problem with NullReferenceExeption but I don´t know why. Can I do it this way? It looks very easy for me.
Your model seems quite strange. It contains properties such as CategoryID and Category which seem redundant. It also contains a SelectListItem collection property called Categories. So, is this a model or a view model? It looks quite messed up. Let's assume it's a model. In this case it would more likely look something like this:
public class Article
{
public int ArticleID { get; set; }
[Required]
public string Title { get; set; }
public DateTime Date { get; set; }
[Required()]
[DataType(DataType.MultilineText)]
[AllowHtml]
public string Text { get; set; }
public virtual Category Category { get; set; }
public IEnumerable<Category> Categories { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Category
{
public int CategoryID { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
Now that the model is clear we could define a view model which will be passed to the view. A view model is a class which is specifically designed for the view. So depending on what you intend to put in this view you define it in this view model. So far you have talked only about a drop down, so let's do it:
public class ArticleViewModel
{
public int SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
and then we have a controller:
public class ArticlesController: Controller
{
private readonly IArticlesRepository _repository;
public ArticlesController(IArticlesRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
Article article = _repository.GetArticle();
ArticleViewModel viewModel = Mapper.Map<Article, ArticleViewModel>(article);
return View(viewModel);
}
}
So the controller uses a repository to fetch the model, maps it to a view model (in this example I use AutoMapper) and passes the view model to the view which will take care of showing it:
#model AppName.Models.ArticleViewModel
#using (Html.BeginForm())
{
#Html.DropDownListFor(
x => x.SelectedCategoryId,
new SelectList(Model.Categories, "Value", "Text"),
"-- Select category --"
)
<input type="submit" value="OK" />
}
I have gone through this as well and I have to agree that at first it seems odd (In my explanation I'm assuming you want to select one category only, but the process is very similar for a multi select).
Basically you need to perform 3 steps:
1:
You need two properties on your viewmodel
One will hold the selected category id (required for postback) and the other will a SelectList with all possible categories:
public class Article
{
public int ArticleID { get; set; }
public int CategoryID { get; set; }
public SelectList Categories { get; set; }
}
2:
Also before passing the viewmodel on to the view you need to initialize the SelectList (Best practivce is to prepare as much as possible before passing a model into the view):
new SelectList(allCategories, "CategoryID", "Name", selectedCategoryID)
3:
In the view you need to add a ListBox for the CategoryID property, but using the Categories property too fill the ListBox with values:
#Html.ListBoxFor(model => model.CategoryID , Model.Categories)
Thats it! In the post back action of the controller you will have the CategoryID set. You can do whatever you need to from there to persist things in your db.