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
最满意答案
所以我想出了一个很好的妥协。 我从这里描述的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:
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")
相关问答
更多-
用于学校教学的电脑网络教室,它的网络类型属于() A.互联网 B.广域网 C.城域网 D.局域网[2023-01-12]
d -
TCP/IP模型是一个________。[2023-10-02]
a -
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
这听起来像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 ...
-
可视化3D数据集(Visualizing a 3D data set)[2024-01-23]
改为使用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 ...
-
可视化3D数据结构(Visualizing a 3D datastructure)[2022-06-08]
所以我想出了一个很好的妥协。 我从这里描述的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, ...