absolutely wonky behaviour of Entity Framework bools ...

Last post 07-05-2009 12:21 PM by bradwils. 3 replies.

Sort Posts:

  • absolutely wonky behaviour of Entity Framework bools ...

    07-02-2009, 1:47 AM
    • Contributor
      5,911 point Contributor
    • gerrylowry
    • Member since 07-02-2008, 9:46 PM
    • alliston ontario canada
    • Posts 2,140

    ASP.NET MVC
    why do you have to torture me?
    M    V     C
    1     2     3
    what is it that I've done to thee?

    MVC says "don't blame me".
    It's that jerk Entity Framework!
    "Blame EF!" says MVC,
    "it's probably another EF quirk".

    My EF model represents an abstraction of up to two types of website material.

    • a news article
    • a highlight

    Each record can be a news article, a highlight (basically just a picture with a short description), or both.

    My EF model contains two bools:

    • newsarticle
    • highlight

    This is very much an analogue to the movie database tutorial with a few more fields.

    Walking the code with F11:

    F5:  debug starts ...  http://localhost:50316/   our home page:  tangent:  an interesting (to me) discovery:

    http://localhost:50316/home            same home page } ~~ wait one minute!
    http://localhost:50316/HOME           same home page } ~~ AFAIK, URLs are supposed
    http://localhost:50316/home/index  same home page }       to be case sensitive!
    http://localhost:50316/Home/index  same home page } ~~ in ASP.NET MVC, they appear
    http://localhost:50316/hOmE/iNdEx same home page }       to be case insensitive!

         <%= Html.ActionLink("Articles", "ArticlesIndex", "Article") %>

    via above menu, I go to http://localhost:50316/Article/ArticlesIndex

    Another revelation:  I notice a new folder in my solution called "Script Documents".
    "Script Documents" contains a process called "Windows Internet Explorer".
    "Windows Internet Explorer" ~~ later for this interesting (to me) tangent.
    ("Script Documents" disappears when I close IE7; the reason I see it is because
      I've click "Show All Files" is Solution Explorer.).

    http://localhost:50316/Article/Edit/6 off to edit an existing article.

            public ActionResult Edit(int id)
            {
                var articleToEdit = (from m in _db.ArticleSet where m.Id == id select m).First();
                // todo:  why and where are status flags changing from true to false?
                bool highlightValue = articleToEdit.highlight;     // debugging
                bool newsArticleValue = articleToEdit.newsArticle; // debugging
                return View(articleToEdit);


    F11:  both bools are true at this point.   Mousing over the return shows _highlight and _newsArticle as true

    F11:  stepping through Edit.aspx<%= Html.Encode(Model.highlight) %> is true;

            <%= Html.Encode(Model.newsArticle)%> is also true.

     Here, editing nothing at all, I submit the Edit.aspx page.

            [ValidateInput(false)]
            [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult Edit(Article articleToEdit, string changeControlString, string continueEditing)
            {
                if (!ModelState.IsValid) return View();
                try
                {
                    // todo:  why and where are status flags changing from true to false?
                    bool currentHighlightValue = articleToEdit.highlight;        // debugging
                    bool currentNewsArticleValue = articleToEdit.newsArticle;    // debugging
                    var originalArticle = (from m in _db.ArticleSet where m.Id == articleToEdit.Id select m).First();
                    // todo:  why and where are status flags changing from true to false?
                    bool originalHighlightValue = originalArticle .highlight;    // debugging
                    bool originalNewsArticleValue = originalArticle.newsArticle; // debugging

    currentHighlightValue and currentNewsArticleValue are both false;
    originalHighlightValue and originalNewsArticleValue are still true.

    _db.ApplyPropertyChanges(originalArticle.EntityKey.EntitySetName, articleToEdit);


    The above statement will flip the values to false even though in theory, I am not responsible for this change!!!

    ASP.NET MVC
    why do you have to torture me?
    M    V     C
    1     2     3
    what is it that I've done to thee?

    MVC says "don't blame me".
    It's that jerk Entity Framework!
    "Blame EF!" says MVC,
    "it's probably another EF quirk".

    Personally, I do not think these values should be flipped.  My text fields do not get messed with.  Therefore, these fields should also be left alone.  I think the cause has something to do with their being set to do not allow nulls in the .mdf file.

    Note:  <%= Html.Encode(Model.Id)%> does not get messed up.

    I'm going to kludge this for now instead of playing around with ideas like:
             [Bind(Exclude = "hightlight, newsArticle")] ~~ perhaps Bind will work?!

    Here's the kludge:

                    articleToEdit.highlight = originalArticle.highlight;         // kludge
                    articleToEdit.newsArticle = originalArticle.newsArticle;     // kludge
    


    Somehow, it seems strange and unnatural that I need to kludge bool fields like this.

    Any idea why?

     

    Thank 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
  • Re: absolutely wonky behaviour of Entity Framework bools ...

    07-02-2009, 8:12 AM
    • Contributor
      6,620 point Contributor
    • paul.vencill
    • Member since 02-01-2006, 7:57 AM
    • Gaithersburg, MD
    • Posts 1,350

     Gerry,

    Case sensitivity in URLS, afaik, is not part of the standard; rather, it's a function of the case sensitivity of the server's file system (which is to say that *nix boxes generally are, while windows generally are not; but many *nix hosts now provide insensitivity since the muggles are used to it).

    re: routing multiple paths.  True that they'll resolve (unless you do something to prevent it), but they do a pretty good job of generating the minimal route possible when you make a call to ActionLink or the related functions.  Not sure what you'd do about this w/o breaking the pattern.

    Finally, your true/false problem.  You didn't post your View code (which is key to this, I beleive) but if I had to guess, I'd guess that you have something wrong w/ your markup there when you generate whatever form input you're using for the booleans.  Can you show the section that you generate radios or checkboxes or whatever for the user to influence the bool properties states?

    It just occurred to me, based on your comments in the controller, that you might not actually be putting anything on the view for those bools... If not, then that's your problem. Remember that the web is stateless, so unless you provide a value somehow, you don't have a value.  In your case, if you don't want to show a checkbox or the like, I'd either throw out a hidden field that holds the value of each boolean, and then exclude them from the binding, or else do what you're doing and set them to the original value explicitly.

    Paul

    Help those who have helped you... remember to "Mark as Answered"
  • Re: absolutely wonky behaviour of Entity Framework bools ...

    07-05-2009, 5:10 AM
    • Contributor
      5,911 point Contributor
    • gerrylowry
    • Member since 07-02-2008, 9:46 PM
    • alliston ontario canada
    • Posts 2,140

    paul.vencill:
    It just occurred to me, based on your comments in the controller, that you might not actually be putting anything on the view for those bools... If not, then that's your problem.

    Hi Paul ... I would not call it my problem.  Let me explain.

    I display the two bools with Html.Encode because all that is necessary is for the end user to see whether they are true or false.

    This is the price one pays with frameworks that "do it all (or almost all)" for the developer.

    Bind(Exclude="...") does not seem to help.  Fortunately, the read only property ModelState.IsValid is true, hence I can use my kludge.

    I would like to see some more powerful attribute as a non kludge solution, something like:

                 [DoNotFalsifyMyBools("boolA, boolB, ....")]

    Gerry

     

    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
  • Re: absolutely wonky behaviour of Entity Framework bools ...

    07-05-2009, 12:21 PM
    Answer
    • Participant
      1,872 point Participant
    • bradwils
    • Member since 05-19-2008, 1:08 PM
    • Redmond, WA
    • Posts 277

    gerrylowry:

    I would like to see some more powerful attribute as a non kludge solution, something like:

                 [DoNotFalsifyMyBools("boolA, boolB, ....")]

    Boolean is a value type whose default value is "false". When you allocate a new copy of the object, before you do anything to it, those values will already be false. That has nothing to do with MVC; we're not "falsifying" your bools. They are false because of the rules set down for values types in the .NET Framework.

    What you are doing here is called a partial edit, meaning, you're not editing the whole object. The problem is, when you ask EF to save the object, it really expects the whole object to be filled out.

    So, what are your options?

    1. Render hidden fields for all the non-edited values so that data binding can put the non-edited values back into your object.

    Note: this represents a potential security risk, since values you never intended the user to be able to edit will now be "changeable" by a bad guy (who could submit the form with new values for the things you didn't want to be edited). A comprehensive approach here would include digital signatures of all uneditable values so that you can ensure they have not been changed; unfortunately, there is no built-in support today for digitally signed form values in MVC 1.0.

    2. Use TryUpdateModel against a fully populated object instead of parameter binding.

    Change your action method to something like this:

            [ValidateInput(false)]  
            [AcceptVerbs(HttpVerbs.Post)]  
            public ActionResult Edit(int id, string changeControlString, string continueEditing)  
            {
                Article articleToEdit = (from m in _db.ArticleSet where m.Id == id).Single();
                if (!TryUpdateModel(articleToEdit)) return View();
                try  
                {
                    // ...


    Senior developer on the ASP.NET MVC team
Page 1 of 1 (4 items)