MVC2 TryUpdateModel's include attributes not ignoring validations on fields unincluded - asp.net-mvc-2

I have a form in my MVC 2 application that allows a user to update a set of fields from a model object, this is purely an update as the model object is already existing with its required fields entered. However when I try to update a small set of fields and call TryUpdateModel on my model object it fails and my modelstate has errors based on required fields that have already been filled out.
Here is my controller code:
[HttpPost]
public ActionResult Work(int id, FormCollection forms)
{
var lead = claimRepo.GetLeadByID(id);
if (lead == null)
return View("NotFound");
if (TryUpdateModel(lead, "Lead")) {...}
}
I've even tried explicitly stating which fields to update like so
TryUpdateModel(lead, "Lead", new string[] { "Date", "UserID", ...}) {...}
And it still fails, is there some reason this doesn't ignore validation on fields not included or am I doing something wrong?
Thanks!
EDIT
I found the issue, I had a property on my class that wasn't database backed and was marked as required in metadata, so adding a getter and setter to return what the property represented caused the TryUpdateModel to pass, but I am still curious as to why the explicit include of properties didn't ignore the field I hadn't included.
Another Edit
I have a user model as well with all database backed required fields and trying to explicitly state which fields are being updated still results in modelstate errors on the fields missing in the form, but are filled in on the model object from the db that is being updated.

I am not sure when the default behaviour was changed for validating only incoming data, from what I know I think only asp.net mvc1 supported it, then it changed in asp.net mvc2 anyway you could say [Validate(false)] and allow the partial data to go through and manually do some validation. You could use a ViewModel and validate all fields on the view model if needed as a second option. A helpful link: partial validation

Related

Foreign entity in form into different kind of input

I have two entities: product and category (Symfony 2.3).
I want to create a form in which an user can choose a product by first selecting the category. A user selects the category by clicking on image, then I want to set the image's value into a hidden input, but I don't see how can I change a foreign entity choice list to a hidden input (http://symfony.com/doc/current/reference/forms/types/entity.html).
How can I accomplish this? (how to change form input to hidden)
If I set cascade validation to true, will it for example check if a category really exist. (To prevent putting products with non-existing category from malicious users) ?
Part 1
To do this you need to use a data transformer to do two things:
transform an entity into an identifier that is either a string or integer so a form can render it as a hidden field.
transform the string or integer identifier into the entity when the form is submitted so that the parent entity can be saved with the correct relationship
The symfony docs I linked to above (here too) actually walk though an entire example of using a data transformer with a form.
As a shameless plug (because I believe it is helpful) I have written a little tutorial on using a data transformer for a hidden field with an entity id: http://lrotherfield.com/blog/symfony2-forms-entity-as-hidden-field/
Part 2
If you are using the data transformer then you don't need to worry about malicious users. The data transformer will fail because it will not be able to reverse transform the category from the fake id. In my tutorial the transformer will throw a Symfony\Component\Form\Exception\TransformationFailedException exception.
You can also write a validator (potentially using a call back) if you wanted that checks that the submitted category is real if you want an error to show in the form. Doctrine wont allow you to persist a fake category relationship as the foreign key constraint will fail.

How to make an Entity Framework property NOT NULL, but not required in form submission

I'm using Entity Framework 4.1 with a code-first model. A common pattern is that many objects reference the user who owns them, eg.
public class Item
{
public User Owner { get; set; }
}
This creates a nullable column in the DB, but since every Item must have an owner I want the column marked NOT NULL. If I use the [Required] attribute then submitting the form to create an Item results in an error. That field is never set through a form, only manually in code.
It is generally recommended to create separate view models for such situations. Using database models as view models for input forms is seen as an anti-pattern.
Make a ItemViewModel that has the same properties as Item and relevant data validation attributes. You may want to use a library called Automapper to automate the boring property-copy-code needed in those cases.

Entity framework and pure POCO update

How do I do an update on a pure POCO object using entity framework 4?
Lets say I change the person's first name and call the repository in this manner:
public User Update(User user)
{
//User originalUser = GetUser(user.UserId);
//Is there a way to update the values that are only changed?
context.Users.Attach(user);
context.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);
return user;
}
I dont want null values to update the database to null. For eg. Suppose I have LastName as a property but when passing the object to the update function, it was null. Am I going to have to get the originalUser and then update each property accordingly?
"update each property accordingly?"
No, you can use,
context.ObjectStateManager.TryGetObjectStateEntry(newItem, out entity);
// this will gives you the entity present in db and after that I suggest to write your code to change the state and save.
Also suggest you to read this
for more info on tracking changes in POCO entities

Saving Dropdown list selection with Entity Framework in ASP.NET MVC solution

I'm looking for advice on a decent pattern for dropdown list selection and persistence of the selection with POCO EF please.
I have a list of IEnumerable<Country> in my view model where Country is a POCO loaded via EF. There is an Address property on the view model that takes the current or user selected value on it's Country property. Within the view I display these via a Html.DropdownListFor() thus:
Html.DropDownListFor(model => model.Address.Country.Id, new SelectList(Model.Countries,"Id","Name",model.Address.Country.Id)
So far so good and it all works on postback with the default ModelBinder providing me with a view model with the Address.Country populated. However Address.Country is of course only populated with the Id field with default model binding.
Trying to send the Address update back to the DB through EF blows up as this is seen as a new object which doesn't have it's full object graph loaded, only the Id set.
Now I can fix this by loading the full Country object from the db into the Address.Country property on postback before saving based on the selected Id. But this seems like a lot of hard work for anything beyond a simple object graph.
The most "elegant" solution I could think of would be a custom model binder for Country but then that would require the Model Binder to know about the repository for retrieving the full EF object which doesn't seem right to me. I'd also have to repeat this for all other Entities used in Dropdown lists.
Hope this makes sense and any feedback on how others are doing this would be appreciated.
If you set Address.Country to an object, EF expects it to be a full object that's part of the current context, but EF does recognize foreign keys: If your Address object has both a CountryID property and a Country property, it should accept Address.CountryID being set as long as Address.Country itself is null.
In your Address class declare country as virtual
public class Address
{
public virtual Country Country;
}
try this and let me know if it works, Virtual supports lazyloading and you don't have to query explicitly

ASP.NET MVC 2 Model partial binding

My problem is that I want to partially edit my model - to display 2 fields and to edit another 2 fields for example. When POST happens, returned model contains only the fields that are editable, other fields that I use only to display are NULL. How to fix this, on POST to be returned model with all fields, because on ERROR when I return this model and fields are NULL is not so good?
The model binder binds the form values only to model properties that have a setter.
Depending on what you need to achieve:
You can use hidden inputs to store the values in the view, these will be bound back (given that the properties have a setter)
<%= Html.Hidden(Model.SomeField) %>
class YourViewModel
{
public SomeField {get; set;}
Or you should ensure in your controller action that you are only updating the fields that you displayed in the view, not the null ones.
Ideally, your viewmodel should contain only the properties that are relevant for the view (and for the logic handled by the controller).