0

列挙値が入力された選択リストを作成しています:

<%= 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 内の「value」の値は、常に 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"))%>
4

1 に答える 1

2

私はこれを再考します..個人的に。列挙型を SelectList にハックしようとすると、必要以上の作業が発生します。

単純に、これをすべてViewModelでラップします..これを考慮してください:

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
}
于 2012-10-08T23:36:08.270 に答える