I had a view model in that viewmodel i created two different instances using same model like this:
public ClaimViewModel()
{
engineClaim = new ClaimModel();
boatClaim = new ClaimModel();
}
public ClaimModel engineClaim { get; set; }
public ClaimModel boatClaim { get; set; }
I had properties in ClaimModel like this:
[Required]
public string Complaint { get; set; }
[RequiredIf("isEngineClaim", true , ErrorMessage = "Required")]
public string Cause { get; set; }
[Required]
public string Correction { get; set; }
public bool isEngineClaim { get; set; }
And in controller i am loading the index page like this
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
ClaimViewModel claim = new ClaimViewModel();
claim.engineClaim = new Models.ClaimModel();
claim.engineClaim.isEngineClaim = true;
claim.boatClaim = new Models.ClaimModel();
claim.boatClaim.isEngineClaim = false;
return View("Index", claim);
}
Now my problem is the requiredif validation is not working though the 'isEngineClaim' property is different for two instances. I am following this link
And moreover i had placed the hidden field of 'isEngineClaim' in my view also. But the requiredifvalidation is not working can anyone suggest me the solution.
Related
I have looked through a ton of tutorials and suggestions on how to work with DropDownList in MVC. I was able to get most of it working, but the selected item is not saving into the database. I am using MVC 3 and Razor for the view.
My DropDownList is getting created with the correct values and good looking HTML. When I set a breakpoint, I can see the correct selected item ID in the model getting sent to controller. When the view goes back to the index, the DropDownList value is not set. The other values save just fine.
Here are the related views. The DropDownList is displaying a list of ColorModel names as text with the ID as the value.
public class ItemModel
{
[Key]
public int ItemID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ColorModel Color { get; set; }
}
public class ItemEditViewModel
{
public int ItemID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int ColorID { get; set; }
public IEnumerable<SelectListItem> Colors { get; set; }
}
public class ColorModel
{
[Key]
public int ColorID { get; set; }
public string Name { get; set; }
public virtual IList<ItemModel> Items { get; set; }
}
Here are the controller actions.
public ActionResult Edit(int id)
{
ItemModel itemmodel = db.Items.Find(id);
ItemEditViewModel itemEditModel;
itemEditModel = new ItemEditViewModel();
itemEditModel.ItemID = itemmodel.ItemID;
if (itemmodel.Color != null) {
itemEditModel.ColorID = itemmodel.Color.ColorID;
}
itemEditModel.Description = itemmodel.Description;
itemEditModel.Name = itemmodel.Name;
itemEditModel.Colors = db.Colors
.ToList()
.Select(x => new SelectListItem
{
Text = x.Name,
Value = x.ColorID.ToString()
});
return View(itemEditModel);
}
[HttpPost]
public ActionResult Edit(ItemEditViewModel itemEditModel)
{
if (ModelState.IsValid)
{
ItemModel itemmodel;
itemmodel = new ItemModel();
itemmodel.ItemID = itemEditModel.ItemID;
itemmodel.Color = db.Colors.Find(itemEditModel.ColorID);
itemmodel.Description = itemEditModel.Description;
itemmodel.Name = itemEditModel.Name;
db.Entry(itemmodel).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(itemEditModel);
}
The view has this for the DropDownList, and the others are just EditorFor().
#Html.DropDownListFor(model => model.ColorID, Model.Colors, "Select a Color")
When I set the breakpoint on the db.Color.Find(...) line, I show this in the Locals window for itemmodel.Color:
{System.Data.Entity.DynamicProxies.ColorModel_0EB80C07207CA5D88E1A745B3B1293D3142FE2E644A1A5202B90E5D2DAF7C2BB}
When I expand that line, I can see the ColorID that I chose from the dropdown box, but it does not save into the database.
You do not need to set the whole Color object. Just set the ColorId property.
Change
itemmodel.Color = db.Colors.Find(itemEditModel.ColorID);
To
itemmodel.ColorId = itemEditModel.ColorID;
Edit
Note that your database does not store the whole object. The Color object in ItemModel is just a convenient way to access the ColorModel entity that is assosiated by a foreign key.
According to convention, the name of the foreign key property should be ColorId. Add this int property in your ItemModel class.
I'm using Scaffolding in ASP.Net, I've a Model called "Page" which has attributes as follows
public class Page
{
private DateTime _Created_at = DateTime.Now;
private bool _IsActive = true;
public int ID { get; set; }
public string Code { get; set; }
[Required]
[DisplayName("Parent Code")]
public string ParentCode { get; set; }
[Required]
public string Title { get; set; }
************
}
Here, During Create Method, I'm updating Code attributes as follows
public ActionResult Create(Page page)
{
if (ModelState.IsValid)
{
page.Code = page.Url.Replace(" ", string.Empty);
page.IsActive = true;
db.Pages.Add(page);
db.SaveChanges();
return RedirectToAction("Details", new { id = page.ID });
}
return View(page);
}
Now, Problem is, I don't want this Code value change during Update method, I'm not included it in Edit form. But still it's updating 'NULL' value if I update.
I tried [Bind(Exclude = "Code")] for Page class, But no use.
You need a hidden field for code in your edit view. Use #Html.HiddenFor(model => model.Code).
I'm building an MVC 3 website. I have a model looking like this:
public class Survey
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime DateStart { get; set; }
public DateTime DateEnd { get; set; }
// Not in view
public DateTime DateCreated { get; set; }
// Not in view
public DateTime DateModified { get; set; }
}
Based on this I also have a View Model to edit the survey information:
public class SurveyEditViewModel
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime DateStart { get; set; }
public DateTime DateEnd { get; set; }
}
When the user finishes editing I would like to persist the changes. Here's my controller post action:
[HttpPost]
public ActionResult Edit(SurveyEditViewModel model)
{
// Map the view model to a domain model using AutoMapper
Survey survey = Mapper.Map<SurveyEditViewModel, Survey>(model);
// Update the changes
_repository.Update(survey);
// Return to the overview page
return RedirectToAction("Index");
}
In my repository (it's a generic one for now) I have the following code:
public void Update(E entity)
{
using (ABCDataContext context = new ABCDataContext())
{
context.Entry(entity).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
}
When this executes I get the following error: "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."
I guess this was to be expected. Mapping from the view model to the model doesn't give me a complete Survey object.
I could modify my controller to look like this. And then it works:
[HttpPost]
public ActionResult Edit(SurveyEditViewModel model)
{
// Map the model to a real survey
survey = _repository.Find(model.Id);
survey.Name = model.Name;
survey.Description = model.Description;
survey.DateStart = model.DateStart;
survey.DateEnd = model.DateEnd;
// Update the changes
_repository.Update(survey);
// Return to the overview page
return RedirectToAction("Index");
}
But I was wondering if a better way is available?
[HttpPost]
public ActionResult Edit(SurveyEditViewModel model)
{
// Fetch the domain model to update
var survey = _repository.Find(model.Id);
// Map only the properties that are present in the view model
// and keep the other domain properties intact
Mapper.Map<SurveyEditViewModel, Survey>(model, survey);
// Update the changes
_repository.Update(survey);
// Return to the overview page
return RedirectToAction("Index");
}
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
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.