I have created a ViewModel which contains other models
namespace CreatingLayout.Models
{
public class ViewModel
{
public tbl_Roles Roles { get; set; }
public tbl_Category Category { get; set; }
public tbl_Course Course { get; set; }
public tbl_User User { get; set; }
}
}
And this sub Model has some Required Field field like tbl_User class has following required fields:
public partial class tbl_User
{
[Required(ErrorMessage = "Please enter {0}")]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter {0}")]
public string Password{ get; set; }
//And many more with Required Field
}
Now my problem is, in my View i am not passing data for all this required fields but only for few. So once i click to submit button, i am calling my Controller Action Method and i am checking for ModelState errors
public ActionResult AdminInsertion(ViewModel objViewModel)
{
if (ModelState.IsValid)
{
//IF No Errors do something
}
return View();
}
So everytime my Modelstate.Isvalid is returning false due to Validation Error which i gave in those 4 classes i.e., tbl_Roles, tbl_Category, tbl_Course and tbl_User. So what i want is to Clear all those error for which i am not passing Data, something like
//Here i want to go to individual classes ex: item should contains all tbl_Roles column fields
foreach(var item in ModelState.Keys)
{
//Now i want to Get Key items of each individual class which is causing Error
foreach(string Key in item)
{
//Here i am going to clear all those error for which i am not passing data
ModelState[Key].Error.Clear();
}
}
But my problem is, i am not able to access fields of tbl_Roles, tbl_Category, tbl_Course and tbl_User. ,How can clear only selected field errors here?
Related
I have a model with validation properties. On a post back to server I would like to check if model values are empty or for example dropdownlist should not be have 0 or something!
Depending on how you have created your models you could do the validation on he model properties.
Example:
public class Foo
{
public long Id { get; set; }
[Required(ErrorMessage = "Please enter name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please select a gender")]
public string SelectedGenderId{ get; set; }
}
Then in your view under your dropDownList:
#Html.ValidationMessageFor(m=> m.SelectedGenderId)
EDIT thanks to #danludwig:
Then in your controller you can validate the state of your model but doing this:
if (ModelState.IsValid)
{
// do your updates/saves
}
I hope that's is what you are after.
i want to perform a database action on login click.
So i am using stored procedure for getting the data, but here i am facing some issues regarding model exception.
public ActionResult Login(UserInfo model, string returnUrl)
{
if (ModelState.IsValid)
{
List<UserInfo> loginDetails = dbContext.Database.SqlQuery<UserInfo>
("exec spGetloginUserInfo #username,#password", new SqlParameter("#username", model.username), new SqlParameter("#password", model.password)).ToList();
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
My Model
public class UserInfo
{
public string usertype { get; set; }
public string username { get; set; }
public string password { get; set; }
public bool active { get; set; }
public DateTime lastmodifieddate { get; set; }
public string modifiedby { get; set; }
public bool RememberMe { get; set; }
}
The exception thrown is
An exception of type
'System.Data.Entity.ModelConfiguration.ModelValidationException'
occurred in EntityFramework.dll but was not handled in user code
Please let me know where i am doing wrong and also whether my approach is right?
And also is there any other way for database interaction other that stored procedure approach.
ModelState.AddModelError throws an error but your client/javascript/views did not catch that error.
Here is a link on how to implement similar error handling in views.
ASP.NET MVC 2 Model Errors with Custom Exceptions
Also, make sure the your model UserInfo has valid data for each properties
Login(UserInfo model, string returnUrl) <<-- the model of type UserInfo
i have come across a strange behaviour when trying to get a SelectList to display correctly when using the Html.EditorForModel().
I have the following Model:
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
public string Gender { get; set; }
[UIHint("SelectList")]
public SelectList AvailibleGender { get; set; }
}
As you can see, I have a SelectList item that holds the values to get put into the Gender string. I have overriden the SelectList EditorTemplate, which for now has a simple script tag showing an alert box.
When I use EditorFor(m=>AvailableGender), my alert box fires, which means the editor correctly chose my SelectList template.
When I use EditorForModel(), my alert box does not fire.
If I change the model as follows:
[UIHint("SelectList")]
public string AvailibleGender { get; set; }
..then my SelectList template does get hit, and I see the alert message.
So it looks like there is something specifically blocking the SelectList.
In case it is something to do with specific custom types, I tried adding an object.cshtml file, but this doesn't get invoked either. so it seems that the SelectList type is getting lost somewhere.
Does anyone have any ideas on how to get the Select List working with EditorForModel()?
Here are my two classes:
class Company
{
public int ID{ get; set; }
public string CompanyName{ get; set; }
}
public class Division
{
public int ID{ get; set; }
public string DivisionName{ get; set; }
public virtual Company Company { get; set; }
}
I have a strongly typed EDIT view for Division, with an EditorFor for DivisionName and a HiddenFor for ID.
The problem I have is when I hit save, the Controller action gets the Division object with an NULL for Company property. When the model is not valid, and the View is returned with that object, I can no longer extract the company name in the view using #Model.Company.CompanyName.
How can I fix this?
If you don't include Company data in your view (as input fields), then nothing about Company will be posted back.
If Company is just for "display only", then re-populate it in your controller during the post before your model is returned in the view.
public ActionResult MyAction(Division model)
{
// ...
// Repopulate Company
model.Company = new Company() { ... };
return View(model);
}
I am trying to find the best way to use MVC for models which are only partially edited.
Below is an simple example.
Model
using System.ComponentModel.DataAnnotations;
public class SimpleModel
{
public int Id { get; set; }
public string Parent { get; set; }
[Required]
public string Name { get; set; }
}
View
using System.ComponentModel.DataAnnotations;
public class SimpleModel
{
public int Id { get; set; }
public string Parent { get; set; }
[Required]
public string Name { get; set; }
}
Controller
using System.Web.Mvc;
public class SimpleController : Controller
{
public ActionResult Edit(int id)
{ return View(Get(id)); }
[HttpPost]
public ActionResult Edit(int id, SimpleModel model)
{
if (model.Name.StartsWith("Child")) //Some test that is not done client-side.
{
Save(model);
//Get the saved data freshly.
//model = Get(id);
}
else
{
ModelState.AddModelError("", "Name should start with 'Child'");
}
//Is this the way to set the Parent property?
//var savedModel = Get(id);
//model.Parent = savedModel.Parent;
return View(model);
}
//Mock a database.
SimpleModel savedModel;
private void Save(SimpleModel model)
{ savedModel = new SimpleModel() { Id = model.Id, Name = model.Name }; }
private SimpleModel Get(int id)
{
if (savedModel == null)
{ return new SimpleModel() { Id = id, Parent = "Father", Name = "Child " + id.ToString() }; }
else
{ return new SimpleModel() { Id = savedModel.Id, Parent = "Father", Name = savedModel.Name }; }
}
}
The Name field is editable. The Parent field is only for reference and should not be updated. Therefore, it is rendered using DisplayFor.
Upon post, I receive a model with property Parent set to null. That's no problem as it will not be saved. However, when I simply return the received model to the view, the Parent field will no longer be displayed. When the model is valid, I can easily get it again from the database and thus get the Parent field's value back.
When the model is not valid, I would like to allow the user to correct input and attempt to save once more. There, I the received model's values that are input should be used, but the displayed values should be shown as well.
In reality, there are many more fields to be shown for reference, most often from different database entities than the one that is being edited.
I have seen suggestions to pass the fields as hidden fields in the view, but I feel very reluctant to read data from the client that should not be updated.
Is there a more elegant way to do this than copying these values into the model manually or passing them as hidden fields?
What about giving those un-editable properties to another model and let it take care of those properties?
View Model
public class PersonViewModel
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public PersonDetailsModel DetailsModel { get; set; }
}
Details Model
public class PersonDetailsModel
{
public string Mother { get; set; }
public string Father { get; set; }
public PersonDetailsModel() { }
public PersonDetailsModel(int personId)
{
// pull required model data from databases
var db = DBParentContext;
Mother = db.Parent.Where(m => m.ChildId == personId)
Father = db.Parent.Where(m => m.ChildId == personId)
}
}
Controller
public class PersonController : Controller
{
[HttpPost]
public ActionResult Edit(PersonViewModel viewModel)
{
viewModel.DetailsModel = new PersonDetailsModel(viewModel.Id)
if (ModelState.IsValid) {
// ~
}
return View(viewModel)
}
}
View
#model PersonViewModel
#Html.DisplayFor(m => m.DetailsModel.Mother)
#Html.DisplayFor(m => m.DetailsModel.Father)
#Html.TextBoxFor(m => m.FirstName)
#Html.TextBoxFor(m => m.LastName)
Since details like your Mother are un-editable then they're not really part of the "Edit" model, so I'd box like that away and try to let something else take care of them.
If you aren't going to update the Parent field, then it really doesn't matter if it's a hidden or not, since you won't update it on post.
I would use the hidden in this case, just make sure not to update that field.