Why would =ViewData[""] show a string but evaluating it for the same string fail?
Asked Answered
R

1

5
//CHECK IF WE SHOULD SHOW THE PASSWORD HINT OR NOT
Setting passwordhints;

using (var db = new dbDataContext())
{
    passwordhints = (from c in db.Settings
            where c.Name == "ShowPasswordHints" && c.ID == _ID
            select c).FirstOrDefault();
}

if (passwordhints != null)
    //NOTE: .Value IS A STRING
    ViewData["ShowPasswordHints"] = passwordhints.Value;
else
    ViewData["ShowPasswordHints"] = "False";

//END PASSWORD HINTS CHECK

is in the controller, when I get to the page itself I output

<%=ViewData["ShowPasswordHints"]%> into the title tag and I can see it up there it says "True" (without quotes, I also checked for spaces by surrounding it with parenthesis and there are no spaces it is literally just True)

However when I do

<%if(ViewData["ShowPasswordHints"] == "True") {%> SHOW THIS <%}%>

SHOW THIS never appears, what the hell?

UPDATE: However, if ViewData is set like this... IT WORKS... HUH??

if (accountRepository.isLDAPEnabled(_ID))
                ViewData["LDAP"] = "True";
            else
                ViewData["LDAP"] = "False";

view...

<%if(ViewData["LDAP"] == "True"){ %>
           SHOW THIS
         <%} %>

THANKS EVERYONE, HERE IS NEW METHOD THAT IS WORKING GREAT

ViewData["something"] = true;

<%if(true.Equals(ViewData["something"])){%> SHOW THIS <%}%>
Ravenna answered 6/12, 2010 at 20:52 Comment(0)
P
11

Since ViewData is an IDictionary<string, object>, ViewData["ShowPasswordHints"] is of type object. By default, objects are compared by reference. You want a value comparison. Thus, try casting it to a string, which will cause a value comparison:

<%if((string)ViewData["ShowPasswordHints"] == "True") {%> SHOW THIS <%}%>

More at msdn.

UPDATE: The value you put into ViewData["ShowPasswordHints"] is always a string. However, since C# is statically typed, the compiler doesn't know that when you take it back out, it is a string -- it only knows that it will be an object, since ViewData is a IDictionary<string, object> (a dictionary returning plain objects). But since you know better, you can cast it to the string that you know it should be. (BTW, I think ViewData is one of the weakest points of the MVC framework, for this reason and others)

Why this works in the <title> is because the <%= %> tags call ToString() on whatever in them. Since ViewData["ShowPasswordHints"] is a string, it comes out like you'd expect -- ToString() of a string is the string itself.

Finally: why aren't you using a boolean?

Pointdevice answered 6/12, 2010 at 20:55 Comment(5)
Perhaps a better (more safe) approach would be "True".Equals(ViewData["ShowPasswordHints"]). No ClassCastException if the object in the view data dictionary is not a string.Robbierobbin
It would also help if you explained why this happens automatically when referencing the object in his first case, the title tag.Croom
see my update, why does it sometimes work? When I tried saying = "True" instead of = obj.Value it still didn't work but the code I added above worked, I'm so troubled by this :(Ravenna
@shogun The code in your update only works because you're lucky: You use the constant string "True" in both places, so the reference comparison works (as constants, they occupy the same memory location). The one from the DB has a different memory address, so the reference comparison fails. But I'll say it again: why not just use booleans? That type is perfect for this siutation.Pointdevice
@Pointdevice when I try using booleans it said operand cannot compare object with boolean... EDIT: OK using false.Equals() or true.Equals() seems to work but not ViewData[] == true, etcRavenna

© 2022 - 2024 — McMap. All rights reserved.