我有一个使用 C# 和 JavaScript 的通用表单填写系统。表单的数据来自 C# 类。
我正在升级系统,以便它可以执行多页表单(无需回调C#来更改页面)。类成员现在具有指示表单的每个字段显示在哪个页面上的属性。
当表单从 JavaScript 提交到 C# 时,它会调用服务器上的 C# 函数来验证输入。如果输入无效,则会传回错误消息。
我目前使用 Check 函数,如果检查的断言不为 true,则会抛出异常。如果检查函数能够告诉 JavaScript 出现错误的字段位于哪个页面,那就太好了。我希望能够将字段值传递到检查函数中,并且神奇地能够计算出该字段来自哪个类,查找页码,然后将其传回。
示例代码:
public class PageAttribute : Attribute {
public int Page;
public PageAttribute(int page) {
Page = page;
}
}
public class Example {
public int Id;
[Page(1)]
public string Name;
[Page(1)]
public string Address;
[Page(2)]
public int Calls;
[Page(2)]
public int Emails;
}
public class CheckException : ApplicationException {
public int Page;
public CheckException(string message, int page = 0) : base(message) {
Page = page;
}
}
void Check<T>(Object o, T item, Func<T, bool> validate, string message) {
if (!validate(item)) {
Type type = o.GetType();
// Somehow magically find out which element in object o item comes from
string name = "Calls";
MemberInfo info = type.GetField(name) as MemberInfo;
PageAttribute p = info.GetCustomAttribute(typeof(PageAttribute)) as PageAttribute;
throw new CheckException(message, p == null ? 0 : p.Page);
}
}
void Main() {
Example e = new Example() { Id = 1, Name = "test", Calls = 3 };
Check(e, e.Calls, x => x == 3, "Calls not equal to 3");
Check(e, e.Calls, x => x == 2, "Calls not equal to 2");
}
嗯,基本上没有办法知道特定的“值”来自哪里 - 相同的值可能存在于“很多”地方。 (如果您刚刚获得值 5,您可能不想在内存中查找数字 5 的每次出现。)
但是,这里有一个比反射更好的方法:CallerArgumentExpressionAttribute
这是一个非常简短的例子:
using System.Runtime.CompilerServices;
string x = "Hello";
ShowValue(x.Length);
void ShowValue(
int value,
[CallerArgumentExpression(nameof(value))] string? expression = null)
{
Console.WriteLine($"{expression} = {value}");
}
打印出
x.Length = 5
。