2011-04-03 86 views
8

我使用ASP.NET MVC 3 RTM的價值,我有一個這樣的視圖模型:綁定錯誤刪除用戶輸入

public class TaskModel 
{ 
    // Lot's of normal properties like int, string, datetime etc. 
    public TimeOfDay TimeOfDay { get; set; } 
} 

TimeOfDay屬性是一個自定義的結構我有,這很簡單,所以我不包括在這裏。我製作了一個自定義模型綁定器來綁定這個結構體。模型綁定是非常簡單的:

public class TimeOfDayModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     try 
     { 
      // Let the TimeOfDay struct take care of the conversion from string. 
      return new TimeOfDay(result.AttemptedValue, result.Culture); 
     } 
     catch (ArgumentException) 
     { 
      bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Value is invalid. Examples of valid values: 6:30, 16:00"); 
      return bindingContext.Model; // Also tried: return null, return value.AttemptedValue 
     } 
    } 
} 

我定製的模型綁定工作正常,但問題是當用戶提供的價值不能轉換或解析。發生這種情況時(TimeOfDay構造函數拋出ArgumentException時),我添加了一個模型錯誤,該錯誤在視圖中正確顯示,但用戶鍵入的值無法轉換,將丟失。用戶輸入值的文本框只是空的,並且在HTML源代碼中value屬性被設置爲空字符串:「」。

編輯:我想知道如果它可能是這做得不對我的編輯模板,所以我包括在這裏:

@model Nullable<TimeOfDay> 
@if (Model.HasValue) 
{ 
    @Html.TextBox(string.Empty, Model.Value.ToString()); 
} 
else 
{ 
    @Html.TextBox(string.Empty); 
} 

如何確保數值不會丟失當發生綁定錯誤時,用戶可以更正該值?

回答

17

啊哈!我終於找到了答案! This blog post給出了答案。我所缺少的是在我的模型活頁夾中調用ModelState.SetModelValue()。所以代碼會是這樣的:

public class TimeOfDayModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     try 
     { 
      // Let the TimeOfDay struct take care of the conversion from string. 
      return new TimeOfDay(result.AttemptedValue, result.Culture); 
     } 
     catch (ArgumentException) 
     { 
      bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Value is invalid. Examples of valid values: 6:30, 16:00"); 
      // This line is what makes the difference: 
      bindingContext.ModelState.SetModelValue(bindingContext.ModelName, result); 
      return bindingContext.Model; 
     } 
    } 
} 

我希望這節省了別人從我經歷過的挫折時間。