自定义模型绑定器不验证模型

2023-12-25

我开始使用 knockout.js,在此过程中我使用了 FromJsonAttribute(由 Steve Sanderson 创建)。我遇到了自定义属性不执行模型验证的问题。我整理了一个简单的示例——我知道它看起来有很多代码——但基本问题是如何在自定义模型绑定程序中强制验证模型。

using System.ComponentModel.DataAnnotations;

namespace BindingExamples.Models
{
    public class Widget
    {
        [Required]
        public string Name { get; set; }
    }
}

这是我的控制器:

using System;
using System.Web.Mvc;
using BindingExamples.Models;

namespace BindingExamples.Controllers
{
    public class WidgetController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(Widget w)
        {
            if(this.ModelState.IsValid)
            {
                TempData["message"] = String.Format("Thanks for inserting {0}", w.Name);
                return RedirectToAction("Confirmation");
            }
            return View(w);
        }

        [HttpPost]
        public ActionResult PostJson([koListEditor.FromJson] Widget w)
        {
            //the ModelState.IsValid even though the widget has an empty Name
            if (this.ModelState.IsValid)
            {
                TempData["message"] = String.Format("Thanks for inserting {0}", w.Name);
                return RedirectToAction("Confirmation");
            }
            return View(w);
        }

        public ActionResult Confirmation()
        {
            return View();
        }

    }
}

我的问题是该模型在我的 PostJson 方法中始终有效。为了完整起见,这里是 FromJson 属性的 Sanderson 代码:

using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace koListEditor
{
    public class FromJsonAttribute : CustomModelBinderAttribute
    {
        private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();

        public override IModelBinder GetBinder()
        {
            return new JsonModelBinder();
        }

        private class JsonModelBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
                if (string.IsNullOrEmpty(stringified))
                    return null;
                var model = serializer.Deserialize(stringified, bindingContext.ModelType);
                return model;
            }
        }
    }
}

描述

The FromJsonAttribute仅绑定到模型,并且像您所说的那样,不进行验证。

您可以将验证添加到FromJsonAttribute为了根据他的 DataAnnotations 属性验证模型。

这可以使用以下方法完成TypeDescriptor class.

类型描述符提供有关组件特征的信息,例如其属性、属性和事件。

看看我的解决方案。我已经测试过了。

Solution

private class JsonModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
        if (string.IsNullOrEmpty(stringified))
            return null;
        var model = serializer.Deserialize(stringified, bindingContext.ModelType);

        // DataAnnotation Validation
        var validationResult = from prop in TypeDescriptor.GetProperties(model).Cast<PropertyDescriptor>()
                                from attribute in prop.Attributes.OfType<ValidationAttribute>()
                                where !attribute.IsValid(prop.GetValue(model))
                                select new { Propertie = prop.Name, ErrorMessage = attribute.FormatErrorMessage(string.Empty) };

        // Add the ValidationResult's to the ModelState
        foreach (var validationResultItem in validationResult)
            bindingContext.ModelState.AddModelError(validationResultItem.Propertie, validationResultItem.ErrorMessage);

        return model;
    }
}

更多信息

  • 类型描述符类 http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspx
  • System.ComponentModel.DataAnnotations 命名空间 http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义模型绑定器不验证模型 的相关文章

随机推荐

  • 在Android中将时间戳转换为日期?

    我正在实现一个Android应用程序 我想将时间戳转换为日期 但我无法成功 我尝试过以下事情 请检查一下我是否做错了什么 我正在传递这个值 myTimestamp 1328015914 DateFormat getDateFormat mC
  • 如何在drools中调用Java函数?

    我想从 Utils 类调用 Java 函数 该函数调用 JPA Repository 方法来检索自定义对象 我想从 Drools 决策表中调用这个函数 现在 这个简单的函数给出了空指针异常 我已经为此浪费了几个小时 我在决策表的 导入 部分
  • 如何从服务器获取客户端套接字的确认?

    我有一个向服务器发送消息的客户端套接字 每当服务器收到消息时 我想在客户端得到确认 是否有可能得到这种认可 我使用apache mina开发客户端 提前致谢 TCP中没有消息 只有字节流 有一个内部 ACK 机制可以跟踪有多少流已被正确接收
  • 如何让 PowerShell 等到命令完成后再继续?

    我使用以下行根据其产品 ID 卸载 Office 2007 Start Process C Windows System32 msiexec exe ArgumentList uninstall 90120000 0030 0000 000
  • 使用缓存时的 Rails 字符编码问题

    我正在使用 Rails fragemnet 缓存来缓存一些 html 下面是我的代码
  • Spark 数据集唯一 id 性能 - row_number 与 monotonically_increasing_id

    我想为我的数据集行分配一个唯一的 ID 我知道有两种实现选项 第一个选项 import org apache spark sql expressions Window ds withColumn id row number over Win
  • Cassandra轻量级事务的一致性级别

    我读到了 Cassandra 2 的轻量级事务 这样写的一致性级别是always在法定人数 这是否意味着即使我有一个包含 100 个节点的多数据中心设置 也会涉及整个集群的仲裁 所有数据中心的行副本的大多数 这会不会很慢并且不会影响可用性吗
  • C++11 是否允许非匿名联合包含静态数据成员?

    在 C 11 中 我声明以下联合 union U4 char c int i static int si 当我使用 std c 11 pedantic errors 使用 g 4 7 0 编译此代码时 出现以下错误 经过少量编辑 错误 本地
  • 从 React Native 中的模态窗口打开模态窗口

    我正在尝试打开一个Modal from a TouchHighlight位于另一个模态中 基本上应该发生的是 TouchHighlight在父主干中Modal应该再开一个中学Modal在它之上 而不关闭主Modal 但我收到以下错误 War
  • ASP.NET MVC4 异步控制器 - 为什么使用?

    我试图理解为什么以及何时应该使用async控制器动作 最终 当我使用await其中 它将等待操作完成才能返回视图 例如 public async Task
  • 我们可以从子元素样式中设置父元素样式吗?

    div div div div 我可以从子样式中设置主样式吗 级联样式表只能向下 级联 因此它们根本不是为了执行此操作而设计的 即使在极少数情况下也是如此very如果他们这样做的话就很方便了 您需要 JavaScript 内联样式或不同的布
  • 在Python中交换字符串大小写[重复]

    这个问题在这里已经有答案了 我是Python新手 因此问题是 我正在尝试解决一个简单的问题 其中程序接受一个简单的字符串并交换所有大小写 因此如果我们输入 SimPLE 我们应该得到 sIMple 这是我的代码 def main oldSt
  • grunt-init 模板条件复制文件

    我刚刚开始使用 grunt init 我一切正常 我想知道是否有一种方法可以根据提示 基于先前提示的答案 进行条件复制根文件 您可以使用rename json文件通过docs http gruntjs com project scaffol
  • Google Play 商店:我的应用程序页面不显示排行榜和成就图标/徽章

    本周我在谷歌游戏商店推出了一个应用程序 该应用程序使用 Google Play 游戏排行榜和成就 API Play 商店应用程序中的应用程序页面是否应该像使用这些 API 的其他应用程序中那样显示这些图标 徽章 我需要在任何地方启用它吗 这
  • 将 HttpContext.Current.User 与异步等待一起使用的正确方法

    我正在使用异步操作并像这样使用 HttpContext Current User public class UserService IUserService public ILocPrincipal Current get return H
  • Ruby:为什么这种使用地图的方式会抛出错误?

    我尝试缩短 values map value value gsub n with values map gsub n 但它给了我一个 SyntaxError csv creator rb 40 syntax error unexpected
  • 使用 WIX 安装自我更新应用程序?

    我正在编写一个需要安装在大量桌面上并且还需要自我更新的应用程序 我们正在寻找 WIX 来创建安装 我使用过 ClickOnce 对于此安装来说它不是一个好的解决方案 WIX似乎适合 但我发现没有好的自动更新过程 我看过通过点击 http w
  • Spring Security ACL 域错误:类型 xxx 已定义

    我正在使用 Eclipse Grails 2 4 5 和Spring Security ACL 插件 https grails org plugin spring security acl 我使用以下命令创建了管理 ACL 数据的域类 s2
  • 简单的 Ajax/PHP 调试

    我正在测试一个 Ajax jQuery 加载的 PHP 模块 我想知道是否有一种简单的方法可以在不使用全功能调试器的情况下对其进行调试 我非常简单的调试选项是回显一些数据并读取浏览器输出 但是由于 Ajax 加载模块的性质 输出是隐藏的 虽
  • 自定义模型绑定器不验证模型

    我开始使用 knockout js 在此过程中我使用了 FromJsonAttribute 由 Steve Sanderson 创建 我遇到了自定义属性不执行模型验证的问题 我整理了一个简单的示例 我知道它看起来有很多代码 但基本问题是如何