<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bipin Radhakrishnan</title>
    <description>The latest articles on DEV Community by Bipin Radhakrishnan (@bipinr).</description>
    <link>https://dev.to/bipinr</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F130272%2F203a37a4-0343-4303-8c6c-7c396d04b75a.png</url>
      <title>DEV Community: Bipin Radhakrishnan</title>
      <link>https://dev.to/bipinr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bipinr"/>
    <language>en</language>
    <item>
      <title>Why I Built CapLog: A Local-First Desktop App for Journaling and Tasks</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Wed, 15 Jul 2026 03:52:57 +0000</pubDate>
      <link>https://dev.to/bipinr/why-i-built-caplog-a-local-first-desktop-app-for-journaling-and-tasks-2f5p</link>
      <guid>https://dev.to/bipinr/why-i-built-caplog-a-local-first-desktop-app-for-journaling-and-tasks-2f5p</guid>
      <description>&lt;p&gt;Two months ago my desk had a stack of sticky notes on the monitor, a handwritten journal I kept forgetting to open, a OneNote tab for quick notes, and — if I'm honest — usually three or four Notepad windows open with things I didn't want to lose. None of it talked to each other. A task I jotted on a sticky note had no connection to the journal entry about the day I wrote it in. Finding anything meant digging through four different places and hoping I remembered which one.&lt;/p&gt;

&lt;p&gt;I wanted one app that could handle two things I kept doing separately: journaling my day and tracking my tasks. So I built &lt;a href="https://github.com/rbipin/caplog" rel="noopener noreferrer"&gt;CapLog&lt;/a&gt;, a local-first desktop app where the log, the todos, and the history all live together in a single SQLite database.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: a desk full of sticky notes and a dozen open Notepad windows
&lt;/h2&gt;

&lt;p&gt;Most productivity tools make you pick a lane. Journaling apps are built for writing and treat tasks as an afterthought. Todo apps are built for tasks and don't want your rambling notes about how the day actually went. Cloud tools solve neither problem — they just add a login screen and a sync spinner to the same fragmented setup.&lt;/p&gt;

&lt;p&gt;None of my existing tools were bad on their own. OneNote is fine for what it does. A paper journal is fine too. The problem was running all of them at once for one continuous stream of "what happened today and what do I still need to do." I wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a place to write a quick note about my day,&lt;/li&gt;
&lt;li&gt;a way to turn that note into something I could look back on,&lt;/li&gt;
&lt;li&gt;a place to capture tasks as I thought of them, without opening a second app,&lt;/li&gt;
&lt;li&gt;and a history I could actually search instead of flipping through notebook pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the gap CapLog fills. It isn't trying to replace every note app or task manager on the market. It's trying to be the one app I keep open while I work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why local, why desktop
&lt;/h2&gt;

&lt;p&gt;I wanted CapLog to be local and secure, and those two things turned out to be the same decision. Local meant the data stays on my machine — no server holding my daily logs, no account to lose access to, no sync conflicts to resolve at 11 PM. Desktop meant no browser tab competing for my attention and no "sign in to continue" between me and a quick note.&lt;/p&gt;

&lt;p&gt;Once I committed to desktop and local, the rest of the product got simpler to reason about. SQLite became the single source of truth. Export became "write a file to disk," not "call an API." And AI — which I wanted for formatting, not as a requirement — became something the app could do without. If AI is off or the request fails, CapLog just saves your raw text as a Markdown bullet. The app doesn't stop working because a network call didn't.&lt;/p&gt;

&lt;p&gt;Security here isn't a checklist item, it's a side effect of the architecture: there's no application server in the middle, no custom backend API to secure, and no routine transmission of your logs anywhere. Data leaves the machine only when you explicitly turn on AI formatting or export a file.&lt;/p&gt;

&lt;h2&gt;
  
  
  What CapLog actually does
&lt;/h2&gt;

&lt;p&gt;CapLog is deliberately small. You type into one input, and the app turns that into either a Markdown journal entry or a task, depending on what you type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plain text becomes a log entry.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/todo&lt;/code&gt; creates a task.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/important&lt;/code&gt; marks a high-priority task.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/done&lt;/code&gt; completes an existing task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an AI provider is configured, it cleans up and formats the entry the moment you submit it. If it isn't, your text is saved exactly as you typed it, wrapped in a Markdown bullet. Either way, it lands in the same place: one local SQLite database, one feed, one history.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpq7sgf15ntsflluv24km.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpq7sgf15ntsflluv24km.png" alt="caplog application screenshot" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's the entire interaction model. No folders to organize, no tags to maintain, no settings to tune before you can start using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's built: no backend, anywhere
&lt;/h2&gt;

&lt;p&gt;CapLog is a Tauri v2 desktop app: a React and TypeScript frontend running in a native webview, with SQLite accessed directly through &lt;code&gt;tauri-plugin-sql&lt;/code&gt;. The Rust side exists to host the window and wire up plugins — its &lt;code&gt;invoke_handler&lt;/code&gt; is empty. There's no custom backend, and that includes the AI calls: when a provider is configured, the renderer talks straight to &lt;code&gt;api.anthropic.com&lt;/code&gt; or an OpenAI-compatible endpoint over &lt;code&gt;fetch()&lt;/code&gt;, using an API key stored in the local SQLite settings table.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffv8sz3zpu1qmxhiu5q1c.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffv8sz3zpu1qmxhiu5q1c.png" alt="Architecture Diagram" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The codebase follows a strict, one-directional layering: components handle UI, hooks connect the UI to data through TanStack Query, repository modules hold the SQL and return typed domain objects, and &lt;code&gt;db.ts&lt;/code&gt; is the thin wrapper over SQLite. Only repos are allowed to touch &lt;code&gt;db.ts&lt;/code&gt; — components never call the database directly. That rule keeps the UI from knowing anything about SQL, and it means the storage layer is isolated enough that it could be swapped out later without touching the rest of the app.&lt;/p&gt;

&lt;p&gt;Data flow is just as plain. You type into the chat-style input, CapLog figures out whether it's a log entry or a slash command, formats it if AI is on, writes it, and TanStack Query invalidates the affected caches so the feed refreshes. Fewer moving parts between typing and saved data means fewer things that can break.&lt;/p&gt;

&lt;p&gt;Content is stored as Markdown, not HTML, which keeps export simple and the renderer safe — CapLog uses a Markdown renderer with raw HTML disabled rather than trusting arbitrary HTML from the app's own history or a model's response.&lt;/p&gt;

&lt;p&gt;Archive search follows the same layering, and it's intentionally simple. &lt;code&gt;archiveRepo.searchDates(year, q)&lt;/code&gt; runs one SQL query — &lt;code&gt;SELECT DISTINCT date FROM log_entries WHERE date LIKE '{year}-%' AND formatted_text LIKE '%{q}%'&lt;/code&gt; — scoped to the selected year, matching against the formatted (AI-cleaned) Markdown text. &lt;code&gt;useArchiveSearch&lt;/code&gt; wraps that in a TanStack Query hook keyed on &lt;code&gt;['archive', 'search', year, q]&lt;/code&gt;, only firing once you've typed something. The archive modal takes the resulting dates and highlights them on the year calendar; click one and it opens that day's log.&lt;/p&gt;

&lt;p&gt;It's a substring match, not full-text or fuzzy search — no ranking, no tokenization, and it only searches log entries, not todos. Switching years re-runs the query. That's a deliberate tradeoff: it's fast, it's easy to reason about, and it covers the actual use case of "I remember roughly what I wrote, help me find the day." A smarter search engine is on the list of things that could get built later, but it hasn't earned its complexity yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two months in
&lt;/h2&gt;

&lt;p&gt;I've been using CapLog daily for two months now, and the sticky notes are gone. So is the handwritten journal, the OneNote tab, and the pile of open Notepad windows. Everything that used to live scattered across four places now lives in one feed I actually look back on, because looking back doesn't mean digging through a notebook or hunting for the right Notepad window.&lt;/p&gt;

&lt;p&gt;The foundation is there: local storage, structured logs, task tracking, history and archive views, optional AI formatting, and export to a plain Markdown file. What's left is polish, not new scope — small improvements that make the daily habit smoother, not new features that make the app bigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it, or steal the idea
&lt;/h2&gt;

&lt;p&gt;CapLog is open source: &lt;a href="https://github.com/rbipin/caplog" rel="noopener noreferrer"&gt;github.com/rbipin/caplog&lt;/a&gt;. If you're juggling the same scattered setup — a notes app here, a todo app there, a journal you keep meaning to open — clone it and see if one input box is enough for you too. And if it isn't quite right for how you work, the architecture is small enough to fork and bend into your own shape: layered frontend, local SQLite, no backend to fight with.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Alternate ways to intercept and manipulate Response in Asp.Net Core- Part 3</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Sun, 07 Jun 2020 14:59:53 +0000</pubDate>
      <link>https://dev.to/bipinr/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-3-4f34</link>
      <guid>https://dev.to/bipinr/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-3-4f34</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I have a web API with two endpoints, the endpoints serve mapped data in XML format for two different vendors. The result of both the endpoints is the same object but there are some differences like namespaces. The problem is how to return the same object with only namespaces serialized differently? I didn't want to go with the obvious solution of serializing the object with the different namespaces and returning them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution 3
&lt;/h2&gt;

&lt;p&gt;This approach is a mix of &lt;a href="https://dev.to/rbipin/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-1-4omf"&gt;solution 1&lt;/a&gt; and &lt;a href="https://dev.to/rbipin/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-2-2mbc"&gt;Solution 2&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Create Action Filters for the two endpoints, also created two output formatters like in solution 1 for both the endpoints. In the action filter, get the result object and add the output formatters to the formatters of the result.&lt;/p&gt;


&lt;h3&gt;
  
  
  Pros and Cons of the solution
&lt;/h3&gt;



&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The MVC pipeline remains unaltered, unlike Solution 1.&lt;/li&gt;
&lt;li&gt;Because there is a separate action filter, there is a clear separation of concerns. Code is well separated, i.e business logic is taken care of by the API, and formatting the output is achieved by the formatters.&lt;/li&gt;
&lt;li&gt;We are not writing into the response body here like solution 2, so the middleware in the pipeline will not be affected in case any middleware alters the response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I haven't found any yet. Let me know in case any finds any.&lt;/p&gt;


&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;



&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I created two Action Filters one for the Washington weather station endpoint and Quebec endpoint.&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-action-filters.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-action-filters.JPG" alt="Sol2-action-filters" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The snippet of the new Action Filter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class QubecCanadaOuputFilterAttribute : ActionFilterAttribute
    {
        public override async void OnResultExecuting(ResultExecutingContext context)
        {
            var response = context.HttpContext.Response;
            if (response.StatusCode != 200)
            {
                base.OnResultExecuting(context);
            }
            var result = context.Result as ObjectResult;
            result.Formatters.Add(new QuebecCanadaOutputFormatter());

            base.OnResultExecuting(context);
        }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next created two output formatters for the endpoints, one for Washington and other for Quebec Canada endpoint&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2Fcode_output_formatters.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2Fcode_output_formatters.JPG" alt="code_output_formatters" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The snippet of one of the output formatters&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public class QuebecCanadaOutputFormatter : XmlSerializerOutputFormatter
    {
        public QuebecCanadaOutputFormatter()
        {

        }
        public QuebecCanadaOutputFormatter(XmlWriterSettings xmlWriterSettings) : base(xmlWriterSettings)
        {

        }
        protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
        {
            var namespaces = new XmlSerializerNamespaces();
            namespaces.Add("WS", "http://www.qubeccanadaweatherstation.com/xml/namespaces/type");
            namespaces.Add("Metric", "http://www.qubeccanadaweatherstation.com/xml/namespaces/siunit/temperature");
            xmlSerializer.Serialize(xmlWriter, value, namespaces);
        }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created a middleware called &lt;em&gt;SimpleMiddleware&lt;/em&gt; in the solution. The middleware simply sets the response status to 200.&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-middleware.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-middleware.JPG" alt="Sol2-middleware" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Endpoint 1: Washington Weather Staion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WeatherForecast xmlns:WS="http://www.wausweatherStation.com/xml/namespaces/type" xmlns:Metric="http://www.wausweatherstation.com/xml/namespaces/siunit/temperature"&amp;gt;
&amp;lt;Date&amp;gt;2020-06-02T13:50:52.5094204-04:00&amp;lt;/Date&amp;gt;
&amp;lt;Temperature&amp;gt;
&amp;lt;Celsius&amp;gt;8&amp;lt;/Celsius&amp;gt;
&amp;lt;Farenheit&amp;gt;46&amp;lt;/Farenheit&amp;gt;
&amp;lt;/Temperature&amp;gt;
&amp;lt;Summary&amp;gt;Mild&amp;lt;/Summary&amp;gt;
&amp;lt;/WeatherForecast&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Endpoint 2: Quebec Canada&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WeatherForecast xmlns:WS="http://www.qubeccanadaweatherstation.com/xml/namespaces/type" xmlns:Metric="http://www.qubeccanadaweatherstation.com/xml/namespaces/siunit/temperature"&amp;gt;
&amp;lt;Date&amp;gt;2020-06-02T13:56:09.5506734-04:00&amp;lt;/Date&amp;gt;
&amp;lt;Temperature&amp;gt;
&amp;lt;Celsius&amp;gt;34&amp;lt;/Celsius&amp;gt;
&amp;lt;Farenheit&amp;gt;93&amp;lt;/Farenheit&amp;gt;
&amp;lt;/Temperature&amp;gt;
&amp;lt;Summary&amp;gt;Cool&amp;lt;/Summary&amp;gt;
&amp;lt;/WeatherForecast&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The sample code for solution 3 is &lt;a href="https://github.com/BipinBlog/asp.net_response_manipulation" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;&lt;br&gt;
or &lt;a href="https://github.com/BipinBlog/asp.net_response_manipulation" rel="noopener noreferrer"&gt;https://github.com/BipinBlog/asp.net_response_manipulation&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Solution : OutputFormatters_in_result.sln&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webapi</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Alternate ways to intercept and manipulate response in Asp.Net core - Part 2</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Sun, 07 Jun 2020 14:36:01 +0000</pubDate>
      <link>https://dev.to/bipinr/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-2-2mbc</link>
      <guid>https://dev.to/bipinr/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-2-2mbc</guid>
      <description>&lt;h2&gt;
  
  
  The Problem:
&lt;/h2&gt;

&lt;p&gt;I have a web API with two endpoints, the endpoints serve data in XML format for two different vendors. The result of both the endpoints is the same object but there are some differences like namespaces. The problem is how to return the same object with only namespaces serialized differently? I didn't want to go with the obvious solution of serializing the object with the different namespaces and returning them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/rbipin/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-1-4omf"&gt;Solution 1&lt;/a&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Solution 2
&lt;/h2&gt;

&lt;p&gt;Create &lt;em&gt;Action Filters&lt;/em&gt; for the endpoints and manually serialize the output in the &lt;em&gt;OnResultExecuting()&lt;/em&gt; method and write the serialized output to the response body.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons of the solution
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The MVC pipeline remains unaltered, unlike Solution 1.&lt;/li&gt;
&lt;li&gt;Because there is a separate action filter, there is a clear separation of concerns. Code is well separated, i.e business logic is taken care of by the API, and formatting the output is achieved by the formatters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since we start writing the response body, further manipulation of response is not possible. This is demonstrated in the mode using a middleware.
&amp;lt;!--kg-card-end: markdown--&amp;gt;
### Implementation
&amp;lt;!--kg-card-begin: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I created two action filters one for the Washington weather station endpoint and Quebec endpoint.&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-action-filters.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-action-filters.JPG" alt="Sol2-action-filters" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I created a custom XML serializer to serialize the object into XML.&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-xml-serializers.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-xml-serializers.JPG" alt="Sol2-xml-serializers" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Use the XML serializers in the corresponding action filters and serialize the object, here is a snippet from Washington action filter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Action Filter
public class WashingtonOuputFilterAttribute : ActionFilterAttribute
    {
        public override async void OnResultExecuting(ResultExecutingContext context)
        {
            var response = context.HttpContext.Response;
            if (response.StatusCode != 200)
            {
               base.OnResultExecuting(context);
            }
            var result = context.Result as ObjectResult;
            var serializedResult = WashingtonOutputSerializer.Instance.Serialize(result.Value);
            var resultBytes = Encoding.UTF8.GetBytes(serializedResult);
            response.Headers.Add("Content-Type","application/xml");
            await response.Body.WriteAsync(resultBytes, 0, resultBytes.Length);
            base.OnResultExecuting(context);
        }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the code of lazy-loaded singleton Washington XML Serializer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Washington XML Serializer
 public class WashingtonOutputSerializer
    {
        public static readonly Lazy&amp;lt;WashingtonOutputSerializer&amp;gt; lazyWashingtonSerializer =
            new Lazy&amp;lt;WashingtonOutputSerializer&amp;gt;(() =&amp;gt; new WashingtonOutputSerializer());
        public static WashingtonOutputSerializer Instance
        {
            get { return lazyWashingtonSerializer.Value; }
        }
        private WashingtonOutputSerializer() { }
        public string Serialize(object outputObject)
        {
            var namespaces = new XmlSerializerNamespaces();
            namespaces.Add("WS", "http://www.wausweatherStation.com/xml/namespaces/type");
            namespaces.Add("Metric", "http://www.wausweatherstation.com/xml/namespaces/siunit/temperature");
            return XMLSerializer.Instance.Serialize(outputObject, namespaces);
        }
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created a middleware called &lt;em&gt;SimpleMiddleware&lt;/em&gt; in the solution to demonstrate one of the drawbacks of this solution and why I started searching for solution 3. The middleware simply sets the response status to 200.&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-middleware.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2FSol2-middleware.JPG" alt="Sol2-middleware" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The middleware is commented in the &lt;em&gt;Configure()&lt;/em&gt; method in the &lt;em&gt;Startup.cs&lt;/em&gt; file.&lt;br&gt;&lt;br&gt;
you may uncomment and check out the error&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; //app.UseSimpleMiddleware();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2Ferror_middleware-1.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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2Ferror_middleware-1.png" alt="error_middleware-1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;lt;!--kg-card-end: markdown--&amp;gt;&amp;lt;!--kg-card-begin: markdown--&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Endpoint 1: Washington Weather Staion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WeatherForecast xmlns:WS="http://www.wausweatherStation.com/xml/namespaces/type" xmlns:Metric="http://www.wausweatherstation.com/xml/namespaces/siunit/temperature"&amp;gt;
&amp;lt;Date&amp;gt;2020-06-02T13:50:52.5094204-04:00&amp;lt;/Date&amp;gt;
&amp;lt;Temperature&amp;gt;
&amp;lt;Celsius&amp;gt;8&amp;lt;/Celsius&amp;gt;
&amp;lt;Farenheit&amp;gt;46&amp;lt;/Farenheit&amp;gt;
&amp;lt;/Temperature&amp;gt;
&amp;lt;Summary&amp;gt;Mild&amp;lt;/Summary&amp;gt;
&amp;lt;/WeatherForecast&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Endpoint 2: Quebec Canada Weather Station&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WeatherForecast xmlns:WS="http://www.qubeccanadaweatherstation.com/xml/namespaces/type" xmlns:Metric="http://www.qubeccanadaweatherstation.com/xml/namespaces/siunit/temperature"&amp;gt;
&amp;lt;Date&amp;gt;2020-06-02T13:56:09.5506734-04:00&amp;lt;/Date&amp;gt;
&amp;lt;Temperature&amp;gt;
&amp;lt;Celsius&amp;gt;34&amp;lt;/Celsius&amp;gt;
&amp;lt;Farenheit&amp;gt;93&amp;lt;/Farenheit&amp;gt;
&amp;lt;/Temperature&amp;gt;
&amp;lt;Summary&amp;gt;Cool&amp;lt;/Summary&amp;gt;
&amp;lt;/WeatherForecast&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/rbipin/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-3-4f34"&gt;Solution 3&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The sample code for solution is &lt;a href="https://github.com/BipinBlog/asp.net_response_manipulation" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;&lt;br&gt;
or &lt;a href="https://github.com/BipinBlog/asp.net_response_manipulation" rel="noopener noreferrer"&gt;https://github.com/BipinBlog/asp.net_response_manipulation&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Solution : Serialize_in_action_filter.sln&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webapi</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Alternate ways to intercept and manipulate response in Asp.Net core- Part 1</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Sun, 07 Jun 2020 11:42:06 +0000</pubDate>
      <link>https://dev.to/bipinr/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-1-4omf</link>
      <guid>https://dev.to/bipinr/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-1-4omf</guid>
      <description>&lt;p&gt;I'm going to make this post kind of a problem and solution post. In my pursuit to solve my problem, I stumbled upon three different solutions. I'm going to make each of these solutions a different post/ part. I will also discuss the pros and cons that I found with each of the solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem:
&lt;/h2&gt;

&lt;p&gt;I have a web API with two endpoints, the endpoints serve data in XML format for two different vendors. The result of both the endpoints is the same object but there are some differences like namespaces. The problem is how to return the same object with only namespaces serialized differently? I didn't want to go with the obvious solution of serializing the object with the different namespaces and returning them. I wanted to explore other ways to tackle this. Why? because this will be fun ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution 1
&lt;/h2&gt;

&lt;p&gt;Using Action Filter to clear the output formatter of the MVC pipeline and adding the vendor-specific formatter&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons of the solution
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code is nice separated, i.e business logic is taken care of by the API, and formatting the output is achieved by the formatters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are directly manipulating the output formatters in the MVC pipeline.&lt;/li&gt;
&lt;li&gt;Unable to test in my machine, but I believe this may interfere with other endpoints, I also noticed a null reference exception from this area after hosting in the cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I created two output formatters inheriting from XmlSerializerOutputFormatter. I serialize the object to the correct format using the vendor-specific XML namespaces.&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2Fcode_output_formatters.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F06%2Fcode_output_formatters.JPG" alt="code_output_formatters" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The snippet of output formatter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace OutputFormatter.API
{
    public class WashingtonOutputFormatter : XmlSerializerOutputFormatter
    {
        public WashingtonOutputFormatter()
        {

        }
        public WashingtonOutputFormatter(XmlWriterSettings xmlWriterSettings) : base(xmlWriterSettings)
        {

        }
        protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
        {
            var namespaces = new XmlSerializerNamespaces();
            namespaces.Add("WS", "http://www.wausweatherStation.com/xml/namespaces/type");
            namespaces.Add("Metric", "http://www.wausweatherstation.com/xml/namespaces/siunit/temperature");
            xmlSerializer.Serialize(xmlWriter, value, namespaces);
        }

    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create two ActionFilterAttribute, in this case for Quebec Canada and another for Washington. These two action filters will clear the existing output filters in the MVC pipeline and add the corresponding output filter. Quebec Canada Action filter will add the Quebec Canada output formatter to the pipeline and the Washington Action filter will add only Washington output formatter.&lt;/p&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F05%2Fcode_action_filter.JPG" 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%2Fblog.bipinr.com%2Fcontent%2Fimages%2F2020%2F05%2Fcode_action_filter.JPG" width="800" height="400"&gt;&lt;/a&gt;screen shot of action filter attribute&lt;br&gt;
&lt;p&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class WashingtonOuputFilterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var washingtonOutputFormat = new WashingtonOutputFormatter(new XmlWriterSettings()
            {
                OmitXmlDeclaration = true
            });

            var outputFormattersToRemove = new List&amp;lt;IOutputFormatter&amp;gt;()
            {
                new XmlSerializerOutputFormatter(),
                new SystemTextJsonOutputFormatter(new System.Text.Json.JsonSerializerOptions()),
                new QuebecCanadaOutputFormatter()
            };
            var commonFormatter = new FilterActionCommon();
            commonFormatter.ClearOutputFormatters(context, outputFormattersToRemove);
            commonFormatter.AddOutputFormatter(context, washingtonOutputFormat);
            base.OnActionExecuting(context);
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Endpoint 1: Washington Weather Staion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WeatherForecast xmlns:WS="http://www.wausweatherStation.com/xml/namespaces/type" xmlns:Metric="http://www.wausweatherstation.com/xml/namespaces/siunit/temperature"&amp;gt;
&amp;lt;Date&amp;gt;2020-06-02T13:50:52.5094204-04:00&amp;lt;/Date&amp;gt;
&amp;lt;Temperature&amp;gt;
&amp;lt;Celsius&amp;gt;8&amp;lt;/Celsius&amp;gt;
&amp;lt;Farenheit&amp;gt;46&amp;lt;/Farenheit&amp;gt;
&amp;lt;/Temperature&amp;gt;
&amp;lt;Summary&amp;gt;Mild&amp;lt;/Summary&amp;gt;
&amp;lt;/WeatherForecast&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Endpoint 2: Quebec Canada Weather Station&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WeatherForecast xmlns:WS="http://www.qubeccanadaweatherstation.com/xml/namespaces/type" xmlns:Metric="http://www.qubeccanadaweatherstation.com/xml/namespaces/siunit/temperature"&amp;gt;
&amp;lt;Date&amp;gt;2020-06-02T13:56:09.5506734-04:00&amp;lt;/Date&amp;gt;
&amp;lt;Temperature&amp;gt;
&amp;lt;Celsius&amp;gt;34&amp;lt;/Celsius&amp;gt;
&amp;lt;Farenheit&amp;gt;93&amp;lt;/Farenheit&amp;gt;
&amp;lt;/Temperature&amp;gt;
&amp;lt;Summary&amp;gt;Cool&amp;lt;/Summary&amp;gt;
&amp;lt;/WeatherForecast&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can see that the only difference between the two output are the namespaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://dev.to/rbipin/alternate-ways-to-intercept-and-manipulate-response-in-asp-net-core-part-2-2mbc"&gt;Solution 2&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The sample code for this is &lt;a href="https://github.com/BipinBlog/asp.net_response_manipulation" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;&lt;br&gt;
or &lt;a href="https://github.com/BipinBlog/asp.net_response_manipulation" rel="noopener noreferrer"&gt;https://github.com/BipinBlog/asp.net_response_manipulation&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Solution : OutputFormatters-Pipeline.sln&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webapi</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>My learning plan 2020</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Fri, 29 May 2020 10:55:59 +0000</pubDate>
      <link>https://dev.to/bipinr/my-learning-plan-2020-19io</link>
      <guid>https://dev.to/bipinr/my-learning-plan-2020-19io</guid>
      <description>&lt;p&gt;This is a list of things I want to learn in 2020 and why these subjects interest me. These are not in any order, so I may try to learn things based on my interest and as I time permits. I know this is a pretty extensive list, so I'm trying to achieve as much possible. I believe some I can learn as part of my work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to learn &lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;, this is a very popular framework and I could use this at my work too. An added advantage, the latest version of angular uses &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;typescript&lt;/a&gt; and I can pick up some typescript when learning angular.&lt;/li&gt;
&lt;li&gt;Learning &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt;, another popular framework. I tried to learn some basics and found this very interesting. React is also used in building cross-platform apps using &lt;a href="https://reactnative.dev/" rel="noopener noreferrer"&gt;react native&lt;/a&gt; for mobile and &lt;a href="https://www.electronjs.org/" rel="noopener noreferrer"&gt;electronjs&lt;/a&gt; for desktop.&lt;/li&gt;
&lt;li&gt;I want to learn &lt;a href="https://www.adobe.com/in/products/photoshop.html" rel="noopener noreferrer"&gt;Adobe Photoshop&lt;/a&gt; and &lt;a href="https://www.adobe.com/in/products/photoshop-lightroom.html" rel="noopener noreferrer"&gt;Adobe Lightroom&lt;/a&gt; because I'm also a photography enthusiast and want to be better in photo editing.&lt;/li&gt;
&lt;li&gt;I want to learn &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;vue.js&lt;/a&gt;, this is another front end framework for web design that is gaining a lot of traction.&lt;/li&gt;
&lt;li&gt;Master &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt; principles, is fundamental for any good application architecture. I have a good understand of SOLID principles and try to follow these in my application architecture, but no always.&lt;/li&gt;
&lt;li&gt;Learn &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;, because of this industry-acclaimed container orchestration system.&lt;/li&gt;
&lt;li&gt;Complete Harvard &lt;a href="https://online-learning.harvard.edu/course/cs50-introduction-computer-science" rel="noopener noreferrer"&gt;CS50&lt;/a&gt; course, this is a great course to refresh your computer science basics and is considered to be the best.&lt;/li&gt;
&lt;li&gt;Learn a bit of &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python&lt;/a&gt;, python is a favorite for folks in data analysis, AI, and Machine learning. These are areas I would like to learn at some point in the future. So learning a little bit of Python will benefit me. I'm hoping I can lean this as part of the CS50 course.&lt;/li&gt;
&lt;li&gt;I want to learn &lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;golang&lt;/a&gt;, I have a heard lot about golang and how this is being used increasingly more these days.&lt;/li&gt;
&lt;li&gt;Learning &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Nodejs&lt;/a&gt;, I know a little bit of nodejs already. I worked on a personal project using nodejs, but did not get time to learn it properly and finish my project.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>learning</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I created an AutoMapper in C# to copy property values automatically</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Wed, 27 May 2020 09:24:41 +0000</pubDate>
      <link>https://dev.to/bipinr/i-created-an-automapper-in-c-to-copy-property-values-automatically-1483</link>
      <guid>https://dev.to/bipinr/i-created-an-automapper-in-c-to-copy-property-values-automatically-1483</guid>
      <description>&lt;p&gt;I was working on a project that required mapping values to complex objects when I say complex the target object was a large collection of multiple objects several levels deep. Some of the objects to which the values had to be mapped were several levels down. The task of finding the correct objects or directly assigning values to the properties of objects was tedious, especially if it had to be done over and over again. This problem led me to create the object auto mapper. During the course of this post, the target is the object you are operating on or mapping the values to and the source is the object from which the values are copied.&lt;/p&gt;

&lt;p&gt;Auto mapper uses reflection to index all the objects on which it is operating. After the index is created, the algorithm can then identify the target object on which to operate based on the type of the source object. Once the target object is found then the algorithm sweeps through the properties of the target to identify all the properties that have a public set on them. The algorithm will now set the values of the properties.&lt;/p&gt;

&lt;p&gt;Some of the features of my Auto mapper is&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically finds the first occurrence of an object type and maps them.&lt;/li&gt;
&lt;li&gt;If there are multiple objects of the same type in the target object, you can specify the property name to map it to.&lt;/li&gt;
&lt;li&gt;If the object already has some data in it, this will preserve the existing once and map only the new once.&lt;/li&gt;
&lt;li&gt;If the target property is null, the auto mapper can initialize the property and map the values.&lt;/li&gt;
&lt;li&gt;If the target property is a List or an Array[], it can initialize it.&lt;/li&gt;
&lt;li&gt;If the property is null or if it already has values the new values get added to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/rbipin/AutoMapper" rel="noopener noreferrer"&gt;https://github.com/rbipin/AutoMapper&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>automapper</category>
      <category>reflections</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>5 Useful IBM DB2 Queries</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Thu, 04 Jan 2018 05:22:20 +0000</pubDate>
      <link>https://dev.to/bipinr/5-useful-ibm-db2-queries-ek3</link>
      <guid>https://dev.to/bipinr/5-useful-ibm-db2-queries-ek3</guid>
      <description>&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2Fwordpress%2F2018%2F01%2Fibm_db2.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%2Fblog.bipinr.com%2Fcontent%2Fimages%2Fwordpress%2F2018%2F01%2Fibm_db2.png" alt="5 Useful DB2 Queries" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some IBM DB2 queries that can be very useful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Query to identify Stores Procedures that is using a particular table
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Identify Schema used by a Stored Procedures
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Identify Primary Key of a table
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Identify Foreign key of a table
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  View used by table
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>database</category>
      <category>db2</category>
      <category>ibm</category>
      <category>ibmdb2</category>
    </item>
    <item>
      <title>Log4net rolling file log based on date and file size</title>
      <dc:creator>Bipin Radhakrishnan</dc:creator>
      <pubDate>Tue, 15 Aug 2017 03:04:08 +0000</pubDate>
      <link>https://dev.to/bipinr/log4net-rolling-file-log-based-on-date-and-file-size-32k7</link>
      <guid>https://dev.to/bipinr/log4net-rolling-file-log-based-on-date-and-file-size-32k7</guid>
      <description>&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%2Fblog.bipinr.com%2Fcontent%2Fimages%2Fwordpress%2F2017%2F08%2FApacheSoftwareFoundation.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%2Fblog.bipinr.com%2Fcontent%2Fimages%2Fwordpress%2F2017%2F08%2FApacheSoftwareFoundation.png" alt="Log4net rolling file log based on date and file size" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Logging is an important part of any application and a developer spends a good amount of time writing code to log. Logging is important as this helps us create a trace of all the events in the application and in turn helps in debugging, identifying and analyzing issues and bugs. Log4net is an open source framework for logging the output in an application. The application framework is released under Apache License, Version 2.0. Log4net provides multiple types of logging techniques.&lt;/p&gt;

&lt;p&gt;What we are going to discuss today is how to configure log4net for a requirement I wanted to implement in one of my project? Requirement was to implement a rolling log system based on date and file size. i.e I wanted to implement a file logging, that would create a new log file everyday and if the file size extends a certain size it should create a new file.&lt;/p&gt;

&lt;p&gt;To accomplish this, I used the “&lt;em&gt;RollingFileAppender&lt;/em&gt;” for the type of appender. Let’s discuss the important parameters in the configuration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;PreserveLogFileNameExtension&lt;/em&gt; – This parameter indicates if the file extension of the log files should be preserved during rolling.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;rollingStyle&lt;/em&gt; – Rolling criteria to use for log, I used &lt;em&gt;Composite&lt;/em&gt; to roll based on date and size of the log.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;datePattern&lt;/em&gt; – Date pattern to append to the log file name, I configured this as &lt;em&gt;_MMddyyyy&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;maxSizeRollBackups&lt;/em&gt; – Maximum number of log files to keep before deleting during rolling.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;maximumFileSize&lt;/em&gt; – Maximum size of the log file before it is rolled to new file.
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;staticLogFileName&lt;/em&gt; – Indicates whether to always log in the same file, I set this to &lt;em&gt;true&lt;/em&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the component to read the parameter from the config file. We to add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XmlConfigurator.Configure();
or
[assembly: log4net.Config.XmlConfigurator(Watch=false)]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters used in the configuration are given below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;log4net&amp;gt;
  &amp;lt;appender name="RollingLogFile" type="log4net.Appender.RollingFileAppender"&amp;gt;
    &amp;lt;file value="log.log" /&amp;gt;
    &amp;lt;PreserveLogFileNameExtension value="true"/&amp;gt;
    &amp;lt;appendToFile value="false" /&amp;gt;
    &amp;lt;rollingStyle value="Composite"/&amp;gt;
    &amp;lt;datePattern value="_MMddyyyy"/&amp;gt;
    &amp;lt;maxSizeRollBackups value="2"/&amp;gt;
    &amp;lt;maximumFileSize value="10KB"/&amp;gt;
    &amp;lt;staticLogFileName value="true" /&amp;gt;
    &amp;lt;layout type="log4net.Layout.PatternLayout"&amp;gt;
      &amp;lt;conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /&amp;gt;
    &amp;lt;/layout&amp;gt;
  &amp;lt;/appender&amp;gt;
  &amp;lt;root&amp;gt;
    &amp;lt;appender-ref ref="RollingLogFile" /&amp;gt;
  &amp;lt;/root&amp;gt;
&amp;lt;/log4net&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sample code with the configuration and code used to test the rolling log is available in the below repository&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Sample Code:&lt;/strong&gt; &lt;a href="https://github.com/rbipin/RollingLog_Log4net" rel="noopener noreferrer"&gt;https://github.com/rbipin/RollingLog_Log4net&lt;/a&gt;&lt;/p&gt;

</description>
      <category>filelogging</category>
      <category>log4net</category>
      <category>logging</category>
    </item>
  </channel>
</rss>
