ASP.NET MVC自定义验证(有条件地要求)

时间:2013-10-14 14:57:17

标签: jquery asp.net entity-framework asp.net-mvc-4 data-annotations

我在ASP.NET MVC中遇到自定义验证问题。我想在下面实现ServerName属性的条件必需验证。条件是如果ServerSpecific属性为true,则ServerName应为必填字段。我已经使用Validate方法来做这件事,但由于某种原因,特定代码Vlaidate methof在任何情况下都不会命中。这里有什么遗漏吗?

public class PlatformConfigurationEditModel : IValidatableObject
{
    #region Constructor
    public PlatformConfigurationEditModel()
    {
        SettingEnabled = true;
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (ServerSpecific == true && String.IsNullOrEmpty(ServerName)) 
        {
            yield return new ValidationResult("Please provide Server Name!.");
        }
    }

    [ScaffoldColumn(false)]
    public int Id { get; set; }
    [Required]

    [ScaffoldColumn(false)]
    public int PlatformProfileId { get; set; }

    [Required]
    [ScaffoldColumn(false)]
    public int EnvironmentId { get; set; }

    [Required]
    [DisplayName("Setting Name")]
    [JqGridColumnEditable(true, EditType = JqGridColumnEditTypes.Text)]
    public string SettingName { get; set; }

    [Required]
    [JqGridColumnEditable(true, EditType = JqGridColumnEditTypes.Text)]
    [DisplayName("Setting Value")]
    public string SettingValue { get; set; }

    [Required]
    [DisplayName("Setting Enabled")]
    [JqGridColumnSearchable(false)]
    [JqGridColumnEditable(true, EditType = JqGridColumnEditTypes.CheckBox)]
    public bool SettingEnabled { get; set; }

    [DisplayName("Server Specific")]
    [JqGridColumnSearchable(false)]
    [JqGridColumnEditable(true, EditType = JqGridColumnEditTypes.CheckBox)]
    public Nullable<bool> ServerSpecific { get; set; }


    [DisplayName("Server Name")]
    [JqGridColumnEditable(true, "GetServers", "Profile", EditType = 
                                                  JqGridColumnEditTypes.Select)]
    public string ServerName { get; set; }

    [ScaffoldColumn(false)]
    public Nullable<int> ServerId { get; set; }

    [ScaffoldColumn(false)]
    public int ProfileVersionId { get; set; }

  }

}

控制器操作方法

   [HttpPost]
    public ActionResult Add(
        [ModelBinder(typeof(PlatformConfigurationEditModelBinder))]
        PlatformConfigurationEditModel platformconfiguration)
    {
        if (ModelState.IsValid)
        {
            #region web binding value adjustments

            if (platformconfiguration.SettingName.ToLower() == "webbinding")
            {
                platformconfiguration.SettingValue = ModifyWebBinding  
                (platformconfiguration.SettingValue);
            }

            #endregion

            var updatedEntity = From<PlatformConfigurationEditModel>.To<PlatformConfiguration>
                                 (platformconfiguration);
            ////
            //// update server id
            ////

            if (updatedEntity.ServerSpecific.HasValue && updatedEntity.ServerSpecific.Value)
            {
                updatedEntity.ServerId = Convert.ToInt32(platformconfiguration.ServerName);
            }

            _context.PlatformConfigurations.Add(updatedEntity);
            _context.SaveChanges();
        }
        return RedirectToAction("Add");

    }

模型活页夹 -

 public class PlatformConfigurationEditModelBinder : IModelBinder
    {
    public object BindModel(ControllerContext controllerContext,
                            ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        int environmentId;
        int profileId;
        int id = 0;
        int pfvid;

        string paramdata = request.Params["Id"];

        if (!paramdata.Equals("_empty"))
        {
            int[] data = request.Params["id"].Split('-').Select(n => Convert.ToInt32(n)).ToArray
            ();
            id = data[0];
            profileId = data[1];
            environmentId = data[2];
            pfvid = data[3];
        }
        else
        {
            id = 0;
            int[] extdt = request.Params["ExtData"].Split('-').Select(n => Convert.ToInt32
            (n)).ToArray();
            profileId = extdt[0];
            environmentId = extdt[1];
            pfvid = extdt[2];
        }

        string settingEnabled = request.Params["SettingEnabled"];
        string serverSpecific = request.Params["ServerSpecific"];

        string settingName = request.Params["SettingName"];
        string settingValue = request.Params["SettingValue"];
        string serverName = request.Params["ServerName"];


        return new PlatformConfigurationEditModel
            {
                Id = id,
                EnvironmentId = environmentId,
                PlatformProfileId = profileId,
                ServerSpecific = serverSpecific.ToLower() == "on" || serverSpecific.ToLower() 
                == "true",
                SettingEnabled = settingEnabled.ToLower() == "on" || settingEnabled.ToLower() 
                == "true",
                ServerName = serverName,
                SettingName = settingName,
                SettingValue = settingValue,
                ProfileVersionId = pfvid
            };
    }
}

1 个答案:

答案 0 :(得分:0)

我会让你的自定义模型绑定器继承自DefaulModelBinder而不是IModelBinder。然后在最后调用基本实现,然后您将获得Validation支持。

您甚至可以考虑使用Jimmy Bogard的“Smart Binder”

http://lostechies.com/jimmybogard/2009/03/18/a-better-model-binder/

这允许您创建一个模型绑定器数组,这些绑定器在完成后仍然会调用基本实现。

请记住,只有在所有其他验证成功后才会调用Validate。这意味着,如果您有客户端验证,那么这些验证将首先失败。并且用户必须在调用IValidatableObject.Validate之前修复它们。

另外两个好资源是这两篇文章:

http://odetocode.com/Blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx

http://odetocode.com/blogs/scott/archive/2009/05/05/iterating-on-an-asp-net-mvc-model-binder.aspx