有两种通用类型来实现检查逻辑:
共享库。示例是“RIA 服务 + Silverlight”。
优点:易于实施。
缺点:没有互操作性(仅限 .NET);每次库更改都需要客户端更新。
在服务部分实现通用方法验证。
优点:互操作性,如果检查逻辑发生变化,无需客户端更新
缺点:可能很复杂,因为它只在你身上
如果我们使用 SOA,最好使用第二选择,前提是您不是仅在您的公司中使用应用程序,而 .NET 无处不在。
例子
让我们考虑一个常见的例子。我们有一个 windows/wpf 表单。并且有两个字段:字符串类型的“姓”,int类型的“年龄”;和一个“保存”按钮。我们需要在客户端进行一些检查
1) 对于某些用户,“保存”按钮被禁用;
2)姓氏不能为空,最大长度为256;
3)年龄不能小于0;
调用保存方法是
void Save(string surname, int age);
在服务中创建第二个方法,该方法返回带有验证信息的 PermissonAnswerDTO 对象类型;
PermissonAnswerDTO SaveValidate(string surname, int age);
和主要验证方法
// If arguments are wrong
[FaultContract(typeof(NotSupportedException))]
// If the user have permisson to invoke this method
[FaultContract(typeof(CustomNotEnoughPermission))]
PermissonAnswerDTO Validate(string methodName, object[] methodParams);
验证。
Validate("SaveValidate", null)
在窗口加载时调用。如果抛出 CustomNotEnoughPermission 类型的异常,那么我们会阻止“保存”按钮。
如果用户可以保存,则调用用户的数据Validate("SaveValidate", object[2]{"Surname", "-60"};
。-60 无效,因此我们得到 PermissonAnswerDTO 类型的答案对象,其中包含以下信息:
ParameterName: "age",
ExceptionMessage: "age cannot be less then null".
我们可以优雅地向用户展示这些信息。
我对此的想法是,有一天微软会实现这一点,并像往常一样调用新技术。大多数情况下,微软的技术并没有宣传的那么具有革命性。例如 Windows Identity Foundation 和 Reactive Extensions。
完整示例
[DataContract]
public class ParameterExceptionExplanaitonDTO
{
[DataMember]
public string ParameterName;
[DataMember]
public string ExceptionMessage;
}
[DataContract]
public class PermissonAnswerDTO
{
[DataMember]
public bool IsValid;
[DataMember]
public ParameterExceptionExplanaitonDTO[] ParameterExceptions;
}
public class Service1 : WcfContracts.IService1
{
// If arguments are wrong
[FaultContract(typeof(NotSupportedException))]
// If the user have permisson to invoke this method
[FaultContract(typeof(CustomNotEnoughPermission))]
public PermissonAnswerDTO Validate(string methodName, object[] methodParams)
{
//1) Using Reflection find the method with name = <methodName + Validate>
//2) Using Reflection cast each object in "object[] methodParams" to the required type
//3) Invoke method
}
private PermissonAnswerDTO GetUserNameValidate(int id)
{
//logic to check param
}
public string GetUserName(int id)
{
// if the user calls method we need validate parameter
GetUserNameValidate(id);
//some logic to retreive name
}
}