2012-10-08 12 views
0

我創建它填充了枚舉值選擇列表驗證過程中的初始值:MVC3 Html.SelectList - 總是看到即使所選的選項已經改變

<%= Html.DropDownListFor(model => model.OrderStatus, new SelectList(Enum.GetValues(typeof(OrderStatus))))%> 

我現在執行客戶端驗證,以確保該OrderStatus設置正確:

[DisplayName("Order Status"), EnsureOrderStatus("ID")] 
public OrderStatus OrderStatus { get; set; } 


public class EnsureOrderStatus : ValidationAttribute, IClientValidatable 
    { 
     private readonly string OrderIDPropertyName; 

     public EnsureOrderStatus(string orderIDPropertyName) 
     { 
      OrderIDPropertyName = orderIDPropertyName; 
     } 

     protected override ValidationResult IsValid (object value, ValidationContext validationContext) 
     { 
      ValidationResult validationResult = ValidationResult.Success; 

      var propertyTestedInfo = validationContext.ObjectType.GetProperty(OrderIDPropertyName); 
      if (propertyTestedInfo == null) 
      { 
       validationResult = new ValidationResult(string.Format("Unknown property {0}", OrderIDPropertyName)); 
      } 
      else 
      { 
       int orderID = (int)propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); 
       OrderStatus orderStatus = (OrderStatus)value; 

       if (orderID == 0 && orderStatus != OrderStatus.Future) 
       { 
        validationResult = new ValidationResult(string.Format("Order must have have an Order Status of Future when being created.")); 
       } 
      } 

      return validationResult; 
     } 

     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      var rule = new ModelClientValidationRule 
       { 
        ErrorMessage = ErrorMessage, 
        ValidationType = "ensureorderstatus" 
       }; 

      rule.ValidationParameters["orderid"] = OrderIDPropertyName; 
      yield return rule; 
     } 
    } 

「價值」的IsValid內的值總是OrderStatus的第一個枚舉值。我想知道是否需要採取其他步驟來確保DropDownList元素的選定值正確更新。

更新的代碼:

//OrderDetailsModel: 
[DisplayName("Order Status"), EnsureOrderStatus("ID")] 
public OrderStatus OrderStatus { get; set; } 
public List<OrderStatusModel> OrderStatusModels = new List<OrderStatusModel>(); 

public OrderDetailsModel() 
{ 
    OrderStatusModels.Add(new OrderStatusModel { EnumStatus = OrderStatus.Active, StringStatus = "Active" }); 
    OrderStatusModels.Add(new OrderStatusModel { EnumStatus = OrderStatus.Completed, StringStatus = "Completed" }); 
    OrderStatusModels.Add(new OrderStatusModel { EnumStatus = OrderStatus.Future, StringStatus = "Future" }); 
} 


<%= Html.DropDownListFor(model => model.OrderStatus, new SelectList(Model.OrderStatusModels, "StringStatus", "EnumStatus"))%> 

回答

2

我會重新考慮這個..個人。試圖將枚舉破解到SelectList中會產生比所需更多的工作。

簡單地說,這個包裹中的所有視圖模型..看看這個:

public enum OrderStatus { 
    NOT_SHIPPED, 
    SHIPPED 
} 

public class ViewModel { 
    public OrderStatus SelectedStatus { get; set; } 
    public List<StatusViewModel> Models = new List<StatusViewModel>(); 
} 

public class StatusViewModel { 
    public string StringStatus { get; set; } 
    public OrderStatus EnumStatus { get; set; } 
} 

設置(也許在控制器..或其他地方)涉及這樣的:

ViewModel model = new ViewModel(); 

model.Models.Add(new StatusViewModel() { EnumStatus = OrderStatus.NOT_SHIPPED, StringStatus = "Not shipped" }); 
model.Models.Add(new StatusViewModel() { EnumStatus = OrderStatus.SHIPPED, StringStatus = "Shipped" }); 

return View(model); 

..和你觀點很簡單:

@model Models.ViewModel 
@Html.DropDownListFor(x => x.SelectedStatus, new SelectList(Model.Models, "StringStatus", "EnumStatus")) 

然後,當你的模型被張貼後入室,SelectedStatus強烈鍵入OrderStatus枚舉:

public ActionResult Index(ViewModel model) { 
    // model.SelectedStatus is an OrderStatus 
} 
+0

我會試試這個......它看起來更像我在想什麼。一致認爲枚舉位是一個黑客。 –

+0

再次。我試過了代碼,我真的很喜歡它的前進方向,但我不確定你最後一段代碼。我正在嘗試執行不顯眼的客戶端驗證。我已將我的EnsureOrderStatus屬性應用於OrderStatus屬性。雖然我看到將我的枚舉分解爲模型的許多其他好處 - 但我不明白(或者看到它影響)OrderStatus在IsValid內部始終默認爲其初始值這一事實。 –

相關問題