在Winforms脱机客户端中重用ServiceStack验证

时间:2013-05-01 13:10:10

标签: servicestack fluentvalidation

我们有一个使用ServiceStack作为后端的工作网站,相当于一个复杂的数据输入表单。

我的用户已请求表单的“离线编辑器”。要使用脱机程序,用户必须连接到ServiceStack服务,创建表单的空实例,然后我将使用ServiceStack的JSON序列化程序将POCO从服务保存到磁盘。用户可以从那里注销服务并编辑POCO。完成后,他们会重新连接到服务,并发布/放置已编辑的POCO对象。

这一切都很棒。我的问题涉及验证。验证逻辑内置于我的Service.Interface库中,该库不可脱机使用。 winforms程序仅引用POCO库和ServiceStack“公共”库,它们看起来不像ServiceStack.Validation名称空间。

有没有办法可以重新安排我的项目,以便服务和Winforms客户端都可以对POCO运行验证,以便他们可以在离线时进行数据验证?

更新: 我想 - 越来越近了 - 我把所有的Validation类都移到了他们自己的项目中。从我的Winforms项目中,我现在可以手动为POCO类设置验证器,如下所示:

 ServiceStack.FluentValidation.IValidator<SomePOCO> IValidator;
 IValidator = new Tonto.Svc.Validation.SomePOCOValidator();

 ServiceStack.FluentValidation.Results.ValidationResult vr = 
    IValidator.Validate(_rpt);

我可以看到正在设置验证器构造函数并初始化规则,但.Validate方法似乎没有做任何事情。 (对象返回有效,断点到自定义验证器代码永远不会到达那里)。

更新#2

我发现我的验证器代码没有从Winforms运行,因为我的验证器都指定了一个服务栈ApplyTo Put / Post(参见下面的示例代码)。但是,当我删除整个Ruleset子句时,验证会在我的GET服务中发生 - 这是我从未想过的。

有人能想到一种方法来配置验证器规则只在从ServiceStack调用时运行POST / PUT,但是也总是在不在servicestack时运行吗?太近了!

public class SomePOCOValidator : AbstractValidator<SomePOCO>    
    {
        public SomePOCO()
        {
            RuleSet(ApplyTo.Put | ApplyTo.Post, () =>
            {
               (rules)
            });
        }
    }

3 个答案:

答案 0 :(得分:1)

如果你的验证做了一些有趣的事情,那么它可能是“在线”完成的。

也许只允许您的客户在本地保存POCO,直到他们重新上线,此时您将它们发送到您的服务器。任何可以正常处理,正常处理的事务以及任何失败的事务都会被返回供用户编辑(因此您的客户需要一些智能才能使用一组可用的POCO进行编辑)...

如果您不想在客户端上添加任何额外的东西,只需将未通过验证的事务填入服务器上的“needs_corrections”表,然后编写一个管理员类型的屏幕来管理该表

答案 1 :(得分:1)

ServiceStack使用的验证框架名为FluentValidation。它没有WinForms支持。 FluentValidation的创建者Jeremy Skinner在2010年的论坛here上回答了有关此事的问题。

  

就个人而言,我不会将FV与WinForms一起使用 - 我的绝大多数项目都是基于网络的,偶尔会有WPF项目。

     

但是,如果我要这样做,那么我可能不会直接验证控件,而是使用绑定到控件的ViewModel。我使用了一个相当严格的约定,其中控件的名称将与它们绑定的属性的名称相匹配。然后,在验证完成后,我将走控制层次结构以找到名称与验证失败的属性匹配的控件(我不确定如何在WinForms中执行此操作,但在WPF中我使用LogicalTreeHelper。 FindLogicalNode)然后使用ErrorProvider设置相应的错误。

     

杰里米

答案 2 :(得分:1)

我能够找到一个解决方案,允许我在ServiceStack客户端和离线客户端上使用ServiceStack验证库。以下是详细信息。

  1. 将所有AbstractValidators移动到他们自己的项目中:Proj.Svc.Validation。

  2. 删除AbstractValidators中的所有RuleSet。

  3. 从Proj.Svc.Interface和Proj.OfflineWinformsClient项目中参考Proj.Svc.Validation。

  4. 关闭服务中的ValidationFeature()插件。所有验证都必须手动完成。这意味着您的服务类中没有iOC注入验证器。

  5. 无论是从您的服务还是离线客户端验证,都需要手动声明验证器并像这样使用它。

    IValidator验证器=新的  Tonto.Svc.Validation.SomePOCOValidator();  ServiceStack.FluentValidation.Results.ValidationResult vr =  validator.Validate(POCO);

    if(!vr.IsValid)       (抛出异常或以某种方式通知用户);