Model binding with empty textboxes

Last post 11-09-2009 10:43 AM by crawford.r. 6 replies.

Sort Posts:

  • Model binding with empty textboxes

    11-06-2009, 11:52 AM
    • Participant
      845 point Participant
    • crawford.r
    • Member since 08-10-2009, 3:01 PM
    • Posts 170

    I have a Controller with a POST method that takes a struct with many values; some string, some decimal. Some of the properties may or may not have an input in the view that corresponds to them. If such an input is not present, then nothing gets added to the ModelState with that value, and the struct will leave the non-posted decimal values at 0. This is just fine; the behavior we want.

    However, if a given input does show up on the screen, and the user chooses to leave it blank, then when it gets posted, rather than not binding that property, and leaving it at 0, it adds an error to the ModelState saying "A Value is Required." How can I get it to treat empty input values as if they weren't posted at all? Do I have to write my own custom ModelBinder? I tried looking at that a little bit, but neither the BindModel nor the BindProperty methods were getting called.

    Basically, I want to allow the user to leave a textbox blank, and when he does treat it as if the textbox weren't there at all.

  • Re: Model binding with empty textboxes

    11-06-2009, 5:22 PM
    • Contributor
      6,571 point Contributor
    • gerrylowry
    • Member since 07-03-2008, 1:46 AM
    • alliston ontario canada
    • Posts 2,261

    ? what do you mean by "if a given input does up on the screen"?

    is this "Create" or "Update"?

    are you using LINQ to Entities?   ... LINQ to SQL?  ... other LINQ?  ... other non LINQ?

    what happens depends on factors like your database schema ... you need to provide more information.


    Simple solution (may not apply to your situation):

    for Edit (i.e. Update):

          if (decimalFieldA == "") objectToUpdate.mydecimalfield == 0;

    the above you do prior to

        _db.ApplyPropertyChanges(originalMovie.EntityKey.EntitySetName, movieToEdit);

    _db.SaveChanges();

    Gerry Lowry, Principal
    Ability Business Computer Services ~~ Because it's your Business, our Experience Counts!
    68 John W. Taylor Avenue
    Alliston · Ontario · Canada · L9R 0E1 · gerry.lowry@abilitybusinesscomputerservices.com

    Websites:
    http://abilitybusinesscomputerservices.com
    http://gerrylowryprogrammer.com ~~ résumé & testimonials
    http://veganoccasions.com ~~ recipes by Susan
  • Re: Model binding with empty textboxes

    11-07-2009, 3:33 PM
    Answer
    • Contributor
      4,372 point Contributor
    • tgmdbm
    • Member since 12-17-2007, 9:08 AM
    • Posts 883
    • ASPInsiders
      TrustedFriends-MVPs

    if you can change the Model, use nullable decimals. then in your code, treat nulls as 0s.


    if not you have 3 options. 1) remove the values from the ValueProviderDictionary, if it's not read only you can remove them easily, otherwise you can create your own dictionary, add only the values you want, and set this.ValueProvider = myValueProvider. 2) write a ModelBinder for your struct which converts the empty string to 0 for decimals. or 3) it you want ALL decimals to behave this way, create a ModelBinder for the decimal type.

     

    There're probably more ways to accomplish you task but these are just a few.


    hope that helps


  • Re: Model binding with empty textboxes

    11-09-2009, 3:50 AM

    Hi,

    Based on my experience we can check the modelstate object to  see whether the 'ModelState' is valid.

    If it isn't, and we are sure the reson is that we don't assign a value to the field and we really want to leave it blank, we can remove the error from the 'ModelState'. You can take a look at the following solution.

    e.g.

      if (!ModelState.IsValid)
      {   //the 'DisplayOrder' is the name you used in the 'Html.ValidationMessage' method //in view.  
           if (ModelState["DisplayOrder"].Errors.Count != 0)
          {
               ModelState.Remove("DisplayOrder");         
           }
                    
         return View();
    }




  • Re: Model binding with empty textboxes

    11-09-2009, 9:59 AM
    • Participant
      845 point Participant
    • crawford.r
    • Member since 08-10-2009, 3:01 PM
    • Posts 170

    Gerry, unfortunately we aren't using any entities type stuff; we have no choice (per client business rules) other than to do any data access using their classes, which call web services. Before our POST action method ever gets called, the ModelState already contains an error because there was a textbox that was left empty. Under different circumstances, that textbox may not ever get rendered in the HTML at all; in which case no ModelState error occurs, which is what we want. Basically I want an empty textbox to be treated the same as a textbox that's not there at all.

  • Re: Model binding with empty textboxes

    11-09-2009, 10:32 AM
    • Contributor
      6,571 point Contributor
    • gerrylowry
    • Member since 07-03-2008, 1:46 AM
    • alliston ontario canada
    • Posts 2,261

    @ crawford.r

    if I understand you correctly, there may be one named textbox field which I will call textboxfieldA.

    (1) sometimes textboxfieldA may be missing.  this is an error.

    (2) at other times, textboxfieldA may be empty.  this too is an error.

    In case (1), ModelState may or may not contain an error.  I do not know.

    In case (2), ModelState should not contain an error unless you do validation AFAIK.


    My understanding of Controller ===>  View ===> Controller flow in an ASP.NET MVC application, which still is incomplete, is that it works some like this.

    Controller, as a messenger, delivers "data" to the ViewView renders the data in HTML.

    [possibility:  if the textbox is not available in the View, then the View could create a proxy textbox with a value like "required".]

    End user clicks a submit button that returns "data" to the Controller; on the way to the Controller, any bound "data" gets readied to be delivered to the data store (e.g.:  an SQL database); some data may be unbound.

    Back in the Controller (usually via a POST request) a decision to either return the View with errors to the end user or accept the results and affect the data store is made, usually based on the ModelState.IsValid property.

    Strategy:  partially ignore blind faith use of ModelState.IsValid if the condition is false.  If ModelState.IsValid is true, no problem.  If ModelState.IsValid is false, determine if there was only one error and if that error was an unacceptable value in textboxfieldA; if this is the case, accept the "data" as if ModelState.IsValid had been true.  Otherwise, follow your error procedure which likely will be to return the View to the end user for correction.


    Does that make any sense?

    If it does, will it work for you?



    Regards,
    Gerry (Lowry)

    Gerry Lowry, Principal
    Ability Business Computer Services ~~ Because it's your Business, our Experience Counts!
    68 John W. Taylor Avenue
    Alliston · Ontario · Canada · L9R 0E1 · gerry.lowry@abilitybusinesscomputerservices.com

    Websites:
    http://abilitybusinesscomputerservices.com
    http://gerrylowryprogrammer.com ~~ résumé & testimonials
    http://veganoccasions.com ~~ recipes by Susan
  • Re: Model binding with empty textboxes

    11-09-2009, 10:43 AM
    • Participant
      845 point Participant
    • crawford.r
    • Member since 08-10-2009, 3:01 PM
    • Posts 170

    Thanks, that's generally what's going on; with some minor corrections:

    (1) textBoxFieldA may be missing, and this is not a problem at all. It's "missing" because the View has determined that based on certain criteria, textBoxFieldA should not be shown to the user. When this happens, the ModelState does not contain any error, which is good. Although the bound data contains a decimal that is bound to textBoxFieldA, in this situation, that decimal just gets set to 0. This is the exact behavior we want.

    (2) When textBoxFieldA is there, but left empty, then the ModelState contains an error, even though we aren't doing any validation on it at all. Presumably the binding is attempting to convert the empty string into a decimal and giving an error.

    Your solution is definitely a possibility; checking the ModelState to see if the only error is in textBoxFieldA, and if so, making it act like there was no error. I am still looking into writing a custom binder for our object though; one that will set the decimal to 0 if textBoxFieldA is an empty string. Thanks.

Page 1 of 1 (7 items)