<?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: Khem Raj Rai</title>
    <description>The latest articles on DEV Community by Khem Raj Rai (@justkhem).</description>
    <link>https://dev.to/justkhem</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%2F4048065%2F4c4ddc84-215a-466b-8f69-f79c5fbb086f.PNG</url>
      <title>DEV Community: Khem Raj Rai</title>
      <link>https://dev.to/justkhem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/justkhem"/>
    <language>en</language>
    <item>
      <title>5 JSON-to-C# conversion mistakes generated models can hide</title>
      <dc:creator>Khem Raj Rai</dc:creator>
      <pubDate>Wed, 05 Aug 2026 01:56:02 +0000</pubDate>
      <link>https://dev.to/justkhem/5-json-to-c-conversion-mistakes-generated-models-can-hide-569f</link>
      <guid>https://dev.to/justkhem/5-json-to-c-conversion-mistakes-generated-models-can-hide-569f</guid>
      <description>&lt;p&gt;JSON-to-C# generators are useful for removing boilerplate, but their output is a starting point - not a schema.&lt;/p&gt;

&lt;p&gt;Before shipping generated models, I review five things:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Missing property vs explicit null
&lt;/h2&gt;

&lt;p&gt;A missing JSON property and a property whose value is &lt;code&gt;null&lt;/code&gt; can mean different things. The generated C# model should reflect whether the field is required, nullable, or optional in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Integers that may outgrow Int32
&lt;/h2&gt;

&lt;p&gt;A sample value of &lt;code&gt;42&lt;/code&gt; does not prove the field will always fit in &lt;code&gt;int&lt;/code&gt;. Identifiers, counters, and timestamps may need &lt;code&gt;long&lt;/code&gt;, &lt;code&gt;decimal&lt;/code&gt;, or even &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Strings with stronger domain types
&lt;/h2&gt;

&lt;p&gt;Values such as ISO timestamps, UUIDs, and money often arrive as strings. Consider &lt;code&gt;DateTimeOffset&lt;/code&gt;, &lt;code&gt;Guid&lt;/code&gt;, or &lt;code&gt;decimal&lt;/code&gt; when the contract supports it.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Empty arrays reveal no element type
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;[]&lt;/code&gt; gives a converter no evidence about the collection's contents. Add a representative item before generating, or review the inferred fallback type.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Record vs class semantics
&lt;/h2&gt;

&lt;p&gt;Records are useful for value-oriented data transfer models. Classes are often a better fit when identity, mutation, or framework behavior matters.&lt;/p&gt;

&lt;p&gt;I built DevCrate's JSON to C# converter to make the first pass fast and private. Conversion happens locally in the browser, so the JSON is not sent to a conversion API:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcrate.org/tools/json-to-csharp/" rel="noopener noreferrer"&gt;https://devcrate.org/tools/json-to-csharp/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generated code still deserves a human review.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>json</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
    <item>
      <title>What “Client-Side” Privacy Actually Means for Developer Tools</title>
      <dc:creator>Khem Raj Rai</dc:creator>
      <pubDate>Sun, 02 Aug 2026 13:29:06 +0000</pubDate>
      <link>https://dev.to/justkhem/what-client-side-privacy-actually-means-for-developer-tools-3k8c</link>
      <guid>https://dev.to/justkhem/what-client-side-privacy-actually-means-for-developer-tools-3k8c</guid>
      <description>&lt;p&gt;When a developer pastes a JWT, API request, or private JSON document into a utility, “client-side” sounds reassuring. But it is important to understand exactly what that promise covers.&lt;/p&gt;

&lt;p&gt;There are two separate data flows involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Processing the tool input
&lt;/h2&gt;

&lt;p&gt;A genuinely client-side utility parses and transforms the user’s input inside the browser. The input is not submitted to an API, stored in a database, or sent to an analytics service.&lt;/p&gt;

&lt;p&gt;For example, a browser can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parse JSON using &lt;code&gt;JSON.parse()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Generate hashes with the Web Crypto API&lt;/li&gt;
&lt;li&gt;Generate identifiers with &lt;code&gt;crypto.randomUUID()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Decode Base64URL data locally&lt;/li&gt;
&lt;li&gt;Convert structured data using JavaScript running on the device&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the privacy benefit developers usually care about: their tokens, payloads, and source data never need to leave the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Loading the website
&lt;/h2&gt;

&lt;p&gt;A client-side tool is still a website. On the first visit, the browser normally requests HTML, JavaScript, fonts, and other files from a hosting provider or CDN.&lt;/p&gt;

&lt;p&gt;That infrastructure may receive ordinary request information such as the IP address, requested page, browser type, and request time. Therefore, “tool inputs never leave your browser” is usually more accurate than claiming “zero server logs” unless the entire hosting configuration has been independently verified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better privacy language
&lt;/h2&gt;

&lt;p&gt;A trustworthy developer tool should make concrete, testable statements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tool inputs are never transmitted to a processing server.&lt;/li&gt;
&lt;li&gt;Conversion happens locally in the browser.&lt;/li&gt;
&lt;li&gt;Inputs and results are not intentionally persisted.&lt;/li&gt;
&lt;li&gt;Clear controls are provided for sensitive data.&lt;/li&gt;
&lt;li&gt;Offline support applies after the required application files have been cached.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These claims tell users what actually happens without overpromising.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy also requires good UX
&lt;/h2&gt;

&lt;p&gt;Implementation alone is not enough. A privacy-focused tool should also provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visible Clear buttons&lt;/li&gt;
&lt;li&gt;No automatic input history&lt;/li&gt;
&lt;li&gt;Warnings when a decoder does not verify cryptographic signatures&lt;/li&gt;
&lt;li&gt;Honest explanations of hosting and offline behavior&lt;/li&gt;
&lt;li&gt;Useful functionality without requiring an account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I applied these principles while building &lt;a href="https://devcrate.org" rel="noopener noreferrer"&gt;DevCrate&lt;/a&gt;, a collection of browser-only developer utilities. Its converters, JWT inspector, hashing tools, and UUID generator run locally without sending tool inputs to a processing API.&lt;/p&gt;

&lt;p&gt;Client-side architecture is not a magic privacy label. It is a specific technical design decision—and the clearest products explain exactly what it protects.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I used AI assistance while editing this article and developing portions of the project. I reviewed the final text and technical claims.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>privacy</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>JWT Decoding Is Not Verification: The Checks That Actually Matter</title>
      <dc:creator>Khem Raj Rai</dc:creator>
      <pubDate>Thu, 30 Jul 2026 09:45:04 +0000</pubDate>
      <link>https://dev.to/justkhem/jwt-decoding-is-not-verification-the-checks-that-actually-matter-3g90</link>
      <guid>https://dev.to/justkhem/jwt-decoding-is-not-verification-the-checks-that-actually-matter-3g90</guid>
      <description>&lt;p&gt;A JWT decoder can make a token readable, but it cannot tell you whether the token should be trusted.&lt;/p&gt;

&lt;p&gt;A JSON Web Token usually has three dot-separated parts: a header, a payload, and a signature. Decoding Base64URL turns the first two parts into readable JSON. That is useful for debugging, but it proves nothing about who created the token or whether it was modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  What verification must check
&lt;/h2&gt;

&lt;p&gt;A secure verifier should do all of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify the signature using the issuer's expected key.&lt;/li&gt;
&lt;li&gt;Enforce an allowed algorithm instead of trusting the token's &lt;strong&gt;alg&lt;/strong&gt; field blindly.&lt;/li&gt;
&lt;li&gt;Validate &lt;strong&gt;exp&lt;/strong&gt; and reject expired tokens.&lt;/li&gt;
&lt;li&gt;Validate &lt;strong&gt;nbf&lt;/strong&gt; before accepting a token that is not active yet.&lt;/li&gt;
&lt;li&gt;Match &lt;strong&gt;iss&lt;/strong&gt; to the expected issuer.&lt;/li&gt;
&lt;li&gt;Match &lt;strong&gt;aud&lt;/strong&gt; to the service receiving the token.&lt;/li&gt;
&lt;li&gt;Apply a small, deliberate clock-skew allowance when appropriate.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A token can contain perfectly readable claims and still be forged, expired, or intended for a different API.&lt;/p&gt;

&lt;h2&gt;
  
  
  A safer debugging habit
&lt;/h2&gt;

&lt;p&gt;Use decoding only to inspect structure and claims. Treat everything you see as untrusted until your application verifies the signature and validates the relevant claims with a maintained JWT library.&lt;/p&gt;

&lt;p&gt;This is also why developer tools should avoid showing a vague green "valid" state after decoding. Readable is not the same as verified.&lt;/p&gt;

&lt;p&gt;I built the browser-only JWT inspector in DevCrate with that distinction in the interface. Decoding runs locally, and the result explicitly says that the signature has not been verified.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcrate.org/tools/jwt/" rel="noopener noreferrer"&gt;Try the DevCrate JWT inspector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What JWT validation mistake have you seen most often in real projects?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>JSON to C# Converter: Generate Classes and Records Safely</title>
      <dc:creator>Khem Raj Rai</dc:creator>
      <pubDate>Sun, 26 Jul 2026 15:11:16 +0000</pubDate>
      <link>https://dev.to/justkhem/json-to-c-converter-generate-classes-and-records-safely-48np</link>
      <guid>https://dev.to/justkhem/json-to-c-converter-generate-classes-and-records-safely-48np</guid>
      <description>&lt;p&gt;Turning an API response into a usable C# model looks simple until the JSON contains nested objects, arrays, nullable values, or inconsistent data types. A converter can remove the repetitive typing, but the generated result should be treated as a strong starting point—not a substitute for reviewing the contract your application actually expects.&lt;/p&gt;

&lt;p&gt;This guide shows how JSON maps to C# classes and records, what to check after generation, and how to do the conversion without uploading private payloads to a processing server.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small JSON-to-C# example
&lt;/h2&gt;

&lt;p&gt;Suppose an API returns this product object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mechanical Keyboard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;129.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inStock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hardware"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"keyboards"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"vendor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Northwind Devices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JP"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A class-oriented model might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&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;long&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;Title&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;double&lt;/span&gt; &lt;span class="n"&gt;Price&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;bool&lt;/span&gt; &lt;span class="n"&gt;InStock&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="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Tags&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="n"&gt;Vendor&lt;/span&gt; &lt;span class="n"&gt;Vendor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vendor&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;Country&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;p&gt;A record-oriented version can express the same shape more compactly:&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;sealed&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;InStock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Vendor&lt;/span&gt; &lt;span class="n"&gt;Vendor&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Vendor&lt;/span&gt;&lt;span class="p"&gt;(&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="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both are valid starting points. The better choice depends on how the model will be created, mutated, compared, and serialized in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to convert JSON to C
&lt;/h2&gt;

&lt;p&gt;You can test the process with the free &lt;a href="https://devcrate.org/tools/json-to-csharp/" rel="noopener noreferrer"&gt;JSON to C# converter in DevCrate&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the converter and load the sample, or paste a valid JSON object.&lt;/li&gt;
&lt;li&gt;Review the generated model on the right as the input changes.&lt;/li&gt;
&lt;li&gt;Choose the C# style that matches your project: records for concise data-focused models, or classes with getters and setters for mutable models.&lt;/li&gt;
&lt;li&gt;Copy the result into your project.&lt;/li&gt;
&lt;li&gt;Review nullability, numeric precision, naming, collection types, and serializer behavior before shipping it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The conversion runs in the browser. The JSON is parsed locally and is not sent to a DevCrate processing API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typical JSON-to-C# type mappings
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;JSON value&lt;/th&gt;
&lt;th&gt;Common C# type&lt;/th&gt;
&lt;th&gt;What to verify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Could it really be a date, URI, GUID, or enum?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Whole number&lt;/td&gt;
&lt;td&gt;int or long&lt;/td&gt;
&lt;td&gt;Can it exceed the 32-bit integer range?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decimal number&lt;/td&gt;
&lt;td&gt;double or decimal&lt;/td&gt;
&lt;td&gt;Use decimal when exact financial precision matters.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;Confirm null is not also permitted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object&lt;/td&gt;
&lt;td&gt;Nested class or record&lt;/td&gt;
&lt;td&gt;Check naming and reuse across the schema.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array&lt;/td&gt;
&lt;td&gt;List, T[], or IReadOnlyList&lt;/td&gt;
&lt;td&gt;Empty arrays do not reveal their element type.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Null&lt;/td&gt;
&lt;td&gt;Nullable reference/value type&lt;/td&gt;
&lt;td&gt;One sample cannot prove the full contract.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Type inference is based on the values present in the sample. That limitation matters: a single payload cannot reveal every possible response the API may produce.&lt;/p&gt;

&lt;h2&gt;
  
  
  C# records versus classes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Choose a record when
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;the object represents data rather than long-lived mutable state;&lt;/li&gt;
&lt;li&gt;value-based equality is useful;&lt;/li&gt;
&lt;li&gt;concise construction and pattern matching improve the code;&lt;/li&gt;
&lt;li&gt;properties should normally be initialized rather than repeatedly changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Records are especially comfortable for DTOs, messages, query results, and configuration snapshots. Positional records are concise, while records with named properties may be easier to decorate with serializer attributes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose a class when
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;the object is mutable through its lifetime;&lt;/li&gt;
&lt;li&gt;a framework expects a parameterless constructor and writable properties;&lt;/li&gt;
&lt;li&gt;identity matters more than value equality;&lt;/li&gt;
&lt;li&gt;the model contains behavior in addition to data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Classes with &lt;strong&gt;get; set;&lt;/strong&gt; remain a practical default for many Entity Framework models, form-binding scenarios, and older serialization conventions. Modern System.Text.Json supports both patterns, but constructor names, access modifiers, and attributes still deserve a quick review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five things to review after generation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Nullable values
&lt;/h3&gt;

&lt;p&gt;If a sample contains a string today, the API may still return null tomorrow. With nullable reference types enabled, decide whether a field should be &lt;strong&gt;string&lt;/strong&gt;, &lt;strong&gt;string?&lt;/strong&gt;, or initialized with a safe default. The API contract or JSON Schema is more reliable than one observed payload.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Money and numeric precision
&lt;/h3&gt;

&lt;p&gt;A converter may infer &lt;strong&gt;double&lt;/strong&gt; from a decimal-looking JSON number. For prices, rates, and financial totals, &lt;strong&gt;decimal&lt;/strong&gt; is often the safer domain type because binary floating-point cannot represent every base-10 value exactly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dates and identifiers
&lt;/h3&gt;

&lt;p&gt;Values such as 2026-07-27T08:30:00Z and UUID-shaped strings are still JSON strings. In C#, you may want &lt;strong&gt;DateTimeOffset&lt;/strong&gt;, &lt;strong&gt;DateOnly&lt;/strong&gt;, &lt;strong&gt;Uri&lt;/strong&gt;, or &lt;strong&gt;Guid&lt;/strong&gt; after confirming the producer's format and validation rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Property names and serializer configuration
&lt;/h3&gt;

&lt;p&gt;C# commonly uses PascalCase, while JSON often uses camelCase or snake_case. System.Text.Json can handle camelCase through naming policies. For irregular names, add &lt;strong&gt;JsonPropertyName&lt;/strong&gt; attributes rather than silently changing the wire contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Arrays and inconsistent objects
&lt;/h3&gt;

&lt;p&gt;An empty array gives a converter no evidence about its item type. Arrays containing objects with different fields can also produce an incomplete model. Test with a representative payload, then compare the result with the API documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why local conversion is useful
&lt;/h2&gt;

&lt;p&gt;Real JSON often contains customer details, internal URLs, access claims, or business data. A server-based converter may be trustworthy, but sending the payload creates another system that could log, retain, or expose it.&lt;/p&gt;

&lt;p&gt;With a browser-only converter, avoiding the processing request entirely creates a simpler privacy boundary. You should still inspect any site and avoid pasting active credentials, but local execution is preferable when the task does not require a server.&lt;/p&gt;

&lt;p&gt;DevCrate is statically hosted and documents its privacy boundary clearly: the converter performs its parsing and code generation in the browser, and tool inputs are not sent to a conversion API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical takeaway
&lt;/h2&gt;

&lt;p&gt;A JSON-to-C# generator is best used to remove boilerplate, then followed by a short engineering review. Check nullability, precision, collection choices, serializer settings, and the difference between the sample and the real API contract.&lt;/p&gt;

&lt;p&gt;Try the &lt;a href="https://devcrate.org/tools/json-to-csharp/" rel="noopener noreferrer"&gt;JSON to C# converter&lt;/a&gt; with generated or non-sensitive sample data. If you find a payload that produces an awkward model, that edge case is useful feedback—the goal is correct, reviewable code rather than blind one-click generation.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>json</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why Developer Utilities Should Process Sensitive Data in Your Browser</title>
      <dc:creator>Khem Raj Rai</dc:creator>
      <pubDate>Sun, 26 Jul 2026 14:45:14 +0000</pubDate>
      <link>https://dev.to/justkhem/why-developer-utilities-should-process-sensitive-data-in-your-browser-2h6h</link>
      <guid>https://dev.to/justkhem/why-developer-utilities-should-process-sensitive-data-in-your-browser-2h6h</guid>
      <description>&lt;p&gt;Developers paste surprisingly sensitive information into online utilities every day: API responses, access tokens, database records, cURL commands, and configuration fragments. A formatter or converter may look harmless, but the input can still contain customer data, internal URLs, credentials, or claims that were never meant to leave a local machine.&lt;/p&gt;

&lt;p&gt;That is why I built &lt;a href="https://devcrate.org" rel="noopener noreferrer"&gt;DevCrate&lt;/a&gt;: a privacy-first collection of developer utilities where the conversion work happens in the browser instead of a processing API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hidden risk in convenient online tools
&lt;/h2&gt;

&lt;p&gt;A typical online converter can send your input to a remote server before returning the formatted result. The site may be legitimate, but a developer often cannot verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;whether the payload is logged;&lt;/li&gt;
&lt;li&gt;how long request data is retained;&lt;/li&gt;
&lt;li&gt;which analytics or third-party scripts can observe the page;&lt;/li&gt;
&lt;li&gt;whether an error-reporting service captures the input;&lt;/li&gt;
&lt;li&gt;who controls the infrastructure later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even when a tool promises not to store data, avoiding the request entirely is a stronger privacy boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What browser-only processing changes
&lt;/h2&gt;

&lt;p&gt;A client-side utility downloads its application code and runs the transformation locally. Parsing JSON, generating UUIDs, decoding Base64URL segments, and converting cURL commands do not inherently require a server.&lt;/p&gt;

&lt;p&gt;DevCrate is statically exported and uses browser APIs or local application logic for its tools. The current collection includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON to TypeScript, C#, Kotlin, and SQL;&lt;/li&gt;
&lt;li&gt;JSON to Shopify CSV;&lt;/li&gt;
&lt;li&gt;cURL to JavaScript Fetch, Python Requests, and C# HttpClient;&lt;/li&gt;
&lt;li&gt;JWT inspection;&lt;/li&gt;
&lt;li&gt;Base64 encoding and decoding;&lt;/li&gt;
&lt;li&gt;hashing and UUID generation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DevCrate is statically hosted, and its privacy boundary is documented on the site: tool inputs are processed in browser memory and are not sent to a conversion API.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT decoding is not JWT verification
&lt;/h2&gt;

&lt;p&gt;This distinction is important. A JWT decoder can parse the token header and payload locally, but readable claims are not proof that the token is authentic.&lt;/p&gt;

&lt;p&gt;Signature verification requires the expected algorithm and the correct issuer key. Until that verification succeeds, an attacker can modify the claims and produce a token that still decodes normally.&lt;/p&gt;

&lt;p&gt;A safe decoder should therefore:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;label the output as unverified;&lt;/li&gt;
&lt;li&gt;avoid uploading the token;&lt;/li&gt;
&lt;li&gt;distinguish issued-at and expiry timestamps clearly;&lt;/li&gt;
&lt;li&gt;remind users to verify signatures in the application that trusts the token.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Base64 is not encryption
&lt;/h2&gt;

&lt;p&gt;Base64 is an encoding format. Anyone who receives the encoded value can reverse it without a password or key. It is useful for transporting binary data in text systems, but it should never be presented as a security control.&lt;/p&gt;

&lt;p&gt;Hashing also needs context. Modern browser cryptography can generate SHA-family hashes locally, while MD5 support is mainly useful for compatibility checks and legacy systems—not for password storage or security-sensitive integrity guarantees.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static architecture has practical benefits
&lt;/h2&gt;

&lt;p&gt;Keeping utility processing on the client creates several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no processing server to operate or scale;&lt;/li&gt;
&lt;li&gt;fewer places where user payloads can be retained;&lt;/li&gt;
&lt;li&gt;fast feedback while typing or pasting;&lt;/li&gt;
&lt;li&gt;easier static hosting;&lt;/li&gt;
&lt;li&gt;the potential to keep working after application assets have been cached by a supported browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also creates responsibilities. Browser code still needs dependency review, a careful content-security policy, transparent analytics choices, and accurate language around what “local” actually covers. External links, hosting requests, and optional analytics are different from sending tool input to a conversion endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  UX matters too
&lt;/h2&gt;

&lt;p&gt;Privacy alone is not enough if the tool is frustrating. Developer utilities should be fast to navigate, usable without a mouse, and honest when input is invalid.&lt;/p&gt;

&lt;p&gt;DevCrate uses a global Cmd/Ctrl+K palette, live conversion, explicit error states, copy and download actions, and sample inputs that let visitors test tools without exposing real data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it with sample data
&lt;/h2&gt;

&lt;p&gt;You can explore the tools at &lt;a href="https://devcrate.org" rel="noopener noreferrer"&gt;devcrate.org&lt;/a&gt;. Start with generated or non-sensitive sample data, and inspect the browser's network activity if you want to verify the behavior.&lt;/p&gt;

&lt;p&gt;I would especially value feedback on converter correctness, missing utilities, keyboard accessibility, and any privacy wording that feels unclear. The goal is not to ask developers for blind trust—it is to make the design easier to verify.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
