首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Silverlight应用程序的服务器端验证

Silverlight应用程序的服务器端验证
EN

Stack Overflow用户
提问于 2011-09-07 22:31:33
回答 1查看 1.1K关注 0票数 0

我正要实现IDataErrorInfo,这时我发现INotifyDataErrorInfo将用于异步验证。当进一步挖掘时,我注意到使用这些接口的示例都在ViewModel上。我需要对模型进行验证,并且需要将错误与模型一起存储,以便持久化。我有一个包含许多实体的大图。此图需要传递回服务器以进行复杂的验证。我不确定我现在应该使用什么方法。

我是否简单地将我的接口实现移动到模型中?

我看到的另一个例子有一个单独的验证服务。在我的例子中,我的验证规则很复杂,我正在考虑使用Windows工作流及其规则引擎来提高验证规则的可维护性。

我是否需要单独的验证服务?

验证完成后,必须将图形传递回客户端。然后需要显示任何错误/警告。

我是否应该在模型中实现INotifyDataErrors,并在验证返回到客户端时引发事件,以便(通过ViewModel)将错误发布到视图?

事实证明,我在引用类库中包含INotifyDataErrors的程序集时遇到了问题。它会在共享这些类的程序集中产生冲突。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-08 08:11:20

当您有大型项目时,RIA可能不是一个好主意,例如具有不同层(服务、应用程序、域、基础设施)的应用程序。

不久前,我不得不在Silverlight应用程序中使用复杂的规则来实现验证。我使用的是Entity Framework生成的自我跟踪实体。我的一个需求就是重新调用所有的验证代码。

首先,我尝试使用EntLib验证块,并在客户端和服务器端使用相同的代码。这种方法不起作用,因为SL和.NET4.0使用不同版本的DataAnnotations程序集,因此会遇到一些问题。

最后,我在服务器上编写了某种验证服务,用于返回实体的错误。如下所示:

代码语言:javascript
复制
interface IValidate
{
    IEnumerable<string> Validate(Entity entity); 
}

然后在客户端使ViewModels实现INotifyDataErrorInfo (此接口支持异步验证),这样您就可以使用服务验证实体并将错误保存在ViewModel上。

代码语言:javascript
复制
class SomeViewModel : INotifyDataErrorInfo
{
    public Entity Entity { get; set; }

    public void Validate()
    {
        this.ClearErrors();
        // this method make the service calls
        var service = -- service instance --;
        var errors = -- get errors from service --;
        foreach (string error in errors)
            this.AddTopLevelError(error);
    }

    {...}
}

这样,所有的验证逻辑都依赖于服务器,它可以随时更改而不会影响客户端,因为所有实体在添加到DataBase (如果您正在使用它)之前都要通过此服务。

该服务还可以返回错误和与错误相关的属性,这样您就可以与Silverlight进行更丰富的交互。因此,服务可以是:

代码语言:javascript
复制
interface IValidate
{
    IEnumerable<PropertyError> Validate(Entity entity); 
}

class PropertyError
{
    public string PropertyName { get; }
    public IEnumerable<string> Errors { get; }
}

在这里,您可以注意到,服务器上的验证规则可能会发生变化,而这个逻辑是如何实现的并不重要。所有这些都运行良好,并满足您的请求,问题是Silverlight要求被验证的对象包含所有有错误的属性。

在使用数据库时,这不是常见的场景,例如,您可能会遇到这种情况(这是一个简单的模型)

这个模型是使用Entity Framework4.1完成的

因为如果您有一个用户实例,并且想要访问电子邮件属性,则必须输入: user_instance.Person.Email。所以Email属性不在用户类型中,而是这个解决方案的问题所在,因为您可能也想验证EMails。

这不是这样的,当你有一个带有实体(类似于上面)的ViewModel (实现INotifyDataErrorInfo),并且想要验证实体(本例中是用户)时,你只需要在属性Entity.Person.Email中添加一个错误。

但世界并不完美,所以我找到的解决方案是将每个属性复制到ViewModel上进行验证,如下所示:

代码语言:javascript
复制
class SomeViewModel : INotifyDataErrorInfo
{
    public User Entity { get; set; }

    public string Name { get { return Entity.UserName; } set {...} }        
    public string Email { get { return Entity.Person.Email; } set {...} }

    {...}
}

通过这种方式,您可以将控件绑定到ViewModels属性,而不是entities属性,但是使用更改通知会有点困难。

您可能还想检查:this工具包。它解决了这个问题,为你的实体定义了一个wapper,并使用DynamicObject模拟一个对象,该对象具有包装的对象的所有属性。这在处理大量数据时有点慢,但大大简化了工作。

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7335642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档