linq - FluentValidation for WP7 - 验证简单类型​​(字符串)

标签 linq windows-phone-7 fluentvalidation

我遇到以下问题,我正在尝试使用 FluentValidation在 Windows Phone 中验证字符串是否是有效的用户名。

我遇到的问题是验证器值的类型为string,必须对其进行测试。在所有示例中,我可以发现它始终是正在测试的对象的属性,如下所示 RuleFor(customer => customer.Surname).NotEmpty();

当我运行此代码时,出现以下错误

代码:

public class UsernameValidator : AbstractValidator<string>
{
    public UsernameValidator()
    {
        RuleFor(username => username).NotNull().NotEmpty().WithMessage("Enter a username");
        RuleFor(username => username).Matches("^[a-zA-Z0-9_]*$").WithMessage("Only letters and numbers");
        RuleFor(username => username).Length(3, 30).WithMessage("Minimum length is 3");
    }
}

错误:

FluentValidation for WP7 can only be used with expressions that reference public properties, ie x => x.SomeProperty
   at FluentValidation.Internal.Extensions.CompilePropertyGetterExpression(LambdaExpression expression, Type delegateType)
   at FluentValidation.Internal.Extensions.Compile[TDelegate](Expression`1 expression)
   at FluentValidation.Internal.PropertyRule`1.Create[TProperty](Expression`1 expression, Func`1 cascadeModeThunk)
   at FluentValidation.AbstractValidator`1.RuleFor[TProperty](Expression`1 expression)
   at WorldChat.ViewModels.Validators.UsernameValidator..ctor()
   at WorldChat.ViewModels.RegisterViewModel.get_ErrorUsername()
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.InternalGetValue(PropertyInfo thisProperty, Object obj, Object[] index, StackCrawlMark& stackMark)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   at System.Windows.CLRPropertyListener.get_Value()
   at System.Windows.PropertyAccessPathStep.ConnectToPropertyInSource(Boolean isSourceCollectionViewCurrentItem)
   at System.Windows.PropertyAccessPathStep.ConnectToProperty()
   at System.Windows.PropertyAccessPathStep.ReConnect(Object newSource)
   at System.Windows.PropertyPathListener.ReConnect(Object source)
   at System.Windows.Data.BindingExpression.SourceAcquired()
   at System.Windows.Data.BindingExpression.System.Windows.IDataContextChangedListener.OnDataContextChanged(Object sender, DataContextChangedEventArgs e)
   at System.Windows.Data.BindingExpression.DataContextChanged(Object sender, DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.OnAncestorDataContextChanged(DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.NotifyDataContextChanged(DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive)
   at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer oldParent, IManagedPeer newParent, Boolean bIsNewParentAlive, Boolean keepReferenceToParent)
   at MS.Internal.FrameworkCallbacks.ManagedPeerTreeUpdate(IntPtr oldParentElement, IntPtr parentElement, IntPtr childElement, Byte bIsParentAlive, Byte bKeepReferenceToParent, Byte bCanCreateParent)
   at MS.Internal.XcpImports.MeasureNative(IntPtr element, Single inWidth, Single inHeight)
   at MS.Internal.XcpImports.UIElement_Measure(UIElement element, Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
   at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
   at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
   at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
   at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
   at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
   at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
   at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
   at Microsoft.Phone.Controls.PhoneApplicationFrame.MeasureOverride(Size availableSize)
   at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)

最佳答案

我找到了一个解决方法,它需要你有一个额外的字符串包装类。

ValidationString.cs

public class ValidationString
{
    public string value { get; set; }

    public ValidationString(string value)
    {
        this.value = value;
    }
}

在用户名验证器类中,我添加了一个静态方法 IsUsername

public class UsernameValidator : AbstractValidator<ValidationString>
{
    public UsernameValidator()
    {
        RuleFor(username => username.value).NotNull().NotEmpty().WithMessage("Enter a username");
        RuleFor(username => username.value).Matches("^[a-zA-Z0-9_]*$").WithMessage("Only letters and numbers");
        RuleFor(username => username.value).Length(3, 30).WithMessage("Minimum length is 3");
    }

    internal static bool IsUsername(string value)
    {
        return new UsernameValidator().Validate(new ValidationString(value)).IsValid;
    }
}

现在我既可以在字符串上使用这个 UsernameValidator,也可以使用另一个验证器,例如注册验证器

public class RegisterValidator : AbstractValidator<User>
{
    public RegisterValidator()
    {
        RuleFor(user => user.Username).Must(UsernameValidator.IsUsername);
        // some more rules
    }
}

如果您不想在其他验证类中使用 UsernameValidator,则可以忽略 IsUsername 方法。

关于linq - FluentValidation for WP7 - 验证简单类型​​(字符串),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10665352/

相关文章:

c# - 使用 LINQ 从 2 个列表中返回列表

c# - 将 foreach 与 LINQ to Entities 一起使用时是否需要 ToList

c# - 比较两个列表 - 如果一个列表中的任何对象属性已更改或列表中添加了新对象,则返回该对象

c# - 调用 try 中的方法时未捕获异常?

windows-phone-7 - WebRequestExtensions.GetCurrentNetworkInterface 抛出 InvalidOperationException

silverlight - Windows Phone 7 - 使用应用程序栏和 Prism(或 MVVM)

c# - 如何在一个规则中添加多个 IF 条件?

c# - FluentValidation:检查两个字段之一是否为空

c# - 为什么一个循环在内存和性能方面比其他循环表现更好?

c# - 是否可以在 ASP.NET Core 中组合 [FromRoute] 和 [FromBody]?