首页 \ 问答 \ ASP.Net MVC:如何动态地向任何模型属性添加验证(ASP.Net MVC: How to add validation to any model property on the fly)

ASP.Net MVC:如何动态地向任何模型属性添加验证(ASP.Net MVC: How to add validation to any model property on the fly)

我很高兴知道如何在运行时向我的模型的任何属性添加验证而不触及代码。 所以寻找指南如何在asp.net mvc中实现我的目标。

样本模型属性

[Required(ErrorMessage = "The field {0} is required")]
[Display(Name = "Company")]
public string Name { get; set; }

上面的代码是一个示例,其中在编码时添加了验证,但我不想在编码时附加验证,而我想在运行时以这样的方式编码,我将能够向任何模型注入验证属性。

我搜索谷歌并找到一个样本,但不明白如何使用它来完成我的任务。 这是我找到的示例代码,但不清楚如何将它用于我的目的。

在模型中:

[Domainabcd(20, "Bar", "Baz", ErrorMessage = "The combined minimum length of the Foo, Bar and Baz properties should be longer than 20")]
public string strAccessionId { get; set; }

在DomainabcdAttribute.cs中:

public class DomainabcdAttribute : ValidationAttribute, IClientValidatable
 //Domain is the Attribute name 
//if you do not inherit IClientValidatable ,the server validation still will work ,but the Client validation will not work.

    {
        public DomainAttribute(int minLength, params string[] propertyNames) 
// this is where to get parameters from you pass 
//such as : 20, "Bar", "Baz",
        {
            this.PropertyNames = propertyNames;
            this.MinLength = minLength;
        }

        public string[] PropertyNames { get; private set; }
        public int MinLength { get; private set; }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
           ///this is where to decide if to display error ,or not.
            //var properties = this.PropertyNames.Select(validationContext.ObjectType.GetProperty);
            //var values = properties.Select(p => p.GetValue(validationContext.ObjectInstance, null)).OfType<string>();
            //var totalLength = values.Sum(x => x.Length) + Convert.ToString(value).Length;
            //if (totalLength < this.MinLength)
            //{
               //this is the place to return the validation result
             //so you may just use this line code:   return new ValidationResult(validationContext.DisplayName)
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            //}
            //return null; //no error massage

       }
        //this is for Client to display error message 
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var modelClientValidationRule = new ModelClientValidationRule
            {
                ValidationType = "requiredif",
                ErrorMessage = ErrorMessage //Added ,pass the error message 

            };

            modelClientValidationRule.ValidationParameters.Add("param", this.PropertyNames); //Added
            return new List<ModelClientValidationRule> { modelClientValidationRule };

        }
        // public override string FormatErrorMessage(string name) //to custom format for error message
        //{
        //    string[] values = this.Values.Select(value => string.Format("'{0}'", value)).ToArray();
        //     //return string.Format("{0}{1}", name, string.Join(",", values));
        //     return string.Format(base.ErrorMessageString, name, string.Join(",", values));
        // }
    }

我的目标如下

1)假设第一天我将在运行时向name属性添加验证,如名称应该是必需的

2)几天后我会在名称属性中添加另一个验证,假设名称不应该有像@ , : # etc特殊字符。

3)几天之后我会再次向名称属性添加另一个验证,假设名称的长度不应小于10个字符。

希望我清楚我想要实现的目标。 所以,任何做过它的人都只是帮我提供示例代码。

谢谢


i am curios to know how could i add validation to any property of my model at run time without touching the code. so looking for guide line how to achieve what i am after in asp.net mvc.

sample model property

[Required(ErrorMessage = "The field {0} is required")]
[Display(Name = "Company")]
public string Name { get; set; }

the above code is a sample where validation has been added when coding but i do not want to attach validation at coding time rather i want to code in such a way as a result at the run time i will be able to inject validation to any model property.

i search a google and found a sample but do not understand how to use it to achieve my task. here is a sample code what i found but not clear how to use it for my purpose.

in Model:

[Domainabcd(20, "Bar", "Baz", ErrorMessage = "The combined minimum length of the Foo, Bar and Baz properties should be longer than 20")]
public string strAccessionId { get; set; }

in DomainabcdAttribute.cs:

public class DomainabcdAttribute : ValidationAttribute, IClientValidatable
 //Domain is the Attribute name 
//if you do not inherit IClientValidatable ,the server validation still will work ,but the Client validation will not work.

    {
        public DomainAttribute(int minLength, params string[] propertyNames) 
// this is where to get parameters from you pass 
//such as : 20, "Bar", "Baz",
        {
            this.PropertyNames = propertyNames;
            this.MinLength = minLength;
        }

        public string[] PropertyNames { get; private set; }
        public int MinLength { get; private set; }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
           ///this is where to decide if to display error ,or not.
            //var properties = this.PropertyNames.Select(validationContext.ObjectType.GetProperty);
            //var values = properties.Select(p => p.GetValue(validationContext.ObjectInstance, null)).OfType<string>();
            //var totalLength = values.Sum(x => x.Length) + Convert.ToString(value).Length;
            //if (totalLength < this.MinLength)
            //{
               //this is the place to return the validation result
             //so you may just use this line code:   return new ValidationResult(validationContext.DisplayName)
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            //}
            //return null; //no error massage

       }
        //this is for Client to display error message 
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var modelClientValidationRule = new ModelClientValidationRule
            {
                ValidationType = "requiredif",
                ErrorMessage = ErrorMessage //Added ,pass the error message 

            };

            modelClientValidationRule.ValidationParameters.Add("param", this.PropertyNames); //Added
            return new List<ModelClientValidationRule> { modelClientValidationRule };

        }
        // public override string FormatErrorMessage(string name) //to custom format for error message
        //{
        //    string[] values = this.Values.Select(value => string.Format("'{0}'", value)).ToArray();
        //     //return string.Format("{0}{1}", name, string.Join(",", values));
        //     return string.Format(base.ErrorMessageString, name, string.Join(",", values));
        // }
    }

my objective as follows

1) suppose first day i will add validation to name property at run time like name should be required

2) after few days i will add another validation to name property on the fly suppose name should not have special character like @ , : # etc.

3) again after few days i will add another validation to name property on the fly suppose name's length should not be less than 10 character.

hope i am clear what i am trying to achieve. so please anyone who did it just help me with sample code.

thanks


原文:https://stackoverflow.com/questions/42714701
更新时间:2023-03-01 08:03

最满意答案

所以我想出了一个很好的妥协。 我从这里描述的git代码开始:

http://www.shocksolution.com/microfluidics-and-biotechnology/visualization/python-vtk-paraview/

它只是一个python文件。 要点是允许您为点提供x,y,z位置和半径的代码,并输出VTK格式的XML文件。 因此,为了做粒子,我只需将x,y,z位置,然后是所有粒子半径的常数。 然后我只在数据集上制作一个球形字形。

对于框,我使用完全相同的代码。 对于每个盒子,我仍然输出x,y,z坐标,其中x,y,z值是盒子中心的坐标。 然后,对于“radius”参数,我使用立方体的边长。 这是有效的,因为再次在paraview我只是标记框的数据点。 我使用方框字形,并按标量缩放,标量是半径。 如果不定位方框字形并将标量因子设置为1,则会得到所需的结果。 这是一个简单的例子,一切都是统一的:

简单的统一树

所以我只是将C数据结构中的坐标输出到CSV文件,然后在python中输入文件并使用链接中的代码并使用paraview打开结果。 以下是我在链接中使用代码的方式:

from vtktools import VTK_XML_Serial_Unstructured
import sys

if len(sys.argv) > 2:
    treeFile = sys.argv[1]
    bodyFile = sys.argv[2]
else:
    print 'No input files'
    exit(4)

x = []
y = []
z = []
r = []

f = open(treeFile, 'r')
for line in f:
    v = line.split(',')
    x.append(float(v[0].strip()))
    y.append(float(v[1].strip()))
    z.append(float(v[2].strip()))
    r.append(float(v[3].strip()))
f.close()

temp = treeFile.split('/')
if (len(temp) == 1):
    temp = temp[0]
else:
    temp = temp[-1]
tree_writer = VTK_XML_Serial_Unstructured()
tree_writer.snapshot(temp.split('.',1)[0] + '.vtu', x, y, z, [], [], [], [], [], [], r)
tree_writer.writePVD("octree.pvd")
x = []
y = []
z = []
r = []

f = open(bodyFile, 'r')
for line in f:
    v = line.split(',')
    x.append(float(v[0].strip()))
    y.append(float(v[1].strip()))
    z.append(float(v[2].strip()))
    r.append(float(v[3].strip()))
f.close()

temp = bodyFile.split('/')
if (len(temp) == 1):
    temp = temp[0]
else:
    temp = temp[-1]
body_writer = VTK_XML_Serial_Unstructured()
body_writer.snapshot(temp.split('.',1)[0] + '.vtu', x, y, z, [], [], [], [], [], [], r)
body_writer.writePVD("distribution.pvd")

So I figured out a nice compromise. I started with the git code as described here:

http://www.shocksolution.com/microfluidics-and-biotechnology/visualization/python-vtk-paraview/

It's only one python file. The gist is the code there lets you give x,y,z positions and radius for points and outputs an XML file that is in VTK format. So to do the particles I just hand it the x,y,z positions and then a constant for the radius for all particles. Then I just make a spherical glyph on the datasets.

For the boxes I use the exact same code. For each box I still output x,y,z coordinates where the x,y,z values are the coordinates of the center of the box. Then for the "radius" parameter I use the edge length of the cube. This works because again in paraview I just glyph the datapoints for the boxes. I use the box glyph, and scale by scalar where the scalar is the radius. If you don't orient the box glyphs and set the scalar factor to 1 you get the desired result. Here's a simple example with everything uniform:

Simple Uniform Tree

So I just output the coordinates in my C datastructure to CSV files and then in python pull in the files and use the code at the link and open the result with paraview. Here's how I used the code at the link:

from vtktools import VTK_XML_Serial_Unstructured
import sys

if len(sys.argv) > 2:
    treeFile = sys.argv[1]
    bodyFile = sys.argv[2]
else:
    print 'No input files'
    exit(4)

x = []
y = []
z = []
r = []

f = open(treeFile, 'r')
for line in f:
    v = line.split(',')
    x.append(float(v[0].strip()))
    y.append(float(v[1].strip()))
    z.append(float(v[2].strip()))
    r.append(float(v[3].strip()))
f.close()

temp = treeFile.split('/')
if (len(temp) == 1):
    temp = temp[0]
else:
    temp = temp[-1]
tree_writer = VTK_XML_Serial_Unstructured()
tree_writer.snapshot(temp.split('.',1)[0] + '.vtu', x, y, z, [], [], [], [], [], [], r)
tree_writer.writePVD("octree.pvd")
x = []
y = []
z = []
r = []

f = open(bodyFile, 'r')
for line in f:
    v = line.split(',')
    x.append(float(v[0].strip()))
    y.append(float(v[1].strip()))
    z.append(float(v[2].strip()))
    r.append(float(v[3].strip()))
f.close()

temp = bodyFile.split('/')
if (len(temp) == 1):
    temp = temp[0]
else:
    temp = temp[-1]
body_writer = VTK_XML_Serial_Unstructured()
body_writer.snapshot(temp.split('.',1)[0] + '.vtu', x, y, z, [], [], [], [], [], [], r)
body_writer.writePVD("distribution.pvd")

相关问答

更多
  • 这听起来像timer功能是下一个尝试的好地方,以便了解您的模拟进展,然后在您对事物的外观感到满意后再制作AVI。 MATLAB有一些很好的文档 ,有连续调用的各种选项和它们之间的间距。 查看ExecutionMode和Period属性。 It sounds like the timer function is a good place to try next in order to get a sense of your simulation's progression and then making an ...
  • 由mathworks员工Joe Conti提供了一个名为vol3d的出色工具。 我认为它完全解决了您的可视化需求 - 尝试一下。 更新(11/2012) :链接到上面的文件不再存在。 这里有一个新版本。 There's an excellent utility called vol3d, by mathworks employee Joe Conti. I think it addresses your visualization needs exactly - give it a try. Update ...
  • 改为使用surf ,例如: % Create a grid of x and y points g= linspace(-2, 2, 20); [X, Y] = meshgrid(g, g); % Define the function Z = f(X,Y) Z = 10*exp(-X.^2-Y.^2); % "phong" and "gouraud" lighting are good for curved, interpolated surfaces. surf(X, Y, Z); view(3 ...
  • 原则上,问题的代码应该有效。 然而,目前还不清楚marker=colormap[kmeans.labels_]会做什么以及为什么需要它。 3D散点图与其2D版本完全相同。 标记参数将期望标记字符串,如"s"或"o"来确定标记形状。 可以使用c参数设置颜色。 您可以提供单一颜色或阵列/颜色列表。 在下面的示例中,我们只是将集群索引提供给c并使用colormap。 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D im ...
  • 所以我想出了一个很好的妥协。 我从这里描述的git代码开始: http://www.shocksolution.com/microfluidics-and-biotechnology/visualization/python-vtk-paraview/ 它只是一个python文件。 要点是允许您为点提供x,y,z位置和半径的代码,并输出VTK格式的XML文件。 因此,为了做粒子,我只需将x,y,z位置,然后是所有粒子半径的常数。 然后我只在数据集上制作一个球形字形。 对于框,我使用完全相同的代码。 对于每个 ...
  • 使用scatter3 : x = rand(1,1000); y = rand(1,1000); z = rand(1,1000); %// example x, y, z d = x.^2+y.^2+z.^2; %// example disparity scatter3(x,y,z,8,d,'fill'); colorbar scatter3的第四个输入参数是标记大小。 第五个决定颜色。 'fill'使用填充标记。 Use scatter3: x = rand(1,1000); y = rand(1, ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)