HTTP Methods Reference — C# source
A searchable reference for every HTTP request method - GET, POST, PUT, PATCH, DELETE, and more. See at a glance which are safe, idempotent, and cacheable, then compare any two methods side by side.
This is the C# implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Source: csharp.cs
// Language: C# (C# 12, .NET Base Class Library only)
//
// HTTP request-method reference — pure, deterministic data + lookups.
//
// CosmoDev polyglot showcase port of the `http-methods` tool, ported from
// src/lib/http-methods.ts. Functionally equivalent to the TypeScript original:
// identical inputs yield identical outputs (case-insensitive lookup, flag +
// free-text filtering, and a human-readable semantic comparison report).
//
// Property flags (safe / idempotent / cacheable / hasBody) follow RFC 9110
// and the MDN reference table.
//
// License: display source — part of CosmoDev's polyglot tool pages.
using System;
using System.Collections.Generic;
using System.Linq;
namespace CosmoDev;
/// <summary>One HTTP request method and its semantic properties.</summary>
public sealed record MethodEntry(
string Method, // Uppercase method name, e.g. "GET".
bool Safe, // Read-only semantics — no server state change.
bool Idempotent, // Repeating the call has the same effect as a single call.
bool Cacheable, // Responses may be stored by a cache (RFC 9110 / MDN).
bool HasBody, // The method conventionally carries a request body.
string Description,
string TypicalUse);
/// <summary>HTTP request-method reference — pure data + lookups.</summary>
public static class HttpMethods
{
/// <summary>The nine HTTP request methods (RFC 9110 / 9111), in canonical order.
/// A readonly table is the single source of truth the helpers hand out references into.</summary>
public static readonly IReadOnlyList<MethodEntry> Methods =
[
new MethodEntry("GET", true, true, true, false,
"Retrieves a representation of the target resource; a read-only request.",
"Fetching a web page, reading an API resource, loading an image."),
new MethodEntry("POST", false, false, true, true,
"Submits data to be processed, typically creating a new resource or triggering an action.",
"Submitting a form, creating a record, publishing a message."),
new MethodEntry("PUT", false, true, false, true,
"Replaces the target resource entirely with the request body.",
"Updating a full record at a known URL, uploading a file by its path."),
new MethodEntry("PATCH", false, false, false, true,
"Applies a partial modification to the target resource.",
"Updating one field of a record, toggling a flag."),
new MethodEntry("DELETE", false, true, false, false,
"Removes the target resource.",
"Deleting a record or file by its URL."),
new MethodEntry("HEAD", true, true, true, false,
"Identical to GET but returns only the response headers, no body.",
"Checking existence, size, or freshness before downloading."),
new MethodEntry("OPTIONS", true, true, false, false,
"Describes the communication options for the target resource.",
"CORS preflight requests, discovering allowed methods."),
new MethodEntry("CONNECT", false, false, false, false,
"Establishes a tunnel to the server (used with TLS/HTTPS proxies).",
"Proxying encrypted connections through an intermediary."),
new MethodEntry("TRACE", true, true, false, false,
"Performs a message loop-back test along the path to the target (debugging only).",
"Diagnosing request transformations by intermediaries."),
];
/// <summary>Narrowing options for <see cref="FilterMethods"/>.</summary>
/// <remarks>Each boolean is <c>bool?</c> so callers can distinguish "constrain
/// to <see langword="false"/>" from "no constraint" — a tri-state a bare
/// <see langword="bool"/> cannot express. <c>null</c> (the default) means
/// no constraint. <paramref name="Query"/> is free text matched
/// case-insensitively against method, description, and typical use;
/// ignored when empty after trimming.</remarks>
public sealed record MethodFilter(
bool? Safe = null,
bool? Idempotent = null,
bool? Cacheable = null,
string? Query = null);
/// <summary>Case-insensitive single-method lookup.</summary>
/// <returns>The canonical entry, or <see langword="null"/> when unknown —
/// the C# analogue of TS's <c>MethodEntry | null</c>.</returns>
public static MethodEntry? GetMethod(string name)
{
string n = name.Trim().ToUpperInvariant();
return Methods.FirstOrDefault(m => m.Method == n);
}
/// <summary>Returns the methods satisfying every present flag and, when
/// <c>Query</c> is non-empty after trimming, matching it in at least one
/// of {method, description, typical use}.</summary>
public static IReadOnlyList<MethodEntry> FilterMethods(MethodFilter? opts = null)
{
opts ??= new MethodFilter();
string q = (opts.Query ?? "").Trim().ToLowerInvariant();
return Methods.Where(m =>
{
// Each present flag is an AND constraint; null means skip.
if (opts.Safe is bool wantSafe && m.Safe != wantSafe) return false;
if (opts.Idempotent is bool wantIdempotent && m.Idempotent != wantIdempotent) return false;
if (opts.Cacheable is bool wantCacheable && m.Cacheable != wantCacheable) return false;
if (q.Length == 0) return true;
return m.Method.Contains(q, StringComparison.OrdinalIgnoreCase)
|| m.Description.Contains(q, StringComparison.OrdinalIgnoreCase)
|| m.TypicalUse.Contains(q, StringComparison.OrdinalIgnoreCase);
}).ToList();
}
/// <summary>Semantic diff between two methods.</summary>
public sealed record MethodComparison(
bool SameSafety, // Both methods share the `safe` flag.
bool SameIdempotence, // Both methods share the `idempotent` flag.
IReadOnlyList<string> Differences); // One sentence per mismatched property.
/// <summary>Surfaces where two methods' semantics agree and differ.</summary>
/// <remarks><c>Differences</c> lists every mismatched property (safe,
/// idempotent, cacheable, hasBody) as a human-readable sentence,
/// reproducing the canonical phrasing verbatim so output stays identical
/// to the TypeScript original and the other polyglot ports.</remarks>
public static MethodComparison CompareMethods(MethodEntry a, MethodEntry b)
{
List<string> differences = [];
if (a.Safe != b.Safe)
{
differences.Add($"{a.Method} is {SafeWord(a.Safe)}, {b.Method} is {SafeWord(b.Safe)}.");
}
if (a.Idempotent != b.Idempotent)
{
differences.Add($"{a.Method} is {IdempotentWord(a.Idempotent)}, {b.Method} is {IdempotentWord(b.Idempotent)}.");
}
if (a.Cacheable != b.Cacheable)
{
differences.Add($"{a.Method} is {CacheableWord(a.Cacheable)}, {b.Method} is {CacheableWord(b.Cacheable)}.");
}
if (a.HasBody != b.HasBody)
{
differences.Add($"{a.Method} {BodyWord(a.HasBody)}, {b.Method} {BodyWord(b.HasBody)}.");
}
return new MethodComparison(a.Safe == b.Safe, a.Idempotent == b.Idempotent, differences);
}
// Phrasing helpers keep the difference-sentence wording in one place, so
// the output stays in lock-step across every polyglot port.
private static string SafeWord(bool v) => v ? "safe" : "not safe";
private static string IdempotentWord(bool v) => v ? "idempotent" : "not idempotent";
private static string CacheableWord(bool v) => v ? "cacheable" : "not cacheable";
private static string BodyWord(bool v) => v ? "takes a body" : "does not take a body";
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →