Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you exclude properties from binding when calling UpdateModel()?

Tags:

I have a view model sent to the edit action of my controller. The ViewModel contains references to EntityObjects. (yea i'm fine with it and don't need to want to duplicate all the entities properties in the viewmodel).

I instantiate the view model and then call UpdateModel. I get an error that a property is "null" which is fine since it is a related model. I am trying to exclude the property from being bound during model binding. On debugging it I see in the entity where the model binder is trying to set the value of the property to null.

Here is my edit action:

var model = new SimplifiedCompanyViewModel(id);

var excludeProperties = new string[] { 
   "Entity.RetainedEarningsAccount.AccountNo"
   ,"Property.DiscountEarnedAccount.ExpenseCodeValue"
   ,"Entity.EntityAlternate.EntityID"
   ,"Property.BankAccount.BankAccountID"
   ,"Entity.PLSummaryAccount.AccountNo"
   ,"Property.RefundBank.BankAccountID"
   ,"Company.Transmitter.TCC"
};

try
{
    UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);

    if (ModelState.IsValid)
    {
       //db.SaveChanges();
    }
       return RedirectToAction("Index");
}
catch
{
    return View(model);
}

I have looked at a few other issues about specifying a "prefix" but I don't think that is the issue since I am telling it to bind to the viewmodel instance not just the entity object.

Am I excluding the properties correctly? Strange thing is is only seems to happen on this item. I suspect it may be an issue with the fact that there is actually no refund bank related to my entity. But I have other related items that don't exist and don't see the same issue.

More info... since I'm told me model isn't designed well.

The Company is related to a BankAccount. The Company view shows the currently related BankAccount.BankAccountId and there is a hidden field with the BankAccount.Key. I use jQueryUI autocomplete feature to provide a dropdown of bank account displaying the BankAccount.BankAccountId and when one is selected the jQuery code changes the hidden field to have the correct Key value. So, when this is posted I don't want the current bankaccounts BankAccountID modified, hence I want it to skip binding that field.

If I exclude BankAccountId in the model then on the BankAccount edit view the user would never be able to change the BankAccountId since it won't be bound. I'm not sure how this indicates a poor model design.

like image 790
PilotBob Avatar asked Nov 30 '11 20:11

PilotBob


People also ask

What is bind property in C#?

The Binding class is used to bind a property of a control with the property of an object. For creating a Binding object, the developer must specify the property of the control, the data source, and the table field to which the given property will be bound.

What is bind property in MVC?

Model binding allows you map request parameters to actions. This means action methods will have one or more parameters and those parameters will receive their values from the model binding framework.

What does the bind attribute do in create action method?

The [Bind] attribute will let you specify the exact properties of a model should include or exclude in binding. In the following example, the Edit() action method will only bind StudentId and StudentName properties of the Student model class. You can also exclude the properties, as shown below.


1 Answers

Use the Exclude property of the Bind attribute:

[Bind(Exclude="Id,SomeOtherProperty")]
public class SimplifiedCompanyViewModel
{
    public int Id { get; set; }

    // ...
}

This is part of the System.Web.Mvc namespace. It takes a comma-separated list of property names to exclude when binding.

Also you should consider using TryUpdateModel instead of UpdateModel. You can also just have the default model binder figure it out by passing it as an argument to the constructor:

public ActionResult Create([Bind(Exclude="Id")]SimplifiedCompanyViewModel model)
{
    // ...
}
like image 159
Dismissile Avatar answered Oct 21 '22 17:10

Dismissile