<?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>Forem: RzR</title>
    <description>The latest articles on Forem by RzR (@iamrzr).</description>
    <link>https://forem.com/iamrzr</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%2F3474814%2Fac5966b7-3de4-4d10-8c8a-b2433d3fd38a.jpg</url>
      <title>Forem: RzR</title>
      <link>https://forem.com/iamrzr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/iamrzr"/>
    <language>en</language>
    <item>
      <title>Handle data set pagination with `PagedListResult`</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Thu, 05 Feb 2026 19:25:11 +0000</pubDate>
      <link>https://forem.com/iamrzr/handle-data-set-pagination-with-pagedlistresult-4hc2</link>
      <guid>https://forem.com/iamrzr/handle-data-set-pagination-with-pagedlistresult-4hc2</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PagedListResult&lt;/strong&gt; is a focused .NET library that standardizes server‑side pagination, sorting, searching, and filtering into a clear &lt;em&gt;request → execution → result&lt;/em&gt; pipeline. The repository is intentionally opinionated: instead of exposing many small helpers, it defines strong contracts (request and result models) and a set of query extensions that apply those contracts to &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt; sources.&lt;/p&gt;

&lt;p&gt;The primary goal of the project is to eliminate repetitive pagination logic in APIs and application services, while keeping the query behavior explicit, testable, and extensible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design Philosophy
&lt;/h2&gt;

&lt;p&gt;The repository follows several consistent design principles that are visible across all projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Contract‑first pagination&lt;/strong&gt; – Pagination is driven by a request model rather than ad‑hoc parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queryable‑centric execution&lt;/strong&gt; – All operations are applied to &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt;, allowing deferred execution and provider‑level optimizations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separation of concerns&lt;/strong&gt; – Request/response models, query logic, and common helpers are separated into distinct projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API‑oriented output&lt;/strong&gt; – The result model includes metadata required by front‑end grids and consumers, not just the data subset.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Repository Structure
&lt;/h2&gt;

&lt;p&gt;The solution is split into multiple projects, each with a strictly scoped responsibility. This separation is not cosmetic; it directly reflects how pagination concerns are decomposed and enforced across the library.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. PagedListResult.DataModels (Core Contract Layer)
&lt;/h3&gt;

&lt;p&gt;This project is the &lt;strong&gt;foundation&lt;/strong&gt; of the entire solution. Every other project depends on it, and it intentionally contains &lt;em&gt;no query execution logic&lt;/em&gt;. Its sole purpose is to define &lt;strong&gt;stable, serializable contracts&lt;/strong&gt; that describe &lt;em&gt;what&lt;/em&gt; the consumer wants and &lt;em&gt;what&lt;/em&gt; the system returns.&lt;/p&gt;

&lt;h4&gt;
  
  
  Architectural Role
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Acts as a &lt;strong&gt;boundary layer&lt;/strong&gt; between clients (API/UI) and query execution&lt;/li&gt;
&lt;li&gt;Ensures pagination behavior is explicit and versionable&lt;/li&gt;
&lt;li&gt;Makes pagination requests portable across services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design allows the same request model to be reused in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Core controllers&lt;/li&gt;
&lt;li&gt;Application services&lt;/li&gt;
&lt;li&gt;Background jobs&lt;/li&gt;
&lt;li&gt;Integration tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Key Types and Responsibilities
&lt;/h4&gt;

&lt;h5&gt;
  
  
  PagedRequest
&lt;/h5&gt;

&lt;p&gt;The &lt;code&gt;PagedRequest&lt;/code&gt; type is the central aggregation root of pagination input. Rather than scattering parameters, it consolidates all query intent into a single object.&lt;/p&gt;

&lt;p&gt;Core responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page index normalization&lt;/li&gt;
&lt;li&gt;Page size definition&lt;/li&gt;
&lt;li&gt;Optional ordering definition&lt;/li&gt;
&lt;li&gt;Optional search definition&lt;/li&gt;
&lt;li&gt;Optional filter collection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model is intentionally permissive: most properties are optional, allowing minimal or advanced usage with the same contract.&lt;/p&gt;

&lt;h5&gt;
  
  
  Paging Semantics
&lt;/h5&gt;

&lt;p&gt;Paging is expressed in &lt;strong&gt;logical terms&lt;/strong&gt;, not execution terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Page&lt;/code&gt; represents the requested page index&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PageSize&lt;/code&gt; represents the logical size of the page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No assumptions are made about storage or transport. Execution layers decide how to translate these into &lt;code&gt;Skip&lt;/code&gt; / &lt;code&gt;Take&lt;/code&gt; operations.&lt;/p&gt;

&lt;h5&gt;
  
  
  OrderOptions
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;OrderOptions&lt;/code&gt; defines ordering intent without binding to LINQ or database specifics.&lt;/p&gt;

&lt;p&gt;Key characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Property name is expressed as a string&lt;/li&gt;
&lt;li&gt;Direction is represented as a semantic enum or value&lt;/li&gt;
&lt;li&gt;Designed to be validated before execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows clients to control ordering while keeping execution safe and predictable.&lt;/p&gt;

&lt;h5&gt;
  
  
  SearchOptions
&lt;/h5&gt;

&lt;p&gt;Search is modeled explicitly rather than as a generic filter.&lt;/p&gt;

&lt;p&gt;Responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store the search term&lt;/li&gt;
&lt;li&gt;Define whether the search applies to all text fields&lt;/li&gt;
&lt;li&gt;Enable consistent interpretation of search intent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By isolating search into its own model, the library avoids overloading filters with responsibilities they are not suited for.&lt;/p&gt;

&lt;h5&gt;
  
  
  Filter Models
&lt;/h5&gt;

&lt;p&gt;Filtering is expressed through a structured hierarchy rather than ad-hoc predicates.&lt;/p&gt;

&lt;p&gt;Typical filter elements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Target property name&lt;/li&gt;
&lt;li&gt;Condition operator (equality, range, containment, etc.)&lt;/li&gt;
&lt;li&gt;One or more comparison values&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AND&lt;/code&gt; or &lt;code&gt;OR&lt;/code&gt; comparation apply between values/filters&lt;/li&gt;
&lt;li&gt;Dependence between filters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This structure enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validation before execution&lt;/li&gt;
&lt;li&gt;Deterministic expression generation&lt;/li&gt;
&lt;li&gt;Consistent behavior across endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  PagedResult
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;PagedResult&amp;lt;T&amp;gt;&lt;/code&gt; is the authoritative output contract of the library.&lt;/p&gt;

&lt;p&gt;It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The paged response collection&lt;/li&gt;
&lt;li&gt;Paging metadata (page, page size, page count)&lt;/li&gt;
&lt;li&gt;Total row count&lt;/li&gt;
&lt;li&gt;Execution diagnostics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Importantly, the result is &lt;strong&gt;self-describing&lt;/strong&gt;: consumers do not need to recompute or infer paging state.&lt;/p&gt;

&lt;h5&gt;
  
  
  ExecutionDetails
&lt;/h5&gt;

&lt;p&gt;Execution diagnostics are modeled explicitly rather than logged implicitly.&lt;/p&gt;

&lt;p&gt;This enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance analysis at the API boundary&lt;/li&gt;
&lt;li&gt;Transparent reporting to consumers&lt;/li&gt;
&lt;li&gt;Easier debugging in distributed systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. PagedListResult.Common (Query Interpretation Layer)
&lt;/h3&gt;

&lt;p&gt;This project translates &lt;em&gt;intent&lt;/em&gt; into &lt;em&gt;executable logic&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Its responsibility is to convert DataModel contracts into expression trees that can be applied to &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt; without knowing the underlying provider.&lt;/p&gt;

&lt;h4&gt;
  
  
  Core Responsibilities
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Validate property access at runtime&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build expression trees for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filters&lt;/li&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Ordering&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Combine multiple expressions deterministically&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Expression-Driven Design
&lt;/h4&gt;

&lt;p&gt;Rather than building queries imperatively, the library constructs expression trees. This allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provider-level optimization&lt;/li&gt;
&lt;li&gt;Deferred execution&lt;/li&gt;
&lt;li&gt;Compatibility with LINQ providers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each query concern (filter, search, order) is handled independently and then composed.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. PagedListResult (Execution &amp;amp; Integration Layer)
&lt;/h3&gt;

&lt;p&gt;This project is the &lt;strong&gt;behavioral core&lt;/strong&gt; of the solution. While &lt;code&gt;DataModels&lt;/code&gt; defines &lt;em&gt;what&lt;/em&gt; should happen and &lt;code&gt;Common&lt;/code&gt; defines &lt;em&gt;how intent is translated&lt;/em&gt;, &lt;strong&gt;PagedListResult&lt;/strong&gt; defines &lt;em&gt;when and in what order&lt;/em&gt; everything is executed.&lt;/p&gt;

&lt;p&gt;It is also the only project that consumers typically reference directly.&lt;/p&gt;




&lt;h4&gt;
  
  
  Public API Surface
&lt;/h4&gt;

&lt;p&gt;The project exposes a minimal but powerful public surface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extension methods over &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Strongly typed pagination execution returning &lt;code&gt;PagedResult&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design deliberately avoids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base repository abstractions&lt;/li&gt;
&lt;li&gt;Framework‑specific dependencies at the API boundary&lt;/li&gt;
&lt;li&gt;Hidden execution side effects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consumers remain in full control of when queries are materialized.&lt;/p&gt;




&lt;h4&gt;
  
  
  Extension Method Architecture
&lt;/h4&gt;

&lt;p&gt;Pagination is implemented entirely via &lt;strong&gt;extension methods&lt;/strong&gt; rather than services or static helpers.&lt;/p&gt;

&lt;p&gt;Key implications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pagination composes naturally with LINQ&lt;/li&gt;
&lt;li&gt;No dependency injection is required&lt;/li&gt;
&lt;li&gt;Domain entities remain untouched&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical execution entry point:&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;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPagedAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pagedRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPagedWithFiltersAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pagedRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPagedWithMainFiltersAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pagedRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Internally, this single call coordinates the entire pipeline.&lt;/p&gt;




&lt;h4&gt;
  
  
  Execution Orchestration Responsibilities
&lt;/h4&gt;

&lt;p&gt;The PagedListResult project does &lt;em&gt;not&lt;/em&gt; build expressions itself. Instead, it orchestrates execution by delegating responsibilities in a strict order.&lt;/p&gt;

&lt;p&gt;Its responsibilities include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Guard‑clause validation of the request&lt;/li&gt;
&lt;li&gt;Delegation of search, filter, and order logic&lt;/li&gt;
&lt;li&gt;Pagination window calculation&lt;/li&gt;
&lt;li&gt;Execution diagnostics capture&lt;/li&gt;
&lt;li&gt;Final result assembly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This ensures that query semantics remain centralized and predictable.&lt;/p&gt;




&lt;h4&gt;
  
  
  Ordering Strategy Enforcement
&lt;/h4&gt;

&lt;p&gt;One subtle but critical responsibility of this layer is &lt;strong&gt;ordering enforcement&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Stable pagination requires deterministic ordering. The execution layer ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explicit ordering is applied when provided&lt;/li&gt;
&lt;li&gt;A fallback strategy exists when ordering is missing&lt;/li&gt;
&lt;li&gt;Ordering is applied &lt;em&gt;before&lt;/em&gt; pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this enforcement, page boundaries could shift between executions.&lt;/p&gt;




&lt;h4&gt;
  
  
  Row Count Evaluation
&lt;/h4&gt;

&lt;p&gt;Row count is evaluated &lt;strong&gt;before pagination is applied&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This design decision ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accurate &lt;code&gt;RowCount&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Correct &lt;code&gt;PageCount&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Independence from page size or index&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The execution layer explicitly separates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Total dataset size&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Paged window size&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This distinction is critical for client‑side pagination controls.&lt;/p&gt;




&lt;h4&gt;
  
  
  Pagination Window Calculation
&lt;/h4&gt;

&lt;p&gt;The execution layer translates logical paging intent into execution behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculates skip offset from page index and page size&lt;/li&gt;
&lt;li&gt;Applies &lt;code&gt;Skip&lt;/code&gt; and &lt;code&gt;Take&lt;/code&gt; only after all query conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guarantees that pagination is applied to the &lt;em&gt;final filtered and ordered dataset&lt;/em&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  ExecutionDetails Population
&lt;/h4&gt;

&lt;p&gt;Execution diagnostics are captured as part of the core workflow.&lt;/p&gt;

&lt;p&gt;Typical captured details include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start and end timestamps&lt;/li&gt;
&lt;li&gt;Total execution duration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By embedding diagnostics in the result rather than logging implicitly, the library enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transparent performance reporting&lt;/li&gt;
&lt;li&gt;API‑level observability&lt;/li&gt;
&lt;li&gt;Easier troubleshooting without log access&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Result Assembly
&lt;/h4&gt;

&lt;p&gt;The final step is deterministic result construction.&lt;/p&gt;

&lt;p&gt;The execution layer assembles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Materialized response data&lt;/li&gt;
&lt;li&gt;Paging metadata&lt;/li&gt;
&lt;li&gt;Execution diagnostics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting &lt;code&gt;PagedResult&amp;lt;T&amp;gt;&lt;/code&gt; is immediately consumable by API clients without additional transformation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Detailed Pagination Execution Pipeline
&lt;/h2&gt;

&lt;p&gt;The execution pipeline is deterministic and ordered to avoid ambiguity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Request Validation&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Page boundaries&lt;/li&gt;
&lt;li&gt;Page size constraints&lt;/li&gt;
&lt;li&gt;Property existence for filters and ordering&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Search Application&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Text-based expressions generated first&lt;/li&gt;
&lt;li&gt;Applied before filters to reduce dataset early&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Filter Application&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Structured conditions translated into expressions&lt;/li&gt;
&lt;li&gt;Combined using logical &lt;code&gt;AND&lt;/code&gt; or &lt;code&gt;OR&lt;/code&gt; semantics&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ordering Application&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Explicit ordering or fallback strategy&lt;/li&gt;
&lt;li&gt;Ensures stable pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Row Count Evaluation&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Executed before paging&lt;/li&gt;
&lt;li&gt;Represents total matching dataset size&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Pagination Application&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Skip&lt;/code&gt; and &lt;code&gt;Take&lt;/code&gt; applied last&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Result Materialization&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Execution timing captured&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PagedResult&amp;lt;T&amp;gt;&lt;/code&gt; populated&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Structured Result Serialization: JSON and XML Support
&lt;/h2&gt;

&lt;p&gt;One important capability of the &lt;strong&gt;PagedListResult&lt;/strong&gt; project that deserves explicit attention is its built‑in support for &lt;strong&gt;result serialization targeting JSON and XML consumers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This functionality is not an afterthought; it is reflected directly in the source code and aligns with the library’s API‑first design.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Serialization Is a First‑Class Concern
&lt;/h3&gt;

&lt;p&gt;The library assumes that paged results are most often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Returned from REST APIs&lt;/li&gt;
&lt;li&gt;Consumed by heterogeneous clients&lt;/li&gt;
&lt;li&gt;Persisted or logged in structured formats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For that reason, the result model (&lt;code&gt;PagedResult&amp;lt;T&amp;gt;&lt;/code&gt;) and its related metadata types are designed to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully serializable&lt;/li&gt;
&lt;li&gt;Deterministic in structure&lt;/li&gt;
&lt;li&gt;Independent of execution context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the result suitable for both &lt;strong&gt;JSON‑based APIs&lt;/strong&gt; and &lt;strong&gt;XML‑based integrations&lt;/strong&gt; without custom mapping layers.&lt;/p&gt;




&lt;h3&gt;
  
  
  JSON Result Shape
&lt;/h3&gt;

&lt;p&gt;From the source perspective, the JSON representation is a &lt;strong&gt;direct projection&lt;/strong&gt; of the result contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paging metadata is exposed as top‑level fields&lt;/li&gt;
&lt;li&gt;Execution details are explicitly represented&lt;/li&gt;
&lt;li&gt;The response collection is serialized as a structured array&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the library avoids custom converters or runtime mutation, the JSON output remains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stable across executions&lt;/li&gt;
&lt;li&gt;Predictable for front‑end grids&lt;/li&gt;
&lt;li&gt;Easy to version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is particularly important for client‑side pagination components that depend on fixed property names.&lt;/p&gt;




&lt;h3&gt;
  
  
  XML Result Support
&lt;/h3&gt;

&lt;p&gt;The repository also supports &lt;strong&gt;XML‑friendly result structures&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Key characteristics visible in the source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Result and metadata models are designed with XML serialization compatibility in mind&lt;/li&gt;
&lt;li&gt;No reliance on JSON‑only attributes or behaviors&lt;/li&gt;
&lt;li&gt;Clean hierarchical structure suitable for XML consumers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This enables scenarios such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Legacy system integrations&lt;/li&gt;
&lt;li&gt;SOAP‑adjacent services&lt;/li&gt;
&lt;li&gt;Inter‑service communication where XML is still required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same &lt;code&gt;PagedResult&amp;lt;T&amp;gt;&lt;/code&gt; contract can be serialized to XML without transformation, preserving paging semantics and metadata.&lt;/p&gt;




&lt;h3&gt;
  
  
  Search Behavior and Serialization Alignment
&lt;/h3&gt;

&lt;p&gt;Search functionality (including text search across multiple fields) is intentionally decoupled from serialization concerns.&lt;/p&gt;

&lt;p&gt;However, the &lt;strong&gt;results of search operations&lt;/strong&gt; are fully reflected in the serialized output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RowCount&lt;/code&gt; represents the count &lt;em&gt;after search and filters&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PageCount&lt;/code&gt; reflects the searched dataset&lt;/li&gt;
&lt;li&gt;The response collection contains only matching items&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guarantees that JSON or XML consumers always receive a consistent and truthful representation of the executed query.&lt;/p&gt;




&lt;h3&gt;
  
  
  Design Implications
&lt;/h3&gt;

&lt;p&gt;By designing serialization‑friendly result contracts, the library achieves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero transformation overhead at API boundaries&lt;/li&gt;
&lt;li&gt;Reduced controller/service boilerplate&lt;/li&gt;
&lt;li&gt;Clear separation between execution logic and representation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This reinforces the repository’s broader architectural theme: &lt;strong&gt;explicit contracts over implicit behavior&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PagedListResult&lt;/strong&gt; is not only a pagination and query‑execution library; it is also a &lt;strong&gt;transport‑ready result framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Its built‑in alignment with JSON and XML serialization ensures that paged results can move safely and consistently across system boundaries, making it especially suitable for real‑world API and integration scenarios.&lt;/p&gt;

&lt;p&gt;For teams working with mixed client ecosystems or strict API contracts, this aspect of the library is a critical—and often underappreciated—strength.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PagedListResult&lt;/strong&gt; is not a simple paging helper; it is a contract-driven pagination framework designed for service-oriented .NET applications.&lt;/p&gt;

&lt;p&gt;By separating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;intent (DataModels)&lt;/li&gt;
&lt;li&gt;interpretation (Common)&lt;/li&gt;
&lt;li&gt;execution (Core)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…the repository achieves a high level of clarity, safety, and extensibility.&lt;/p&gt;

&lt;p&gt;For teams building APIs that require consistent, transparent, and extensible pagination behavior, this project provides a strong and thoughtfully designed foundation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PagedListResult&lt;/strong&gt; is a strongly structured pagination solution for .NET developers who want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explicit pagination contracts&lt;/li&gt;
&lt;li&gt;Centralized query logic&lt;/li&gt;
&lt;li&gt;Rich response metadata&lt;/li&gt;
&lt;li&gt;Minimal repetition across endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repository demonstrates a clean separation between data contracts, query infrastructure, and execution logic, making it both approachable for consumers and extensible for advanced scenarios.&lt;/p&gt;

&lt;p&gt;For developers building serious, data‑driven APIs, this repository provides a solid and opinionated foundation for pagination done right.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/I-RzR-I/PagedListResult" rel="noopener noreferrer"&gt;https://github.com/I-RzR-I/PagedListResult&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>backend</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>`XmlFluentValidator`: Code-First XML Validation That Stays Close to Your Rules</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Mon, 12 Jan 2026 18:17:08 +0000</pubDate>
      <link>https://forem.com/iamrzr/xmlfluentvalidator-code-first-xml-validation-that-stays-close-to-your-rules-3mj6</link>
      <guid>https://forem.com/iamrzr/xmlfluentvalidator-code-first-xml-validation-that-stays-close-to-your-rules-3mj6</guid>
      <description>&lt;h2&gt;
  
  
  XmlFluentValidator: Code-First XML Validation That Stays Close to Your Rules
&lt;/h2&gt;

&lt;p&gt;XML is still alive and is almost everywhere used: configuration files, integration contracts, legacy systems, and enterprise messaging. Yet validating XML in a &lt;strong&gt;clean, maintainable, and expressive way&lt;/strong&gt; remains a challenge for a part of developers.&lt;/p&gt;

&lt;p&gt;A lot of teams end up choosing between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hand-written XSDs&lt;/strong&gt; that are verbose, fragile, and disconnected from business logic;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imperative validation code&lt;/strong&gt; scattered across internal services, quite difficult to reuse or document.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;XmlFluentValidator&lt;/strong&gt; proposes another approach:&lt;br&gt;
&lt;strong&gt;define XML validation rules fluently in C#, validate at runtime, and generate schemas and documentation from the same source of truth (source code).&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem/Difficulties with Traditional XML Validation
&lt;/h2&gt;

&lt;p&gt;XSD has its own power, but it comes with real trade-offs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low readability and poor discoverability;&lt;/li&gt;
&lt;li&gt;Limited expressiveness for cross-element or computed rules;&lt;/li&gt;
&lt;li&gt;Hard to evolve alongside application logic;&lt;/li&gt;
&lt;li&gt;No(or very poor) natural place for business-level validation semantics;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, pure runtime validation often results in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom XPath logic duplicated across projects;&lt;/li&gt;
&lt;li&gt;No formal schema to share with consumers;&lt;/li&gt;
&lt;li&gt;Inconsistent validation behavior between runtime and contracts;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;XmlFluentValidator can help you to close a part of this gap.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What XmlFluentValidator Is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;XmlFluentValidator&lt;/strong&gt; is a &lt;strong&gt;.NET Standard 2.0&lt;/strong&gt; library that allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define XML validation rules using a fluent, strongly-typed C# API;&lt;/li&gt;
&lt;li&gt;Validate XML documents at runtime with structured error output;&lt;/li&gt;
&lt;li&gt;Set documentation, severity, and messages to rules;&lt;/li&gt;
&lt;li&gt;Combine schema validation with custom runtime logic&lt;/li&gt;
&lt;li&gt;Generate XSD schemas from rules (supported and evolving)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It treats validation rules as &lt;strong&gt;first-class code artifacts&lt;/strong&gt;, not static XML files.&lt;/p&gt;


&lt;h2&gt;
  
  
  Core Design Principles
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. The Code Is the Source of Truth
&lt;/h3&gt;

&lt;p&gt;Validation rules live in C#, alongside your domain logic.&lt;br&gt;
No duplication between schema files and runtime validation.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Fluent, Intent-Driven API
&lt;/h3&gt;

&lt;p&gt;Rules read like &lt;strong&gt;requirements&lt;/strong&gt;, not infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What element is required?&lt;/li&gt;
&lt;li&gt;What constraints apply?&lt;/li&gt;
&lt;li&gt;Why does this rule exist?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. Runtime + Schema Compatibility
&lt;/h3&gt;

&lt;p&gt;Rules are designed to map cleanly to XSD constructs where possible, while still allowing runtime-only logic when necessary.&lt;/p&gt;


&lt;h2&gt;
  
  
  Defining Validation Rules
&lt;/h2&gt;

&lt;p&gt;At the core of the library is a fluent builder that targets &lt;strong&gt;paths, elements, and attributes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Element Rules
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XmlFluentValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/order/id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithElementRequired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order ID is required"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithElementMatchesRegex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"^\d+$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Order ID must be numeric"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/order/total"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithElementInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Total must be between 0 and 10000"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This expresses clearly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The element must exist;&lt;/li&gt;
&lt;li&gt;The value must follow a specific format;&lt;/li&gt;
&lt;li&gt;The value must be within a valid numeric range;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No XSD syntax. No XPath boilerplate.&lt;/p&gt;


&lt;h3&gt;
  
  
  Attribute Validation
&lt;/h3&gt;

&lt;p&gt;Attributes are validated explicitly and consistently:&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;validator&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/order/items/item"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithAttributeRequired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SKU is mandatory"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithAttributeMatchesRegex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;@"^[A-Z0-9\-]+$"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithAttributeInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"quantity"&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="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids the common XSD problem where attribute rules are hard to read or scattered.&lt;/p&gt;




&lt;h3&gt;
  
  
  Cardinality, Length, and Uniqueness
&lt;/h3&gt;

&lt;p&gt;The API supports common structural constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Element existence (required / optional);&lt;/li&gt;
&lt;li&gt;Maximum occurrences;&lt;/li&gt;
&lt;li&gt;Value length (min, max, exact);&lt;/li&gt;
&lt;li&gt;Uniqueness across sibling nodes;&lt;/li&gt;
&lt;li&gt;Data type enforcement;&lt;/li&gt;
&lt;li&gt;Nullable (&lt;code&gt;xs:nillable&lt;/code&gt;) control;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these can also be documented and messaged directly in code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Custom and Global Rules
&lt;/h2&gt;

&lt;p&gt;Some rules cannot be expressed in XSD at all.&lt;/p&gt;

&lt;p&gt;For example: cross-element logic, computed totals, or document-wide constraints.&lt;/p&gt;

&lt;p&gt;XmlFluentValidator supports &lt;strong&gt;global rules&lt;/strong&gt;:&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;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GlobalRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&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;items&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;XPathSelectElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/order/items/item"&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s"&gt;"Order must contain at least one item"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run at runtime;&lt;/li&gt;
&lt;li&gt;Participate in the same validation pipeline;&lt;/li&gt;
&lt;li&gt;Produce structured error messages;&lt;/li&gt;
&lt;li&gt;Can coexist with schema validation;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the strongest differentiators of the library.&lt;/p&gt;




&lt;h2&gt;
  
  
  Validation Execution and Results
&lt;/h2&gt;

&lt;p&gt;Validation is executed explicitly:&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xDocument&lt;/span&gt;&lt;span class="p"&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&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;error&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&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;Each validation error includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The XML path;&lt;/li&gt;
&lt;li&gt;The violated rule;&lt;/li&gt;
&lt;li&gt;The configured message;&lt;/li&gt;
&lt;li&gt;Severity metadata;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the output suitable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Automated tests&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  XSD Schema Generation
&lt;/h2&gt;

&lt;p&gt;A key goal of XmlFluentValidator is &lt;strong&gt;schema generation from fluent validation rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rules such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;required elements;&lt;/li&gt;
&lt;li&gt;data types;&lt;/li&gt;
&lt;li&gt;ranges;&lt;/li&gt;
&lt;li&gt;enumerations;&lt;/li&gt;
&lt;li&gt;documentation annotations;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can be emitted into an XSD representation.&lt;/p&gt;

&lt;p&gt;This allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share contracts with external systems;&lt;/li&gt;
&lt;li&gt;Keep schemas aligned with runtime validation;&lt;/li&gt;
&lt;li&gt;Avoid maintaining two parallel validation models;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The feature is actively evolving and designed into the API from the start.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Fits into Real Systems
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;XmlFluentValidator&lt;/code&gt; is especially useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XML validation rules evolve frequently;&lt;/li&gt;
&lt;li&gt;Business logic must be enforced beyond XSD capabilities;&lt;/li&gt;
&lt;li&gt;Validation must run dynamically at runtime;&lt;/li&gt;
&lt;li&gt;Schemas still need to be shared or documented;&lt;/li&gt;
&lt;li&gt;Validation logic belongs with application code, not static files;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typical use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration gateways;&lt;/li&gt;
&lt;li&gt;Configuration validation;&lt;/li&gt;
&lt;li&gt;ETL pipelines;&lt;/li&gt;
&lt;li&gt;Legacy XML modernization;&lt;/li&gt;
&lt;li&gt;Domain-specific XML formats;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;XmlFluentValidator&lt;/strong&gt; is not trying to replace XSD.&lt;br&gt;
It aims to make XML validation &lt;strong&gt;more expressive, maintainable, and aligned with the way modern .NET developers think. **&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you also believe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validation rules should read like business rules;&lt;/li&gt;
&lt;li&gt;code should be the primary source of truth;&lt;/li&gt;
&lt;li&gt;and schemas should be generated, not hand-crafted;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, XmlFluentValidator is worth your attention.&lt;/p&gt;

&lt;p&gt;🔗 Repository: &lt;a href="https://github.com/I-RzR-I/XmlFluentValidator" rel="noopener noreferrer"&gt;https://github.com/I-RzR-I/XmlFluentValidator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>xml</category>
      <category>validation</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Avoid "String or binary data would be truncated" or how to save safe strings.</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Fri, 05 Sep 2025 05:58:20 +0000</pubDate>
      <link>https://forem.com/iamrzr/avoid-string-or-binary-data-would-be-truncated-or-how-to-save-safe-strings-549k</link>
      <guid>https://forem.com/iamrzr/avoid-string-or-binary-data-would-be-truncated-or-how-to-save-safe-strings-549k</guid>
      <description>&lt;p&gt;In the current reality almost everyone and everyday interact with data and executing base CRUD operations. The most common exception met is: &lt;/p&gt;

&lt;p&gt;“&lt;code&gt;String or binary data would be truncated&lt;/code&gt;” or in other words… &lt;/p&gt;

&lt;p&gt;“&lt;code&gt;The maximum allowed field/property length was exceeded and the operation can’t be finished&lt;/code&gt;”.&lt;/p&gt;

&lt;p&gt;This error happens when the length of string data exceeds the maximum length defined for a column—resulting in disruptive runtime failures and tedious debugging. Manually trimming strings or validating their lengths can be cumbersome, especially in projects with numerous entities or frequent changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;That is where EntityMaxLengthTrim comes in.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EntityMaxLengthTrim&lt;/strong&gt; is a lightweight .NET library designed to automate the truncation of string values based on their maximum length constraints. It inspects entity properties adorned with standard data-annotation attributes—such as &lt;strong&gt;MaxLength&lt;/strong&gt;, &lt;strong&gt;StringLength&lt;/strong&gt; or &lt;strong&gt;MaxAllowedLength&lt;/strong&gt; —and a custom attribute for extra flexibility. The library trims overly long inputs before they reach the database, helping you avoid runtime exceptions while preserving code cleanliness and maintainability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why This Matters
&lt;/h4&gt;

&lt;p&gt;The value of a library like &lt;strong&gt;EntityMaxLengthTrim&lt;/strong&gt; lies in safety and consistency. By applying length rules at the entity level, you ensure that all string values conform to your schema before they reach the database. This reduces runtime surprises, prevents data loss, and keeps your codebase focused on business rules instead of plumbing.&lt;/p&gt;

&lt;h4&gt;
  
  
  How EntityMaxLengthTrim Works
&lt;/h4&gt;

&lt;p&gt;At its core, &lt;strong&gt;EntityMaxLengthTrim&lt;/strong&gt; relies on interception and reflection to ensure your entity strings always conform to the maximum allowed length before ORM attempts to persist them. Let us unpack the mechanics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Example 1:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;So from the beginning first action is to define the data model.
&lt;/li&gt;
&lt;/ul&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;FooModel&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;Guid&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;string&lt;/span&gt; &lt;span class="n"&gt;Name&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;FullName&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;Description&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The next step is to decorate every string property which you would like to apply the maximum length rule with one of the following attribute: &lt;code&gt;MaxLength&lt;/code&gt;, &lt;code&gt;StringLength&lt;/code&gt; or &lt;code&gt;MaxAllowedLength&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&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;FooModel&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;Guid&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MaxLength&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="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&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="nf"&gt;StringLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;120&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;FullName&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="nf"&gt;MaxAllowedLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;512&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;Description&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;One of the last step is to call the methods which will make &lt;code&gt;the magic&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parsedData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sourceEntityData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToSafeStoreStrings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Example 2:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;For this example, the first step is the same as in &lt;code&gt;Example 1&lt;/code&gt;, we need to define the data model.
&lt;/li&gt;
&lt;/ul&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;FooModel&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;Guid&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;string&lt;/span&gt; &lt;span class="n"&gt;Name&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;FullName&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;Description&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The next step we nedd to execute is to inheritance a base class &lt;code&gt;EntityPropChangeEventBase&lt;/code&gt; which implement the interface &lt;code&gt;INotifyPropertyChanged&lt;/code&gt; and event &lt;code&gt;PropertyChangedEventHandler&lt;/code&gt;. In the data model class we need to &lt;em&gt;convert&lt;/em&gt; &lt;code&gt;default property&lt;/code&gt; to &lt;code&gt;property with backing field&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;As result we will see:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&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;FooModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntityPropChangeEventBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_fullName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_description&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;Guid&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="n"&gt;Type&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="nf"&gt;MaxLength&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="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_name&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&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="nf"&gt;StringLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;120&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;FullName&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_fullName&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_fullName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&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="nf"&gt;MaxAllowedLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;512&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;Description&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_description&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&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;ul&gt;
&lt;li&gt;And the last step is to implement functionalities from base class
&lt;/li&gt;
&lt;/ul&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;FooModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntityPropChangeEventBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_fullName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_description&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;Guid&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MaxLength&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="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_name&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Name&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;StringLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;120&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;FullName&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_fullName&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_fullName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;_fullName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FullName&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MaxAllowedLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;512&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;Description&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_description&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_description&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;_description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Description&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So this is the result, but when we take a look in the result class first think is that: &lt;code&gt;is too much code for the set property&lt;/code&gt;.&lt;br&gt;
For this case exist another method &lt;code&gt;SetContent&lt;/code&gt; which will simplify the code:&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;FooModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntityPropChangeEventBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_fullName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_description&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;Guid&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MaxLength&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="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_name&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;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="k"&gt;value&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="nf"&gt;StringLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;120&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;FullName&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_fullName&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;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;_fullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="k"&gt;value&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;Description&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;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_description&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;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SetContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="n"&gt;_description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;ref&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;512&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 we take a look at the last code example, we can see that in the two cases was used the rule for maximum text length was used as an attribute, but in one case, the length was passed as an input parameter for &lt;code&gt;SetContent&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;As a simple conclusion, the &lt;code&gt;SetContent&lt;/code&gt; can be used in dependency on the code environment. The next time this data model is supplied with data, the maximum length rule will be triggered.&lt;/p&gt;

&lt;p&gt;These two examples are not all the use cases of when and how it can be used. For all publicly available methods, you can check the repository in GitHub; it all depends on the application's business logic and core environment, and requirements.&lt;/p&gt;

&lt;p&gt;The repository link: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/I-RzR-I" rel="noopener noreferrer"&gt;
        I-RzR-I
      &lt;/a&gt; / &lt;a href="https://github.com/I-RzR-I/EntityMaxLengthTrim" rel="noopener noreferrer"&gt;
        EntityMaxLengthTrim
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      One important thing about this repository, you have the possibility to avoid database exceptions related to exceeding the limit of the maximum allowed length of the string type columns. To specify the maximum allowed string length you can use data annotation attributes predefined in `System.ComponentModel.DataAnnotations` or a new custom attribute.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; This repository is developed for .netstandard1.5+ and net framework 4.5&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://www.nuget.org/packages/EntityMaxLengthTrim/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2d7296c4052290b8693935a8d4f91c3951c3e2cf3e00aa38dc8131c8640ff24c/68747470733a2f2f696d672e736869656c64732e696f2f6e756765742f762f456e746974794d61784c656e6774685472696d2e7376673f7374796c653d666c6174266c6f676f3d6e75676574" alt="NuGet Version"&gt;&lt;/a&gt;
&lt;a href="https://www.nuget.org/packages/EntityMaxLengthTrim" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8b4cab41629507684125d85f48241efbef9aba814a9519889f49d454ec290db9/68747470733a2f2f696d672e736869656c64732e696f2f6e756765742f64742f456e746974794d61784c656e6774685472696d2e7376673f7374796c653d666c6174266c6f676f3d6e75676574" alt="Nuget Downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One important thing about this repository is that you can truncate input string in the fields/properties at the maximum allowed length from DB. To specify the maximum allowed string length you can use data annotation attributes predefined in &lt;code&gt;System.ComponentModel.DataAnnotations&lt;/code&gt; or a new custom attribute.&lt;/p&gt;
&lt;p&gt;The maximum allowed length will be searched in the attributes(you may use one of these):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MaxLengthAttribute&lt;/code&gt; -&amp;gt; ([MaxLength(&lt;strong&gt;x&lt;/strong&gt;)]);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StringLengthAttribute&lt;/code&gt; -&amp;gt; ([StringLength(&lt;strong&gt;x&lt;/strong&gt;)]);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MaxAllowedLengthAttribute&lt;/code&gt; -&amp;gt; ([MaxAllowedLength(&lt;strong&gt;x&lt;/strong&gt;)]).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;To get acquainted with a more detailed description, please check the content table at &lt;a href="https://github.com/I-RzR-I/EntityMaxLengthTrim/docs/usage.md" rel="noopener noreferrer"&gt;the first point&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once you use this repository, you have the possibility to avoid database exceptions related to exceeding the limit of the maximum allowed length and the string type columns.&lt;/p&gt;
&lt;p&gt;No additional components or packs are required for use. So, it only needs to be added/installed in the project…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/I-RzR-I/EntityMaxLengthTrim" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>csharp</category>
      <category>webdev</category>
      <category>development</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>MediatRItemExtension - Visual Studio(2019,2022) extension made by developer for developers</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Tue, 02 Sep 2025 19:12:27 +0000</pubDate>
      <link>https://forem.com/iamrzr/mediatritemextension-visual-studio20192022-extension-made-by-developer-for-developers-3060</link>
      <guid>https://forem.com/iamrzr/mediatritemextension-visual-studio20192022-extension-made-by-developer-for-developers-3060</guid>
      <description>&lt;p&gt;This Visual Studio extension is designed to streamline the development process when working with the &lt;code&gt;MediatR&lt;/code&gt; and &lt;code&gt;FluentValidation&lt;/code&gt; NuGet packages.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FluentValidation&lt;/code&gt; is a .NET library for building strongly typed, expressive and reusable validation rules for objects, particularly model classes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MediatR&lt;/code&gt; is a lightweight, in-process messaging library for .NET that implements the Mediator design pattern. It decouples the communication between objects, enabling a clean, maintainable, and scalable architecture by reducing direct dependencies between components.&lt;/p&gt;

&lt;p&gt;This extension automates the creation of essential classes, such as &lt;code&gt;Request&lt;/code&gt; (Command/Query object), &lt;code&gt;Handler&lt;/code&gt;, and &lt;code&gt;Validator&lt;/code&gt;, ensuring consistency and reducing manual effort. By eliminating the repetitive task of setting up these boilerplate components, the extension enhances productivity, allowing developers to allocate more time to higher-priority tasks from the backlog or active sprint.&lt;/p&gt;

&lt;p&gt;From the box, are available functionalities are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save all classes in one file;&lt;/li&gt;
&lt;li&gt;Create a file for each class;&lt;/li&gt;
&lt;li&gt;Add import references (for &lt;code&gt;MediatR&lt;/code&gt; and &lt;code&gt;FluentValidation&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;Select how the request will be executed Sync or Async;&lt;/li&gt;
&lt;li&gt;Select which type of operation you want to create;&lt;/li&gt;
&lt;li&gt;Specify the name of the folder/file;&lt;/li&gt;
&lt;li&gt;Use one name for the folder/file where information will be stored;&lt;/li&gt;
&lt;li&gt;Select an option if you want to add &lt;code&gt;IStringLocalizer&lt;/code&gt;(Microsoft.Extensions.Localization) to &lt;code&gt;Validator&lt;/code&gt; or/and to the &lt;code&gt;Handler&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Specify any base class that will be added to the operation class (&lt;code&gt;Query&lt;/code&gt;, &lt;code&gt;Command&lt;/code&gt;, &lt;code&gt;Notification&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;Declare the operation inheritance class;&lt;/li&gt;
&lt;li&gt;Declare the handler inheritance class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can install extensions from the VS marketplace (&lt;a href="https://marketplace.visualstudio.com/publishers/RzR" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/publishers/RzR&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;After installing the VS extension &lt;code&gt;MediatRItemExtension.V2K19&lt;/code&gt; or &lt;code&gt;MediatRItemExtension.V2K22&lt;/code&gt; (depending on which Visual Studio version you have installed).&lt;/p&gt;

&lt;p&gt;Trigger/activate extension can be thought of as a &lt;code&gt;shortcut&lt;/code&gt; or from the project/folder &lt;code&gt;context menu&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Select a project or a folder from the solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-&amp;gt; SHIFT + INSERT + M;

-&amp;gt; Right click and select MediatR Items Creation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;How the interaction window is shown&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0vyiu9q2y5cawqkioks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0vyiu9q2y5cawqkioks.png" alt="Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repository: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/I-RzR-I" rel="noopener noreferrer"&gt;
        I-RzR-I
      &lt;/a&gt; / &lt;a href="https://github.com/I-RzR-I/MediatRItemExtension" rel="noopener noreferrer"&gt;
        MediatRItemExtension
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This is a relatively simple VS extension that allows you to create necessary classes when u use `MediatR` with `FluentValidation` nuget packages. Also, allows to save time and redirect it to more important tasks that are on the board or in the queue.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=RzR.MediatRItemExtensionV2K19" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;MediatRItemExtensionV2K19&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Extension for Visual Studio 2019&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=RzR.MediatRItemExtensionV2K22" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;MediatRItemExtensionV2K22&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Extension for Visual Studio 2022&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;This is a relatively simple VS extension that allows you to create necessary classes when u use &lt;code&gt;MediatR&lt;/code&gt; with &lt;code&gt;FluentValidation&lt;/code&gt; nuget packages. Also, allows to save time and redirect it to more important tasks that are on the board or in the queue.&lt;/p&gt;
&lt;p&gt;From the box are available functionalities as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Save all classes in one file;&lt;/li&gt;
&lt;li&gt;Create a file for each class;&lt;/li&gt;
&lt;li&gt;Add import references (for &lt;code&gt;MediatR&lt;/code&gt; and &lt;code&gt;FluentValidation&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;Select how the request will be executed &lt;code&gt;Sync&lt;/code&gt; or &lt;code&gt;Async&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Select which type of operation you want to create;&lt;/li&gt;
&lt;li&gt;Specify the name of the folder/file;&lt;/li&gt;
&lt;li&gt;Use one name for the folder/file where will be stored information;&lt;/li&gt;
&lt;li&gt;Select option if you want to add &lt;code&gt;IStringLocalizer&lt;/code&gt; to Validator or/and to the Handler;&lt;/li&gt;
&lt;li&gt;Specify any base class which will be added to the operation class (&lt;code&gt;Query&lt;/code&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/I-RzR-I/MediatRItemExtension" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>csharp</category>
      <category>visualstudio</category>
      <category>microsoft</category>
      <category>development</category>
    </item>
    <item>
      <title>Generating a version and history of code changes with automation on Azure DevOps</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Tue, 02 Sep 2025 07:26:39 +0000</pubDate>
      <link>https://forem.com/iamrzr/generating-a-version-and-history-of-code-changes-with-automation-on-azure-devops-ecn</link>
      <guid>https://forem.com/iamrzr/generating-a-version-and-history-of-code-changes-with-automation-on-azure-devops-ecn</guid>
      <description>&lt;p&gt;Every person, as an application developer, a manager, or another member of the development team, but also as a customer of a final product, is interested in being traceable throughout the project/product life cycle. &lt;/p&gt;

&lt;p&gt;To make it clear, we can define some major points as to why an application version is necessary: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Tracking changes and functionalities;&lt;/li&gt;
&lt;li&gt;  Handling errors and debugging the code;&lt;/li&gt;
&lt;li&gt;  Specifying compatibility and dependencies;&lt;/li&gt;
&lt;li&gt;  Communicating with the user/customer;&lt;/li&gt;
&lt;li&gt;  Preparing update packages;&lt;/li&gt;
&lt;li&gt;  Periodic security updates;&lt;/li&gt;
&lt;li&gt;  Product support and maintenance;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the given context, when I try to say traceability, I mean that every change made, regardless of its purpose, must be associated with a product version. Thus, every adjustment can be tracked. A code or application error can be identified in different situations, significantly reducing the time and resources required for an investigation or debugging of the code, drawing attention and resources only in a narrow direction. Also, application versioning is beneficial when communicating with the customer/user of the product about a new functionality introduced in version X, but surely there are still many reasons why it is beneficial and why it must be implemented in every project.&lt;/p&gt;

&lt;p&gt;Next, I would like to present an implementation method that would be the logic followed when generating the version and when executing changes in the code according to the commits. For the demonstration, "PowerShell", "YAML" and a C# project will be used.&lt;/p&gt;

&lt;p&gt;First, we need to define how to generate a version. For the given example, w.x.y.z will be used, where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  w -&amp;gt; major version, set manually;&lt;/li&gt;
&lt;li&gt;  x -&amp;gt; the current year will be taken at execution&lt;/li&gt;
&lt;li&gt;  y -&amp;gt; the current month will be taken at execution;&lt;/li&gt;
&lt;li&gt;  z -&amp;gt; it will be incremented by one unit each time at execution and will be reset at the beginning of each month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Example: w.x.y.z -&amp;gt; 1.25.3.1, 1.25.3.2, ..., 1.25.4.1&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once the generation algorithm is generally defined, a script must be written that will execute it each time and will take into account the current version defined in the project.&lt;/p&gt;

&lt;p&gt;The project used is one written in C#, the version will be defined in the predefined file "AssemblyInfo.cs"; we will create another file, "GeneralAssemblyInfo.cs" to be able to use it within a solution for all projects and to have a single version reflected.&lt;/p&gt;

&lt;p&gt;The data about the current version is stored in the attributes: "AssemblyVersion", "AssemblyFileVersion" and "AssemblyInformationalVersion". Following the generation of a new version, the data should be updated in this file and in the specified attributes.&lt;/p&gt;

&lt;p&gt;The file "generate-new-version.ps1"(&lt;a href="https://github.com/I-RzR-I/AutoAzureDevOpsGenerateChangeLogAndVersion/blob/main/build/generate-new-version.ps1" rel="noopener noreferrer"&gt;https://github.com/I-RzR-I/AutoAzureDevOpsGenerateChangeLogAndVersion/blob/main/build/generate-new-version.ps1&lt;/a&gt;) contains the execution code. From the current point, you can run scripts with supplying the required parameters and get a new version of the application. To enhance comfort during usage, you can create a bat file and run it every time you need it and forget about the required parameters or the value that needs to be added to a parameter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about a changelog history that is based on code commits?&lt;/strong&gt;&lt;br&gt;
Writing relevant, clear, and well-structured commit messages is crucial for maintaining organized and understandable project history. Every commit message helps team members understand the purpose of change added to the project, so it can provide base context information without the necessity to open code and examine it. A clear commit can help develop teams to track when some issue appear or was introduced, making code debugging easier, efficient, and faster.&lt;/p&gt;

&lt;p&gt;To make a change log from the commits, we need to define the logic and what we need from the changelog. In the current example, the following structure is defined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# v0.0.0.0 [DevOps ChangeLogVersion](mailto:commit@domain.com)

* [658f59b] (User) -&amp;gt; Update generate changelog pipeline

* [80c37a2] (User) -&amp;gt; Update solution build pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On generating the commit history, I’ll add more logic to simplify the number of required actions to execute the code.&lt;/p&gt;

&lt;p&gt;Creating the script file, I’ll also use the "PoweShell" script and define the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;“Get-CommitMessage” – Get the commit message added by the user;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Get-CommitHash” – Get commit hash;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Add-ChangeLog” – Add the commit data to changelog file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add input parameters to make a more customized request, like application name, generate new application version, auto pull the latest version of source/main branch, auto commit and push data (modification) to origin, source branch name, destination branch name, and current execution path (solution path). The full code and execution logic are in the “generate-change-log.ps1”(&lt;a href="https://github.com/I-RzR-I/AutoAzureDevOpsGenerateChangeLogAndVersion/blob/main/build/generate-change-log.ps1" rel="noopener noreferrer"&gt;https://github.com/I-RzR-I/AutoAzureDevOpsGenerateChangeLogAndVersion/blob/main/build/generate-change-log.ps1&lt;/a&gt;) file.&lt;/p&gt;

&lt;p&gt;In case when you are the only developer or have a small development team (2-3 persons), you can execute the script on your local machine and never mind about some problems. However, every time to open the console and write parameters, it is annoying and boring, so to use efficient time, just create a bat file and apply all parameters there. &lt;/p&gt;

&lt;p&gt;In part with automation is used “Azure DevOps”. Through automation, I try to make known the chosen method for the given case. It will try to automate the generation of a new version and the generation of the history, but also the solution build.&lt;/p&gt;

&lt;p&gt;For both cases, two files will be created: “&lt;em&gt;run_gen_changelog_version.yaml&lt;/em&gt;” and “&lt;em&gt;run_solution_build.yaml&lt;/em&gt;”. These two files will be integrated to be executed before merging the new feature branch and the stable 'develop' branch.&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;run_gen_changelog_version.yaml&lt;/em&gt;” – generate new application version, commit history in changelog;&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;run_solution_build.yaml&lt;/em&gt;” – build the solution;&lt;/p&gt;

&lt;p&gt;Integration will be achieved by implementing policies and blocking completion pull requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Azure DevOps configuration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Select your repository, for me, it is “GenerateChangeLogAndVersion”&lt;/p&gt;

&lt;p&gt;Add (import) previously specified yaml file to pipelines and set the pipeline variables. For “&lt;em&gt;run_gen_changelog_version.yaml&lt;/em&gt;”: “&lt;em&gt;commit_user_email&lt;/em&gt;” and “&lt;em&gt;repository_full_path&lt;/em&gt;”. For “&lt;em&gt;run_solution_build.yaml&lt;/em&gt;”, there are two local variables that must be modified “&lt;em&gt;solutionPath&lt;/em&gt;” and “&lt;em&gt;sdkVersion&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx92c4eo4ngzpe03urb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvx92c4eo4ngzpe03urb5.png" alt="Pipeline configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branch build service configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Select your repository, for me is “GenerateChangeLogAndVersion”&lt;/li&gt;
&lt;li&gt;Access repository branches&lt;/li&gt;
&lt;li&gt;Select the position “All branches”, then go to “Security”, and select “… Build Service” (for me is “GenerateChangeLogAndVersion Build Service”), then for “Contribute” pick “Allow” option.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16g18uhem21san5rw167.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16g18uhem21san5rw167.png" alt="Branch build service configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Branch policy configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Select your repository, for me is “GenerateChangeLogAndVersion”&lt;/li&gt;
&lt;li&gt;Access repository branches&lt;/li&gt;
&lt;li&gt;Select the “develop” branch and go to “Policies”.&lt;/li&gt;
&lt;li&gt;Here starts “Build Validation” and “Status Checks” configuration. See the images&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Build Validation Configuration&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffqrbs7s046cwptzb3wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffqrbs7s046cwptzb3wm.png" alt="Build Validation Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Status Checks Configuration&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0cjzbdi2wavqg8lo1cpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0cjzbdi2wavqg8lo1cpm.png" alt="Status Checks Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As result&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3tkmzzo9b60fny6nwn4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3tkmzzo9b60fny6nwn4.png" alt="Build Validation/Status Checks Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After all configurations on the pull request are initiated, all policies will be applied and require user action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dtoutajj3yu8p55alrm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dtoutajj3yu8p55alrm.png" alt="Policies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After “Queue”, the script with the version generate will run and push new changes in the current PR.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftwvai38l9v9skubstrxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftwvai38l9v9skubstrxz.png" alt="Execution queue result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Changelog and version result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylamth96aqq9nzvmsglf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylamth96aqq9nzvmsglf.png" alt="Changelog and version result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source code: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/I-RzR-I" rel="noopener noreferrer"&gt;
        I-RzR-I
      &lt;/a&gt; / &lt;a href="https://github.com/I-RzR-I/AutoAzureDevOpsGenerateChangeLogAndVersion" rel="noopener noreferrer"&gt;
        AutoAzureDevOpsGenerateChangeLogAndVersion
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Generating a version and history of code changes with automation on Azure DevOps
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="MD"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Generating a version and history of code changes with automation on Azure DevOps.&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Every person, as an application developer, a manager, or another member of the development team, but also as a customer of a final product, is interested in being traceable throughout the project/product life cycle.&lt;/p&gt;

&lt;p&gt;To make it clear, we can define some major points as to why an application version is necessary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracking changes and functionalities;&lt;/li&gt;
&lt;li&gt;Handling errors and debugging the code;&lt;/li&gt;
&lt;li&gt;Specifying compatibility and dependencies;&lt;/li&gt;
&lt;li&gt;Communicating with the user/customer;&lt;/li&gt;
&lt;li&gt;Preparing update packages;&lt;/li&gt;
&lt;li&gt;Periodic security updates;&lt;/li&gt;
&lt;li&gt;Product support and maintenance;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the given context, when I try to say traceability, I mean that every change made, regardless of its purpose, must be associated with a product version. Thus, every adjustment can be tracked. A code or application error can be identified in different situations, significantly reducing the time and resources required for an investigation or debugging of…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/I-RzR-I/AutoAzureDevOpsGenerateChangeLogAndVersion" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>azure</category>
      <category>git</category>
      <category>devops</category>
      <category>changelog</category>
    </item>
    <item>
      <title>Web API `Result` or `AggregatedGenericResultMessage.Web` how it works.</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Tue, 02 Sep 2025 06:52:36 +0000</pubDate>
      <link>https://forem.com/iamrzr/web-api-result-or-aggregatedgenericresultmessageweb-how-it-works-4e4f</link>
      <guid>https://forem.com/iamrzr/web-api-result-or-aggregatedgenericresultmessageweb-how-it-works-4e4f</guid>
      <description>&lt;p&gt;&lt;code&gt;Web Result&lt;/code&gt; is based on the simple implementation of &lt;code&gt;Result&lt;/code&gt;(AggregatedGenericResultMessage). The entire implementation is like a wrapper to be used within a web project, which will be able to an easy-to-understand, structured, and filtered response as needed to be returned to the client.&lt;/p&gt;

&lt;p&gt;Everything can start by inheriting the methods from &lt;code&gt;ResultBaseApiController&lt;/code&gt; which returns a response of the type &lt;code&gt;IActionResult&lt;/code&gt; and as HTTP codes 200, 204, or 400. &lt;code&gt;IResult&lt;/code&gt; or &lt;code&gt;IResult&amp;lt;T&amp;gt;&lt;/code&gt; is used as an input parameter, thus checking which code the response should be returned to the client.&lt;/p&gt;

&lt;p&gt;Another way of using it is by using methods that extend the &lt;code&gt;I/Result&lt;/code&gt; and &lt;code&gt;I/Result&amp;lt;T&amp;gt;&lt;/code&gt; functionalities from the &lt;code&gt;ToActionResult&lt;/code&gt; class, but which as a final result return &lt;code&gt;ActionResult&lt;/code&gt; via &lt;code&gt;ObjectResult&lt;/code&gt;, thus diversifying the way of use and offering opportunities and levers for easy integration into other solutions.&lt;/p&gt;

&lt;p&gt;GitHub source: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/I-RzR-I" rel="noopener noreferrer"&gt;
        I-RzR-I
      &lt;/a&gt; / &lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web" rel="noopener noreferrer"&gt;
        AggregatedGenericResultMessage-Web
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This library is an aggregate of some extensions to use more comfortable `Result lib`. In other words, transform from `Result` to `IActionResult`.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; This repository is developed using .netstandard2.1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://www.nuget.org/packages/AggregatedGenericResultMessage.Web/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cc9f9cdbf902c99fb7bbaecf1a599623dc7e6e58ac43a18ee2e2053f068e7252/68747470733a2f2f696d672e736869656c64732e696f2f6e756765742f762f4167677265676174656447656e65726963526573756c744d6573736167652e5765622e7376673f7374796c653d666c6174266c6f676f3d6e75676574" alt="NuGet Version"&gt;&lt;/a&gt;
&lt;a href="https://www.nuget.org/packages/AggregatedGenericResultMessage.Web" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2502a0e4e8166dfeabb2343f74b327365e53a2182098c6315d9868722cf19c5b/68747470733a2f2f696d672e736869656c64732e696f2f6e756765742f64742f4167677265676174656447656e65726963526573756c744d6573736167652e5765622e7376673f7374796c653d666c6174266c6f676f3d6e75676574" alt="Nuget Downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The important thing about this repository is to offer the possibility to manage and organize your result/response from infrastructure to user/controller, as the principal repository around which are built all extensions is &lt;a href="https://www.nuget.org/packages/AggregatedGenericResultMessage" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;AggregatedGenericResultMessage&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In case you wish to use it in your project, u can install the package from &lt;a href="https://www.nuget.org/packages/AggregatedGenericResultMessage.Web" rel="nofollow noopener noreferrer"&gt;nuget.org&lt;/a&gt;&lt;/strong&gt; or specify what version you want:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Install-Package AggregatedGenericResultMessage.Web -Version x.x.x.x&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Content&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/docs/usage.md" rel="noopener noreferrer"&gt;USING&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/docs/CHANGELOG.md" rel="noopener noreferrer"&gt;CHANGELOG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/docs/branch-guide.md" rel="noopener noreferrer"&gt;BRANCH-GUIDE&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Refer links:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ResultBaseApiController&lt;/code&gt;: &lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/blob/main/src/AggregatedGenericResultMessage.Web/ResultBaseApiController.c" rel="noopener noreferrer"&gt;https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/blob/main/src/AggregatedGenericResultMessage.Web/ResultBaseApiController.c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ToActionResult&lt;/code&gt;: &lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/tree/main/src/AggregatedGenericResultMessage.Web/Extensions/ActionResult" rel="noopener noreferrer"&gt;https://github.com/I-RzR-I/AggregatedGenericResultMessage-Web/tree/main/src/AggregatedGenericResultMessage.Web/Extensions/ActionResult&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>dotnet</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What is the `Result` ( AggregatedGenericResultMessage) and how does it work?</title>
      <dc:creator>RzR</dc:creator>
      <pubDate>Tue, 02 Sep 2025 06:44:40 +0000</pubDate>
      <link>https://forem.com/iamrzr/what-is-the-result-aggregatedgenericresultmessage-and-how-does-it-work-2na1</link>
      <guid>https://forem.com/iamrzr/what-is-the-result-aggregatedgenericresultmessage-and-how-does-it-work-2na1</guid>
      <description>&lt;p&gt;In this section, I would like to explain what it is for and how it can work.&lt;/p&gt;

&lt;p&gt;To begin with, it would be necessary to specify that such an idea has been around since I started my career as a developer. Surely everyone has faced a situation when during the execution of a flow, some errors or exceptions occur that need to be handled and a response returned that is understandable to each participant in the execution flow. The main reason behind the implementation was the principle that no method implemented in the code should throw an exception, the only and most correct approach is to handle it and return it in a relatively easily understood form.&lt;/p&gt;

&lt;p&gt;Respectively, this repository/package aims to provide the possibility to manage the response that must be returned as a response to the execution of a method or flow. In other words, a single type of structured response is easy to understand and further exposed, with the possibility of having full control of the messages that are returned.  Namely messages, the concept is realized in the form of messages, 6 general types of messages such as:&lt;/p&gt;

&lt;p&gt;• Information (Info);&lt;br&gt;
• Warning (Warning);&lt;br&gt;
• Error (Error);&lt;br&gt;
• Nonexistent data (NotFound);&lt;br&gt;
• Restricted access (AccessDenied);&lt;br&gt;
• Exception in the execution process (Exception).&lt;/p&gt;

&lt;p&gt;Generally, access is done by calling &lt;code&gt;Result&lt;/code&gt; and &lt;code&gt;Success&lt;/code&gt; or &lt;code&gt;Failure&lt;/code&gt; methods. These two methods are basic and are called initially after all the additional information required has been set.&lt;/p&gt;

&lt;p&gt;To be easier to use, but also flexible, extensions have been added to the current solution to set error messages such as: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;WithMessage&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WithKeyCode&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WithCodeMessage&lt;/code&gt;; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WithError&lt;/code&gt;; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WithErrors&lt;/code&gt;. 
In some cases when you may have the necessity to add in the result additional information like the link between the code execution method and data store name: stored procedure, function or table, etc; in code/result is defined object &lt;code&gt;RelatedObject&lt;/code&gt; where this information can be stored and returned to the caller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more efficient use, in some cases, you may need to execute some custom actions/functions after a successful or failed execution request. In that case, was added extension methods (&lt;code&gt;ActionOnSuccess&lt;/code&gt;, &lt;code&gt;ActionOnFailure&lt;/code&gt;, &lt;code&gt;ActionOn&lt;/code&gt;, &lt;code&gt;ExecuteAction&lt;/code&gt;, &lt;code&gt;FunctionOnSuccess&lt;/code&gt;, &lt;code&gt;FunctionOnFailure&lt;/code&gt;, &lt;code&gt;FunctionOn&lt;/code&gt;, &lt;code&gt;ExecuteFunction&lt;/code&gt;) which allow you to execute this action/function like insert log when execution has a status equal to failure.&lt;/p&gt;

&lt;p&gt;In addition to those mentioned above, within the solution, there is also another series of methods that will surely be helpful. In particular, an implementation is presented that allows the message to be returned in XML form, as in previous versions of web services (SOAP), JSON cannot be returned using XML or in other words, a dynamic response/message cannot be returned.&lt;/p&gt;

&lt;p&gt;For more technical information, please consult the available documentation and use terms from the GitHub repository.&lt;/p&gt;

&lt;p&gt;Link to the repository: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/I-RzR-I" rel="noopener noreferrer"&gt;
        I-RzR-I
      &lt;/a&gt; / &lt;a href="https://github.com/I-RzR-I/AggregatedGenericResultMessage" rel="noopener noreferrer"&gt;
        AggregatedGenericResultMessage
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This repository can help you to aggregate all results from an API or method in one. So as a result of this, you will have control over all responses given to the caller.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; This repository is developed in .netstandard2+ with support for SOAP service results mainly used in the .net framework (current support 4.5, 4.6.1 - 4.8)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://www.nuget.org/packages/AggregatedGenericResultMessage/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/436d52f030f5c07acc872d4a8d9523a661e660de2c36a0ab1c36f2759d278424/68747470733a2f2f696d672e736869656c64732e696f2f6e756765742f762f4167677265676174656447656e65726963526573756c744d6573736167652e7376673f7374796c653d666c6174266c6f676f3d6e75676574" alt="NuGet Version"&gt;&lt;/a&gt;
&lt;a href="https://www.nuget.org/packages/AggregatedGenericResultMessage" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e5827857c9c070ab5738290c4a7b5a62113d02b39ebb4c7995e783edd6b93f00/68747470733a2f2f696d672e736869656c64732e696f2f6e756765742f64742f4167677265676174656447656e65726963526573756c744d6573736167652e7376673f7374796c653d666c6174266c6f676f3d6e75676574" alt="Nuget Downloads"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The goal of this repository is to offer the possibility to manage and agree on the answers received as a result of the execution of a method or a process.&lt;/p&gt;
&lt;p&gt;In other words, it offers the possibility to use a single(general) response, structured and easier parsed model for the executed methods
As a result, you can have control over the messages and types of messages that will be obtained.&lt;/p&gt;
&lt;p&gt;By currently following, 6 general types of messages (&lt;code&gt;Info&lt;/code&gt;, &lt;code&gt;Warning&lt;/code&gt;, &lt;code&gt;Error&lt;/code&gt;, &lt;code&gt;NotFound&lt;/code&gt;, &lt;code&gt;AccessDenied&lt;/code&gt;, &lt;code&gt;Exception&lt;/code&gt;) are implemented that can be returned to the caller
As you can see in the &lt;code&gt;MessageType&lt;/code&gt; enum, there are 9 types of messages, for all 3 (&lt;code&gt;Info&lt;/code&gt;, &lt;code&gt;Warning&lt;/code&gt;, &lt;code&gt;Error&lt;/code&gt;) types previously…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/I-RzR-I/AggregatedGenericResultMessage" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>productivity</category>
      <category>api</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
