ViewDataDictionary change mentioned in release notes

Last post 10-20-2008 3:35 PM by bradleylandis. 6 replies.

Sort Posts:

  • ViewDataDictionary change mentioned in release notes

    10-17-2008, 1:14 PM
    • Member
      184 point Member
    • bradleylandis
    • Member since 06-19-2008, 11:28 AM
    • Posts 97

    I am interested in this line from the release notes:

    We made a minor change to the ViewDataDictionary class to change its indexer to be a normal indexer. We also added an Eval method that evaluates the model. The Eval method contains an overload that accepts a format string.

    I didn't see this mentioned in ScottGu, Phil or ScottHa's blog posts.  I am wondering if it address an issue that I had.  My issue was that I wanted to format some input fields.  For example, currency and dates.  But when the user enters invalid input and I have to redraw it with the error, this causes problems.  I ended up with some distasters like this in my view:

    <%

    DateTime nextReviewDate;

    string nextReviewDateText = string.Empty;

    if (ViewData.ModelState.ContainsKey("Employee.NextReviewDate"))

    {

    if (DateTime.TryParse(ViewData.ModelState["Employee.NextReviewDate"].AttemptedValue, out nextReviewDate))

    {

    nextReviewDateText = nextReviewDate.ToString(
    "MM/dd/yyyy");ViewData.ModelState["Employee.NextReviewDate"].AttemptedValue = nextReviewDateText;

    }

    else

    {

    nextReviewDateText = ViewData.ModelState[
    "Employee.NextReviewDate"].AttemptedValue == null ? string.Empty : ViewData.ModelState["Employee.NextReviewDate"].AttemptedValue.ToString();

    }

    }

    else if(employee.NextReviewDate != null)

    {

    nextReviewDateText = employee.NextReviewDate.Value.ToString(
    "MM/dd/yyyy");

    }

    %>

    <%
    =Html.TextBox("Employee.NextReviewDate", nextReviewDateText)%>

    <%= Html.ValidationMessage("Employee.NextReviewDate", "*")%>

    So can I get an example of how the Eval method of ViewDataDictionary could be used?  And will it help with issue that I described?

  • Re: ViewDataDictionary change mentioned in release notes

    10-17-2008, 8:25 PM
    • Member
      525 point Member
    • panjkov
    • Member since 01-12-2003, 5:16 AM
    • Sarajevo/Banjaluka, Bosnia and Herzegovina
    • Posts 167

     DISCLAIMER: I haven't tried this in practice. I've only browsed througr MVC source code and VS Help/MSDN.

    OK. After disclaimer, let's do some work. Here is a decompiled source code for Eval metod that takes two arguments:

     

    1    public string Eval(string expression, string format)
    2 {
    3 object obj2 = this.Eval(expression);
    4 if (obj2 == null)
    5 {
    6 return string.Empty;
    7 }
    8 if (string.IsNullOrEmpty(format))
    9 {
    10 return Convert.ToString(obj2, CultureInfo.CurrentCulture);
    11 }
    12 return string.Format(CultureInfo.CurrentCulture, format, new object[] { obj2 });
    13 }

      Take atention to line 12 in this code fragment. It returns overload of String.Format that takes format string as an argument. From MSDN/VS Help:

    Format(IFormatProvider, String, array<Object>[]()[]) Replaces the format item in a specified String with the text equivalent of the value of a corresponding Object instance in a specified array. A specified parameter supplies culture-specific formatting information.
    public static string Format(
    IFormatProvider provider,
    string format,
    Object[] args

    and format is a composite format string -again from MSDN:

    A composite format string and object list are used as arguments of methods that support the composite formatting feature. A composite format string consists of zero or more runs of fixed text intermixed with one or more format items. The fixed text is any string that you choose, and each format item corresponds to an object or boxed structure in the list. The composite formatting feature returns a new result string where each format item is replaced by the string representation of the corresponding object in the list.

    for example, in next code fragment, first argument is a composite format string . This page also contains examples of various usages of this argument.

    1    string FormatString1 = String.Format("{0:dddd MMMM}", DateTime.Now);
     
    In the end, you might use Eval like this:
    EDIT: ViewData.Eval("{0:dddd MMMM}", NextReviewDate) - Arguments are in wrong order and NextReviewDate must be passed as string name, and not variable
    ViewData.Eval("NextReviewDate", "{0:dddd MMMM}")  

    Dragan
    Dragan Panjkov
    [http://blogpanjkov.qsh.eu/] [http://www.microsoft.com/bih]

    Filed under: , ,
  • Re: ViewDataDictionary change mentioned in release notes

    10-17-2008, 8:38 PM
    • Member
      525 point Member
    • panjkov
    • Member since 01-12-2003, 5:16 AM
    • Sarajevo/Banjaluka, Bosnia and Herzegovina
    • Posts 167

    I've posted wrong syntax for ViewData.Eval at the end of previous post. I've corrected this code fragment.

    Eval function takes name of variable to evaluate as string, and doesn't take variable itself as an argument.

    Dragan Panjkov
    [http://blogpanjkov.qsh.eu/] [http://www.microsoft.com/bih]

  • Re: ViewDataDictionary change mentioned in release notes

    10-20-2008, 12:29 PM
    • Contributor
      4,440 point Contributor
    • levib
    • Member since 07-23-2007, 7:50 PM
    • Redmond, WA
    • Posts 773
    • AspNetTeam

    Intended usage:

    <% Html.TextBox("NextReviewDate, ViewData.Eval("NextReviewDate", formatString)) %>

    We'll always use the AttemptedValue (if it exists) first, only falling back to the explicitly provided value if no AttemptedValue exists.

  • Re: ViewDataDictionary change mentioned in release notes

    10-20-2008, 12:44 PM
    • Member
      184 point Member
    • bradleylandis
    • Member since 06-19-2008, 11:28 AM
    • Posts 97

    So it looks like it was indeed intended to help with the exact situation I described.  Great!  But it doesn't seem to work for me.  It correctly redisplays bad input, but when good input is supplied for this field but another field has bad input, this field is redisplayed as blank. Also, if all good input is supplied, the format doesn't seem to take effect.

     I had this as my format string:

    "{0:MM/dd/yyyy}"

     and entered this:

    1/1/1

     and this is what was redisplayed:

    1/1/2001 12:00:00 AM

  • Re: ViewDataDictionary change mentioned in release notes

    10-20-2008, 1:05 PM
    Answer
    • Contributor
      4,440 point Contributor
    • levib
    • Member since 07-23-2007, 7:50 PM
    • Redmond, WA
    • Posts 773
    • AspNetTeam

    We never apply formatting to the user input.  The behavior is that if the user types in a value, we'll save that value in ModelState and redisplay that value in the textbox, regardless of whether or not that value was correct.  Only if there's no ModelState["blah"].AttemptedValue will we use the explicit value passed to the TextBox() helper, which in this case is a formatted ViewData.

    The DefaultModelBinder is responsible for populating the ModelState dictionary with all of the values that it pulls.  If you're using a custom model binder, be sure that it's correctly populating the ModelState dictionary with all attempted values.

    Are you able to repro this behavior using our default binder and helpers?  I can take a look at it if you are.

  • Re: ViewDataDictionary change mentioned in release notes

    10-20-2008, 3:35 PM
    • Member
      184 point Member
    • bradleylandis
    • Member since 06-19-2008, 11:28 AM
    • Posts 97

    Okay, I am currently only filling the Modelstate for fields with Input Errors.  Now it makes sense that they split "SetAttemptedValue" from "AddModelError" in the Beta.

Page 1 of 1 (7 items)