{"id":13327233,"url":"https://github.com/jybbang/ReactiveUI-FluentValidation","last_synced_at":"2025-03-11T02:32:32.675Z","repository":{"id":133231612,"uuid":"180660426","full_name":"jybbang/ReactiveUI-FluentValidation","owner":"jybbang","description":"It is a small library for ReactiveUI to support XAML Binding validation using *FluentValidation","archived":false,"fork":false,"pushed_at":"2019-04-11T05:15:12.000Z","size":42,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-04T18:44:48.209Z","etag":null,"topics":["fluentvalidation","mvvm","reactiveui","validation"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jybbang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-10T20:39:35.000Z","updated_at":"2022-01-03T22:16:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"62b48646-feb5-4f36-8310-ce1197e379c1","html_url":"https://github.com/jybbang/ReactiveUI-FluentValidation","commit_stats":{"total_commits":9,"total_committers":1,"mean_commits":9.0,"dds":0.0,"last_synced_commit":"fa1cd39e1459c929baa82728bfe418b3f7627731"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jybbang%2FReactiveUI-FluentValidation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jybbang%2FReactiveUI-FluentValidation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jybbang%2FReactiveUI-FluentValidation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jybbang%2FReactiveUI-FluentValidation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jybbang","download_url":"https://codeload.github.com/jybbang/ReactiveUI-FluentValidation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242959544,"owners_count":20212999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fluentvalidation","mvvm","reactiveui","validation"],"created_at":"2024-07-29T18:53:51.624Z","updated_at":"2025-03-11T02:32:32.667Z","avatar_url":"https://github.com/jybbang.png","language":"C#","readme":"# ReactiveValidationObject\n\nIt is a small library for [ReactiveUI](https://reactiveui.net/) to support XAML Binding validation using [*FluentValidation](https://fluentvalidation.net/)\n\n- ReactiveUI is one of the most powerful framworks for MVVM.\n- It has a original validation library ([ReactiveUI.Validation](https://reactiveui.net/docs/handbook/user-input-validation/)), It is very simple to use and well functioned.\n- But It does not support `INotifyDataErrorInfo` interface for XAML binding engine to display validation erros in your view.\n- So, I wrap the base ViewModel (ReactiveObject) with a popular validation library [*FluentValidation](https://fluentvalidation.net/)\n- To XAML binding, we should initialize the DataContext of View. Andthen we use some traditional XAML markup bindings (only some properties that we want to validate).\n\n\u003e CAUTION \n\u003e\n\u003e If you HATE to use XAML markup bindings. It's NOT for you.\n\n## Get Started\n\n### 1. Installation\n\nReactiveValidationObject can be installed using the Nuget package manager or the dotnet CLI:\n\n    Install-Package ReactiveUI-FluentValidation\n\nOr you can just copy the `ReactiveValidationObject.cs` into your project.\n\nAfter that you should get [*FluentValidation](https://fluentvalidation.net/) pakage.\n\n### 2. Use case\n\nI use a popular validation library *FluentValidation. Therefore you can learn more validation rules HERE - [https://fluentvalidation.net/](https://fluentvalidation.net/)\n\nSo this thime. I just show a how to use my library only.\n\nThis is our first ReactiveObject ViewModel class:\n```csharp\n    using ReactiveUI;\n    \n    public class AppViewModel : ReactiveObject\n    {\n      private string fullname;\n      private string surname;\n      private string forename;\n      public string Fullname\n      {\n        get =\u003e fullname;\n        set\n        {\n          this.RaiseAndSetIfChanged(ref fullname, value);\n        }\n      }\n      public string Surname\n      {\n        get =\u003e surname;\n        set\n        {\n          this.RaiseAndSetIfChanged(ref surname, value);\n        }\n      }\n      public string Forename\n      {\n        get =\u003e forename;\n        set\n        {\n          this.RaiseAndSetIfChanged(ref forename, value);\n        }\n      }\n    \n      public ReactiveCommand\u003cUnit, Unit\u003e SomeAction { get; }\n    \n      public AppViewModel()\n      {\n        var isValid = this.WhenAnyValue(vm =\u003e vm.Surname, vm =\u003e vm.Forename)\n          .Select(x =\u003e !String.IsNullOrWhiteSpace(x.Item1) \n    \t\t\t\u0026\u0026 !String.IsNullOrWhiteSpace(x.Item2));\n    \n        SomeAction = ReactiveCommand.Create(() =\u003e\n        {\n          Fullname = $\"{Forename} {Surname}\";\n        }, isValid);\n      }\n    }\n```\nAs you can see it is work very well.\n\nYou can not click the button if suname and forename are empty:\n\n![](Images/Untitled-2d68fc39-3088-4d08-b289-91b1771b8d81.png)\n\nHowever If you wanna display validation erros in your view.\n\nFollow next step.\n\n### 3. Create your validator\n\nYou would define a set of validation rules for our first class by inheriting from `AbstractValidator\u003cT\u003e` :\n```csharp\n    using FluentValidation;\n    \n    public class AppViewModelValidator : AbstractValidator\u003cAppViewModel\u003e\n    {\n      public AppViewModelValidator()\n      {\n        RuleFor(vm =\u003e vm.Surname).NotEmpty();\n        RuleFor(vm =\u003e vm.Forename).NotEmpty();\n      }\n    }\n```\n### 4. Define your ReactiveValidationObject class\n\nFirst of all we should change base class.\n\nBefore: \n```csharp\n    public class AppViewModel : ReactiveObject\n```\nAfter:\n```csharp\n    using ReactiveUI.FluentValidation;\n    public class AppViewModel : ReactiveValidationObject\n```\nAnd then you have to set an argument `AbstractValidator\u003cAppViewModel\u003e`  to the base class constructor:\n```csharp\n    public AppViewModel() : base(new AppViewModelValidator())\n    {\n      SomeAction = ReactiveCommand.Create(() =\u003e\n      {\n          Fullname = $\"{Forename} {Surname}\";\n      }, isValid);\n    }\n```\nYou now don't need define `IObservable\u003cbool\u003e isValid`  any more. The validation result `isValid` will be set if validations are completed.\n\nFinally, You should raise an event related property `this.RaiseValidation(nameof(Property))`:\n```csharp\n    public string Surname\n    {\n      get =\u003e surname;\n      set\n      {\n          this.RaiseAndSetIfChanged(ref surname, value);\n          this.RaiseValidation(nameof(Surname));\n      }\n    }\n    public string Forename\n    {\n      get =\u003e forename;\n      set\n      {\n          this.RaiseAndSetIfChanged(ref forename, value);\n          this.RaiseValidation(nameof(Forename));\n      }\n    }\n```\nSo, This is our first ReactiveValidationObject ViewModel class:\n```csharp\n    using ReactiveUI;\n    using ReactiveUI.FluentValidation;\n    using FluentValidation;\n    \n    public class AppViewModelValidator : AbstractValidator\u003cAppViewModel\u003e\n    {\n      public AppViewModelValidator()\n      {\n        RuleFor(vm =\u003e vm.Surname).NotEmpty();\n        RuleFor(vm =\u003e vm.Forename).NotEmpty();\n      }\n    }\n    \n    public class AppViewModel : ReactiveValidationObject\n    {\n    \tprivate string fullname;\n    \tprivate string surname;\n    \tprivate string forename;\n    \t\n    \tpublic string Fullname\n    \t{\n    \t    get =\u003e fullname;\n    \t    set\n    \t    {\n    \t        this.RaiseAndSetIfChanged(ref fullname, value);\n    \t    }\n    \t}\n    \tpublic string Surname\n    \t{\n    \t    get =\u003e surname;\n    \t    set\n    \t    {\n    \t        this.RaiseAndSetIfChanged(ref surname, value);\n    \t        this.RaiseValidation(nameof(Surname));\n    \t    }\n    \t}\n    \tpublic string Forename\n    \t{\n    \t    get =\u003e forename;\n    \t    set\n    \t    {\n    \t        this.RaiseAndSetIfChanged(ref forename, value);\n    \t        this.RaiseValidation(nameof(Forename));\n    \t    }\n    \t}\n    \t\n    \tpublic ReactiveCommand\u003cUnit, Unit\u003e SomeAction { get; }\n    \t\n    \tpublic AppViewModel() : base(new AppViewModelValidator())\n    \t{\n    \t    SomeAction = ReactiveCommand.Create(() =\u003e\n    \t    {\n    \t        Fullname = $\"{Forename} {Surname}\";\n    \t    }, isValid);\n    \t}\n    }\n```\n### 5. Modify your View\n\nAs I mentioned our goal is to display errors in your view. To use XAML binding engine set DataContext:\n```csharp\n    DataContext = ViewModel;\n```\nAnd then you should bind properties in xaml:\n```xml\n    \u003cTextBox x:Name=\"TextboxSurname\"         \n             Text=\"{Binding Surname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" /\u003e\n    \n    \u003cTextBox x:Name=\"TextboxForename\"         \n             Text=\"{Binding Forename, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" /\u003e\n```\nNow you can see errors in your view like this:\n\n![](Images/Untitled-380e4205-1068-4782-bb47-d9287bac25fa.png)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjybbang%2FReactiveUI-FluentValidation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjybbang%2FReactiveUI-FluentValidation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjybbang%2FReactiveUI-FluentValidation/lists"}