Hello MVC和LINQ Experts,
我的模型看起来像这样:
public class SomeClass : IValidatableObject
{
public string SomeString { get; set; }
public string SomeString2 { get; set; }
public int SomeInteger { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
//... IF there is some error...THEN
yield return new ValidationResult("Some Error Message.", GetFieldNames(() => new []{ this.SomeString }));
}
}
正如您所看到的,我正在调用带有表达式的GetFieldNames,并将表达式成员作为字符串数组返回给您。根据我最近阅读的一本书,将错误链接到字段的方法是将其作为字符串传递,如下所示:
yield return new ValidationResult("Some Error Message.", new []{ "SomeString" }));
但我想成为强类型,所以这是我写的方法:
public static string[] GetFieldNames(Expression<Func<object[]>> exp)
{
//Build a string that will in the end look like this: field1,field2,field3
//Then we split(',') it into an array and return that string array.
string fieldnames = "";
MemberExpression body = exp.Body as MemberExpression;
if (body == null)
{
NewArrayExpression ubody = (NewArrayExpression)exp.Body;
foreach(MemberExpression exp2 in ubody.Expressions)
{
fieldnames += exp2.Member.Name + ",";
}
fieldnames = fieldnames.TrimEnd(',');
}
if(fieldnames.Length > 0)
return fieldnames.Split(',');
else
return new string[]{};
}
当前用法:
GetFieldNames(() => new[] { this.SomeString , this.SomeString2 });
输出:
{ "SomeString" , "SomeString2" }
这很好用。
问题是,如果我按如下方式使用它,它会给我一个错误(编译时):
GetFieldNames(() => new[] { this.SomeString , this.SomeInteger });
错误:
No best type found for implicitly-typed array
我想要的输出:
{ "SomeString" , "SomeInteger" }
我无法传入一个对象数组,因为int不是一个复杂的类型。
如何使用int
和string
传递函数表达式数组?
答案 0 :(得分:1)
您可以尝试传递一个对象数组(这是您的表达式所期望的),而不是尝试使用数组初始化程序语法:
GetFieldNames(() => new object[] { this.SomeString, this.SomeInteger });
这允许您传递任意对象类型。
答案 1 :(得分:0)
您可以定义一个接口IFieldName,它允许在列表中使用,然后在处理过程中出现的实际类型的不同类(int,error,string等)中实现它。
这大致相当于定义对象的rray,但恢复了类型安全性。
答案 2 :(得分:0)
在Darin Dimitri的帮助下(传递new object[]
代替new []
的想法
以下代码将确保您的IValidatableObject
现在可以强类型而不仅仅是字符串数组。
public static string[] GetFieldNames(Expression<Func<object[]>> exp)
{
string fieldnames = "";
MemberExpression body = exp.Body as MemberExpression;
if (body == null)
{
NewArrayExpression ubody = (NewArrayExpression)exp.Body;
foreach (Expression exp2 in ubody.Expressions)
{
if (exp2 is MemberExpression) {
fieldnames += ((MemberExpression)exp2).Member.Name + ",";
}
else {
var op = ((UnaryExpression)exp2).Operand;
fieldnames += ((MemberExpression)op).Member.Name + ",";
}
}
fieldnames = fieldnames.TrimEnd(',');
}
if(fieldnames.Length > 0)
return fieldnames.Split(',');
else
return new string[]{};
}
用法:
GetFieldNames(() => new object[] { this.SomeString, this.SomeInteger }));
MVC验证的用法:
yield return new ValidationResult("Some Error.", GetFieldNames(() => new object[] { this.SomeString, this.SomeInteger }));