<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marcel Jurtz</title>
    <description>The latest articles on DEV Community by Marcel Jurtz (@marceljurtz).</description>
    <link>https://dev.to/marceljurtz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F471247%2F79f380fa-940f-4cc7-b13a-2664549db9e3.jpeg</url>
      <title>DEV Community: Marcel Jurtz</title>
      <link>https://dev.to/marceljurtz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marceljurtz"/>
    <language>en</language>
    <item>
      <title>Password-Synchronization with Syncthing</title>
      <dc:creator>Marcel Jurtz</dc:creator>
      <pubDate>Thu, 25 Nov 2021 07:07:57 +0000</pubDate>
      <link>https://dev.to/marceljurtz/password-synchronization-with-syncthing-i7a</link>
      <guid>https://dev.to/marceljurtz/password-synchronization-with-syncthing-i7a</guid>
      <description>&lt;p&gt;If you are reding this, chances are you already use a password manager. I have been doing that for several years now. But I have to admit that my password manager has only run on my phone so far and I have always transferred passwords that I use on my PC by hand. Probably out of sheer laziness. Today, I use this blog post to finally synchronise my password database between any number of devices - and to show you how to do it. The whole thing not only makes dealing with passwords more convenient, but naturally also reduces the inhibition threshold to actually use the applications. This in turn improves the overall security of your accounts.&lt;/p&gt;

&lt;p&gt;Let’s briefly talk about the software: I use Keepass 2 on my PC and Keepass2Android on my mobile phone. This article should work with all applications that use kdbx files. To synchronise the individual files, I use Syncthing, which is available for various platforms. Accordingly, this article is not limited to Windows and Android.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syncthing
&lt;/h2&gt;

&lt;p&gt;Syncthing is an open source application that can be used to synchronise files between devices. The software supports synchronization via local and remote networks. As mentioned earlier, syncthing is available for a lot of different platforms, check out their download-page for details.&lt;/p&gt;

&lt;p&gt;Syncthing is implemented in a peer-to-peer manner, which means that files are synchronised between the devices without a central server. Communication is protected via TLS and Perfect Forward Secrecy.&lt;/p&gt;

&lt;p&gt;Syncthing allocated a unique ID to each device, which is used for address resolution, authentication and authorisation. In order for two devices to communicate with each other, they must know the respective device ID. If the IDs are known to each other, the devices are located using several discovery protocols:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local Discovery&lt;/strong&gt;: Broad- or multicast packets are sent into the local network via the router at intervals of 30 to 60 seconds. Each participating device therefore sends so-called announcement packets at regular intervals and keeps a table with all received announcements. Even in the event of an IP address change within a network, this ensures that the devices know the current IP address of all participants.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Global Discovery&lt;/strong&gt;: If two devices are not in the same network, the global discovery protocol is used. This consists of two steps: First, each device periodically sends an announcement packet to a global discovery server. In the second step, each device sends a query packet with the (known) device ID of its counterpart. If the Syncthing server knows the device ID and the current location or IP address, it responds with the announcement packet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Syncthing automatically starts the synchronization as soon as the location of the participating devices is known. If the devices cannot communicate directly with each other, e.g. due to firewall restrictions, a connection using a relay server is established. Syncthing hereby automatically detects whether a relay server is necessary or not. If you want to use syncthing only in your local network, you can also turn off the (remote) discovery protocols.&lt;/p&gt;

&lt;p&gt;One last thing to mention is that syncthing doesn’t perform a real synchronization. It’s more of a push to other devices after recent changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;To get started, use the download-page to get syncthing for your respective platform(s). I am going to use Android and Windows 10 for this post. For Windows, just unzip the downloaded folder and run the contained executable. You’ll be greeted with a web interface that shows you your installation details and let’s you the configure your setup.&lt;/p&gt;

&lt;p&gt;After installing, you’ll want to connect your devices. To do so, I use my phone to scan the QR-Code on my PC. You can do this both ways, but might have to type in the id if you have no camera available. When you have the devices on the same local network, syncthing can discover devices automatically. On the second device, you will now receive a notification that the first device would like to establish a connection. As soon as you have agreed to this, you can continue with the configuration.&lt;/p&gt;

&lt;p&gt;Synthing works with the concept of directories. A virtual directory is created for each physical folder I want to synchronize between devices. The virtual folders are displayed in the web interface. I start by creating a “Keepass” folder on my Android device and link it to the file path I want to use. I then select my PC to share the folder with it. After saving, I receive a new notification on my PC to include the shared folder. I confirm this too and now configure the physical part of my second device.&lt;/p&gt;

&lt;p&gt;Now the two directories are linked, and as long as both devices are online, Syncthing will keep their contents up to date. It also displays the current status, which is currently “Out of sync”. Shortly afterwards, syncthing starts the first adjustment and my Keepass file already ends up on the PC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Syncthing is a fast, simple and very flexible solution to synchronise files between multiple devices. This also works very well with Keepass databases, but care must be taken here regarding merge conflicts. You should therefore avoid changing data on both databases while both devices are not connected. If necessary, Keepass itself has a merge function that can be used to synchronise database statuses that have drifted apart.&lt;/p&gt;

</description>
      <category>security</category>
      <category>passwords</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Resolve Open Generics with ASP.NET Cores DI-Container</title>
      <dc:creator>Marcel Jurtz</dc:creator>
      <pubDate>Tue, 10 Nov 2020 20:08:33 +0000</pubDate>
      <link>https://dev.to/marceljurtz/resolve-open-generics-with-asp-net-cores-di-container-35cm</link>
      <guid>https://dev.to/marceljurtz/resolve-open-generics-with-asp-net-cores-di-container-35cm</guid>
      <description>&lt;p&gt;ASP .NET Core already has quite a decent di-container built in. However, there are some quirks you might need to be aware of. In one of my applications, I've been using a factory pattern to register my views by using open generics. To be more clear about that: I have an Interface &lt;em&gt;IView&amp;lt;TView&amp;gt;&lt;/em&gt;, and I want to register all of this interfaces implementations.&lt;/p&gt;

&lt;p&gt;As I found out, Microsofts DI-Container currently doesn't support that by default (text me if I'm wrong!), but there's a solution for this problem.&lt;br&gt;
&lt;a href="https://github.com/khellang/Scrutor"&gt;Scrutor&lt;/a&gt; is a package that adds more complex di-features - specifically &lt;em&gt;scanning&lt;/em&gt;. This means that, using this library, you now have the ability to scan through your assemblies and perform registrations based on your findings.&lt;/p&gt;

&lt;p&gt;Now, for my case, this was quite simple: All I had to do was to add the following snippet to my startup-class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromAssembliesOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IView&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AssignableTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IView&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&amp;gt;)).&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsGenericType&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTransientLifetime&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Now, all the implementations of the interface find their way into my di container and I can easily retrieve new instances by utilizing the following factory class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ViewFactory&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IViewFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;_services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ViewFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_services&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CreateViewAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IView&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"View &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TView&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt; not registered"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BuildAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If needed, you could easily extend this by a second type parameter to specify e.g. arguments to pass to the view. Those would then be passed to the &lt;em&gt;CreateViewAsync&lt;/em&gt;-Method, which in turn would forward them to the builders &lt;em&gt;BuildAsync&lt;/em&gt;-Method.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>aspnetcore</category>
      <category>webdev</category>
      <category>dependencyinjection</category>
    </item>
    <item>
      <title>Redirection with .htaccess and PHP</title>
      <dc:creator>Marcel Jurtz</dc:creator>
      <pubDate>Sat, 07 Nov 2020 09:58:03 +0000</pubDate>
      <link>https://dev.to/marceljurtz/redirection-with-htaccess-and-php-dm4</link>
      <guid>https://dev.to/marceljurtz/redirection-with-htaccess-and-php-dm4</guid>
      <description>&lt;p&gt;I’ve been starting a new blog on my domain, for which I wanted to use the &lt;code&gt;blog&lt;/code&gt; subdomain. However, this subdomain was already in use for all my coding-related stuff. So, I decided to move my current blog from &lt;code&gt;/blog&lt;/code&gt; to &lt;code&gt;/coding&lt;/code&gt; and upload my new blog to &lt;code&gt;/blog&lt;/code&gt;. So far, so good. Now I have both of my blogs up and running. &lt;/p&gt;

&lt;p&gt;There’s just one problem: Any incoming traffic to existing posts on my blog would resolve to &lt;em&gt;404s&lt;/em&gt;. In todays post, I’m gonna show you how I resolved that issue.&lt;/p&gt;

&lt;p&gt;First of all, my domain runs on an apache server, so I decided to capture all 404s and redirect them to a specific errorpage. To do this, I needed to add the following statement to my .htaccess file, which is located in the root directory of my webspace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ErrorDocument 404 /notfound.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that it’s important to use a relative path to the php file. If you use an absolute path, you will override the query-string variable in php, which you might need later for the redirect.&lt;/p&gt;

&lt;p&gt;I added the notfound.php file to my blog-directory, from where it will be resolved correctly. The file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php 
  header("Location: https://coding.mjurtz.com" . $_SERVER["REQUEST_URI"], true, 301); 
  die(); 
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All it does is it takes the request uri, and appends it to the new domain, passing a 301 — permanent redirect back to the browser. And that’s it already — My old links are still working and I can work on both blogs separately.&lt;/p&gt;

</description>
      <category>php</category>
      <category>apache</category>
      <category>webdev</category>
      <category>writing</category>
    </item>
    <item>
      <title>FluentValidation in ASP.NET Core</title>
      <dc:creator>Marcel Jurtz</dc:creator>
      <pubDate>Tue, 06 Oct 2020 08:03:18 +0000</pubDate>
      <link>https://dev.to/marceljurtz/fluentvalidation-in-asp-net-core-2jni</link>
      <guid>https://dev.to/marceljurtz/fluentvalidation-in-asp-net-core-2jni</guid>
      <description>&lt;p&gt;Have you been implementing the validation of your ViewModels in ASP.NET (Core) using DataAttributes so far? If so, chances are you've always been dissatisfied because your classes became messy and full of unnecessarily replicated code. Yes? Then today's post is for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  FluentValidation
&lt;/h2&gt;

&lt;p&gt;FluentValidation is a way to define strongly typed validation for classes in the form of a Fluent API. The term &lt;em&gt;fluent&lt;/em&gt; in this case refers to a code structure where a function always return the modified object. This way, you can chain together multiple method calls and produce very readable source code, especially in configurations where it is often used. You may already be familiar with this structure from areas like the ASP.NET setup or LINQ.&lt;/p&gt;

&lt;p&gt;FluentValidation is a popular library for defining validation rules in .NET and is available open source at &lt;a href="https://github.com/FluentValidation"&gt;GitHub&lt;/a&gt;. Oh, and before I jump into the topic: the &lt;a href="https://docs.fluentvalidation.net/en/latest/index.html"&gt;projects documentation&lt;/a&gt; is very good and should be more than sufficient for most of your questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation &amp;amp; Setup
&lt;/h2&gt;

&lt;p&gt;To use FluentValidation, you first need to install corresponding NuGet package &lt;em&gt;FluentValidation.AspNetCore&lt;/em&gt;. After that, the only thing left to do is the configuration in your applications startup class. Just add a call to &lt;em&gt;AddFluentValidation&lt;/em&gt; in the method &lt;em&gt;ConfigureServices&lt;/em&gt; and you're all set! To work correctly with the DI infrastructure, the validators must be defined here afterwards tough:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMvc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFluentValidation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IValidator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ClubMember&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;ClubMemberValidator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you may guess, that would of course get very messy very quickly, so let's check for another way to achieve that. Fortunately, the authors also thought of that and provided another solution: the automatic registration of all validators inside a given assembly. The only two requirements to these is that they are a) marked as public and b) inherit the generic &lt;em&gt;AbstractValidator&lt;/em&gt;-class.&lt;/p&gt;

&lt;p&gt;To do that, you just need to customize the call to &lt;em&gt;AddFluentValidation&lt;/em&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFluentValidation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fv&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterValidatorsFromAssemblyContaining&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will now register all validators, that are contained inside the same assembly as &lt;em&gt;Startup&lt;/em&gt;. Knowing that, we can just jump straight into defining our first validator. In my case, that's the one for the &lt;em&gt;ClubMember&lt;/em&gt;-class, which could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClubMember&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;MemberId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ClubId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Role&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClubMemberValidator&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AbstractValidator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ClubMember&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ClubMemberValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;RuleFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;InclusiveBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are multiple predefined validationrules available in FluentValidation. However, you can of course create your own if you need to support a specific usecase. The validation itself is now set up, and you can check it by calling &lt;em&gt;ModelState.IsValid&lt;/em&gt; inside your controller actions. &lt;/p&gt;

&lt;h2&gt;
  
  
  Pitfalls
&lt;/h2&gt;

&lt;p&gt;There are a few things to be considered when using the library. For example, the regular asp.net validation using DataAttributes is still active and will be applied after the fluentvalidation. It may be helpful to clean up old code to avoid unexpected side effects.&lt;/p&gt;

&lt;p&gt;Another point to keep in mind is that complex objects are not automatically checked further down in their hierarchical structure. If you want to your validator to validate child objects by default, you have to specify this either on the object itself or in the configuration. To achieve this, you can use the property &lt;em&gt;ImplicitlyValidateChildProperties&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;FluentValidation itself is meant to be used for server-side validation. However, it can also be used to provide metadata for validation on the client side. You can find more information on this topic in the project documentation linked above.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;In my opinion, FluentValidation offers a very nice way to define strongly typed validation rules in ASP.NET (Core), without having to mess up your classes. However, there are many more details I haven't covered yet. As I mentioned earlier, the documentation of the project is a very good place to get answers to potential questions and general information, but you also might find posts on various details here in the future.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>aspnet</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How do you organize your personal projects</title>
      <dc:creator>Marcel Jurtz</dc:creator>
      <pubDate>Fri, 18 Sep 2020 11:01:14 +0000</pubDate>
      <link>https://dev.to/marceljurtz/how-do-you-organize-your-personal-projects-236c</link>
      <guid>https://dev.to/marceljurtz/how-do-you-organize-your-personal-projects-236c</guid>
      <description>&lt;p&gt;What software do you guys use to manage your personal projects? Especially for requirements and feature documentation, but also things like time management and so on.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>management</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
