Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to whitelist/blacklist child object fields in the ModelBinder/UpdateModel method?
    primarykey
    data
    text
    <p>I have a question regarding how to get the white- and black-listing feature of the MVC controller's UpdateModel/TryUpdateModel to work on individual properties of child objects. For example, lets say I have a questionnaire collecting details about the person filling out the form and about his or her company.</p> <p>My [simplified] form fields would be named, for example:</p> <pre><code>YourName YourEmail Company.Name Company.Phone </code></pre> <p>Now in my model, lets say I don't want Company.ID or Company.IsPremiumMember to be tampered with, so I'd like to exclude them from the model-binding. I have tried a combination of whitelisting, blacklisting, and both in order to get this to work. I have not had any success. Here is what I am running into:</p> <p>When I explicitly include in my whitelist the same four fieldnames I wrote above, the entire Company does not get bound (i.e., questionnaire.Company is left null) unless I also include "Company" in my whitelist. But then this has the undesirable effect of binding the ENTIRE company, and not just the two properties I want.</p> <p>So, I then tried to include Company.ID and Company.IsPremiumMember in my blacklist, but this seems to be trumped by the whitelist and does not filter out these properties "after the fact" I suppose.</p> <p>I know that there are other ways to express the "bindability", such as via the [Bind] attribute on members, but this is not ideal as I would like to have the same model classes used in other situations with different binding rules, such as allowing an admin to set whatever properties she would like.</p> <p>I expect an obvious answer is that I should write my own model binder, and I've already starting trying to look into how to perhaps do this, but I was really hoping to use an "out-of-the-box" solution for what (in my opinion) seems like a very common scenario. Another idea I'm pondering is to fabricate my own ValueProvider dictionary to hand to the UpdateModel method, but again, something I'd rather avoid if there is an easier way.</p> <p>Thanks for any help! -Mike</p> <p><hr /> <strong><em>Addendum #1</em></strong></p> <p><em>Here are the fields I present on my form:</em></p> <pre>YourName YourEmail Company.Name Company.Phone</pre> <p><em>And here is what a black hat sends my way:</em></p> <pre>YourName=Joe+Smith&YourEmail=joe@example.com&Company.Name=ACME+Corp&Company.Phone=555-555-5555&Company.CreditLimit=10000000</pre> <p>(be sure you notice the extra parameter tacked on there at the end!)</p> <p><em>And here is the problem:</em></p> <p>As I originally posted, it doesn't seem possible (using the default model binder) to prevent CreditLimit from being set---it's either the entire Company or nothing---without some big workaround. Am I wrong?</p> <p><hr /> <strong><em>Addendum #2</em></strong></p> <p>I'm pretty much convinced now that the simple objective I have is not possible "out of the box." My solution has been to walk through the posted form fields and construct my own ValueProvider dictionary, thus whitelisting the fields I want to allow, and handing that to UpdateModel.</p> <p><hr /> <strong><em>Addendum #3</em></strong></p> <p>I still have not yet checked out AutoMapper, but with something like that at hand, the solution of creating some ViewModels/DTOs to handle this type of complex whitelisting---plus the ability to easily attach the same server-side validation (FluentValidation) I'm already using on my domain objects---seems a viable solution. Thank you everyone!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload