2014-03-01 137 views
0

我是ASP.NET MVC的新手,遇到了一个新手问题。ASP.NET mvc 5,实体框架,排除modeldata

我创建了一个窗体,其中一些数据只能从视图发送到控件,如果满足一些条件。比如,我收到了一个复选框,上面有一个文字说“今天”,如果其未点击的文本字段应该出现在用户可以输入更早日期的地方。

我的问题是:我如何与最佳实践(我已经解决了JavaScript的问题,填写/清除字段,但这真的很难看)告诉它根据某些条件排除/包括字段。

我想是这样的:

public ActionResult Create([Bind(Include = "EventID,ActivityID", Exclude = "EventDate")] FSEvent fsevent) 
{ 
     if (ModelState.IsValid) 
     { 
      if (fsevent.EventDate == DateTime.MinValue) 
      { 
       fsevent.EventDate = DateTime.Now; 
      } 

      db.FSEvents.Add(fsevent); 
      db.SaveChanges(); 

      return RedirectToAction(returnUrl); 
     } 

     ViewBag.ActivityID = new SelectList(db.FSEventItems, "ActivityID", "Name", fsevent.ActivityID); 
     ViewBag.UserID = new SelectList(db.FSUsers, "UserID", "FirstName", fsevent.UserID); 

     return View(fsevent); 
    } 

但浏览器给我(用户)“的EVENTDATE字段是必须”在JavaScript验证(MVC EF BUIT错误信息,所以如果我禁用了JavaScript的它工作正常)。

回答

1


我得到了类似的问题,并使用自定义属性解决它。
下面您可以找到ViewModel,视图和属性。

视图模型

public class TheViewModel{ 

    [Display(Name = "YourOtherFieldDisplayName", ResourceType = typeof(YourResourceFile))] 
    public string YourOtherField { get; set; } 

    [Display(Name = "YourFieldDisplayName", ResourceType = typeof(YourResourceFile))] 
    [RequiredIf("TheOtherField", true, ErrorMessageResourceName = "FieldRequired", ErrorMessageResourceType = typeof(YourResourceFile))] 
    public string YourField { get; set; } 
} 

@Html.LabelFor(model => model.YourOtherField) 
@Html.CheckBoxFor(model => model.YourOtherField) 
@Html.LabelFor(model => model.YourField) 
@Html.TextBoxFor(model => model.YourField) 
@Html.ValidationMessageFor(model => model.YourField) 

属性

namespace YOURNAMESPACE.attributes 
{ 
    public class RequiredIfAttribute : ValidationAttribute, IClientValidatable 
    { 
     private RequiredAttribute _innerAttribute = new RequiredAttribute(); 

     public string DependentProperty { get; set; } 
     public object TargetValue { get; set; } 

     public RequiredIfAttribute(string dependentProperty, object targetValue) 
     { 
      this.DependentProperty = dependentProperty; 
      this.TargetValue = targetValue; 
     } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      var containerType = validationContext.ObjectInstance.GetType(); 
      var field = containerType.GetProperty(this.DependentProperty); 

      if (field != null) 
      { 
       var dependentvalue = field.GetValue(validationContext.ObjectInstance, null); 

       // compare the value against the target value 
       if ((dependentvalue == null && this.TargetValue == null) || 
        (dependentvalue != null && dependentvalue.Equals(this.TargetValue))) 
       { 
        if (!_innerAttribute.IsValid(value)) 
         return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName }); 
       } 
      } 

      return ValidationResult.Success; 
     } 

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

      string depProp = BuildDependentPropertyId(metadata, context as ViewContext); 

      string targetValue = (this.TargetValue ?? "").ToString(); 
      if (this.TargetValue.GetType() == typeof(bool)) 
       targetValue = targetValue.ToLower(); 

      rule.ValidationParameters.Add("dependentproperty", depProp); 
      rule.ValidationParameters.Add("targetvalue", targetValue); 

      yield return rule; 
     } 

     private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext) 
     { 
      // build the ID of the property 
      string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(this.DependentProperty); 
      var thisField = metadata.PropertyName + "_"; 
      if (depProp.StartsWith(thisField)) 
       depProp = depProp.Substring(thisField.Length); 
      return depProp; 
     } 
    } 
} 

我希望这能帮助你

0

你也可以直接从输入日期的字段获取数据,并且只验证该字段。

通过这种方式,您选中/取消选中的复选框只是帮助用户界面显示隐藏的内容,但它不是验证或有效内容的一部分。你总是只从隐藏或可见的字段中取回日期。

它也将简化您的控制器代码。