how to remove the collection from modelstate MVC - asp.net-mvc

I have a class Person. Which is associated with the Students. now students class contain a datefield "CreatedOn".
class Person
{
String Name;
List<Student> students;
-----rest of props and methods
}
class Student
{
DateTime CreatedOn;
DateTime UpdatedOn;
---------rest of props and methods
}
now my problem is I want to remove these dates (of student class) from modelstate while updating object of person class. How can I do that?
since a person can have 2 student and other can have any number of students.
if I need to remove "Name" from ModelState I would have used ModelState.Remove("Name") for person
but how can I do it for students of person. Is there something like ModelState.Remove("students") or
ModelState.Remove("students[0]") etc?
Please help me with example

I had answered similar question before here
For those who can't afford one extra click to visit the link
Ignore other properties(other than UserInfo) : ModelState.IsValidField(UserInfo)
Clear/Remove property error : ModelState["ExtraInfo"].Errors.Clear();
Create custom validator, as also suggested by ataravati : MVC Custom validation attribute
Option 1 and 2 will work only when client side validation is disabled.

Add two viewmodels one for update action and one for create action and exclude createdon and updatedon properties from the viewmodels,
This way you keep your controllers clean from additional complexity of clearing or adding errors and just test for ModelState.IsValid.
If valid then update or create the Student with updatedon or createdon respectivily.

Related

MVC 5 Scaffolding with inheritance uses the wrong entity set

With MVC 5 and EF 6.1 I am using a simple inheritance hierarchy, where class Student inherits from class Person. For both classes I have an entity set (DbSet property) in my database context:
public class DatabaseContext : DbContext
{
public DbSet<Person> Persons { get; set; }
public DbSet<Student> Students { get; set; }
}
Now when I ask the scaffolder to generate a controller for Student, the subclass, it uses the Persons entity set, leading to statements such as
Student student = db.Persons.Find(id);
where the compiler obviously complains that it cannot just convert any Person to a Student.
Is there a way to make sure that the scaffolder uses the correct entity set (Students in this case)?
Note that removing the Persons entity set is not a good solution, because there are other controllers that need that.
Use find and replace to change all occurrences in the Controller class of the parent DBSet to the child DBSet eg change Persons to Students.
As you probably know (as I think you raised it) Microsoft have confirmed this is a known bug http://connect.microsoft.com/VisualStudio/feedbackdetail/view/945937/mvc-5-scaffolding-with-inheritance-uses-the-wrong-entity-set but they won't be fixing it.
Instead of inheritance why not use a relationship making personID the Foreign key ? That why you can db.students.find(personID)
And
db.person.find(personID)
To find all details ?
Extra code but I can't think of another way
You can use the command OfType<>, as shown:
Student student = db.Persons.OfType<Student>().SingleOrDefault(s => s.id == id);
This command works with inheritance. In this case, when Student inherits from Person.

ASP.NET MVC 3 Views and Model

I have a model, called Organisation and the model is stored in an assembly called Model. There is a requirement to insert an organisation and update an organisation.
Couple of questions:
When inserting a new organisation, I want to ensure that the organisation doesn't already exist so I've inserted some remote validation. I then bind the model to the insert view.
Now, when I'm creating the update view should I use a different view model which removes the remote validation for duplicate organisation names? If so, I can't use my base Organisation model for the update view, so do I then need to create 2 different views, one for insert and one for update? If this is the case, there is going to be 2 views that are basically the same but just use different models.
Can anyone help?
For this specific scenario the validation that no other organization with the same name exists seems valid for both the insert and update case so you could reuse the same view model.
However validating that the name does not exists when updating a organization must have extra because if the user does not change the organization name then at least one record on the database has that name, the one being updated, and the validation should ignore that record.
So if you choose to reuse the view model the validation must perform according to the context of the operation (insert or update).
Question 1: check validation:
If their is something not valid, do this:
If(isNotValid()){
ModelState.AddModelError("Key", "The user name or password provided is incorrect.")
}
Key is the field in your view that is incorrect.
Question 2: Difference between Create / Edit
You should use the same ViewModel, because in your update, they can still change the "Organisation Name" and you should still check if it is unique.
But why should you use a ViewModel just to check the validation? Is there a reason why you can't check the organisation names for uniqueness in your controller and do a ModelState.AddModelError when it is not unique?
A ViewModel is when you have to extend the Page, For Example
public class DashBoardViewModel
{ public List(Of Organisation) Organisation {get;set;}
public List(Of Staff) Staff{get;set;}
public List(Of Assignment) Assignments{get;set;}
}
Above would be a fictional DashBoardViewModel where i show all the Organisations, Staff and Assignments.
A ViewModel doesn't contain just one type of object, it contains multiple.
And don't forget, sometimes when you need to add some data to a View, you could just use ViewData or ViewBag, instead of creating a ViewModel.

MVC post not populating the model

I cannot figure out why my model is not being populated. All the data posted is in the Request.Form, but the model is actually turning out to be null.
According to this answer on model with collection not populating on postback
In other words, (...) If any required fields are missing, or if the values are
submitted in such a way that they cannot be converted to the type of a required field, then the entire object will be left null
I have changed several value types, but I cannot get it to work.
Here is my model:
public class AddModel
{
//Get properties
public Vehicle vehicle;
//Post properties
[Required(ErrorMessage = "Please enter a start date")]
public DateTime StartDate;
public int? StatusCode;
public SelectList StatusCodes()
{
...
}
}
Can you think of why it's not being populated?
Making AddModel members Properties - adding get; set; to fields should solve your problem
As per #archil's response, you should make your public variables properties. Although this may work with types you will run into problems as soon as you add complexity. Certainly for classes but possible for nullable types too.
The model binders use reflection to parse the form fields into the model, and reflection works differently on properties to public variables - in the case of these models, the differences will likely be causing the failure here.
Hope that helps - and hat tip to #archil for answering this (probably) correctly, much sooner than me!

MVC2, using the same EF Entity in various Views

i have this problem that has been buggin me for the last hours.
Lets suppose i have this Signup form, that i need to fill it up, all propertieshave the RequiredAttribute, the model is a EF entity named "User".
i have this second edit account details form, and at this moment a specific field ("Username") is no longer required, because i already have it, the user doesnt need to fil it again and in matter of fact it doest enven show up on the Edit form.
The problem:
when posting the second Edit form, obviously i am stucked with the Username RequiredAttribute.
I would solve this just by adding a "Bind" attribute with "Exclude" option, BUT, this is my current model :
public class AccountDetailsModel
{
public User user { get; set; }
public string NEWPASSWORD1 { get; set; } // new password
public string NEWPASSWORD2 { get; set; } // new password comparison
}
and just looks like Bind Attribute with Exclude option doesnt handle complex Model types. I cant get it to work on this scenario.
Im stuck, scratching my heads for a long time now...
How can i overcome this?
I just want to re-use my EF Entity (User) on 2 different views along with its DataAnnotations.
Thanks in advance.
I just want to re-use my EF Entity (User) on 2 different views along with its DataAnnotations.
Here's the problem. You shouldn't do this. I would recommend you setting up view models which are classes specifically tailored for a given view and contain the necessary validation attributes for this view only. To ease the mapping between your EF models and the view models you could use AutoMapper.
Put the UserName in a hidden input field for the details page.

Field in mapped entity required

I'm not sure if my problem is solvable in a more or less comfortable way.
There is a class Person which has mapped 'hasOne' a participant.
The person has a birthday but this field is not required on the person itself. But if I would like to add a participant to the person then the birthday is required.
How to get rid of this
move the birthday information to the participant object -> That's how I did it for now, but I think moving person related information to other objects cannot be the final solution
Map the property in both classes -> how to tell the validator when it's required and when not?
Merge the two objects -> for now not allowed
Maybe someone has a better idea, I use the nHibernate Validator and there I configure the validation in the class (where the information 'birthday' is not a property on both - maybe this would be a solution?)
With NHibernate validator attributes as you mentioned. This would be in the Participant class. Would this work for you? It is optional on the base class and nullable as you see (can't change type on overriding)
[NotNull, NotEmpty]
public override DateTime? Birthday { get; set; }
This would still leave field nullable in the DB, but don't see way around this without having a table per class implementation rather than a class per hierarchy fluent implementation. Your domain validation will be there to protect though.

Resources