Generate UUID (GUID) in C#
System.Guid.NewGuid() is built into .NET — zero dependencies, returns a 16-byte value type. .NET 9 adds Guid.CreateVersion7() for time-ordered UUIDs natively.
Quick Reference
| Method | Version | Sortable | Use Case |
|---|---|---|---|
| Guid.NewGuid() | v4 | No | General purpose — session IDs, record IDs, API keys |
| Guid.CreateVersion7() | v7 | Yes | .NET 9+ — time-ordered, database PKs |
| Guid.Parse() | any | — | Parse — throws on invalid input |
| Guid.TryParse() | any | — | Safe parse — returns bool, no exception |
Primary Implementation
// No using statements needed — System.Guid is in the global namespace
// Generate a GUID (UUID v4) — CSPRNG-backed, zero dependencies
Guid id = Guid.NewGuid();
Console.WriteLine(id);
// → f47ac10b-58cc-4372-a567-0e02b2c3d479
// Format specifiers
string standard = id.ToString(); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
string noHyphens = id.ToString("N"); // "f47ac10b58cc4372a5670e02b2c3d479"
string braces = id.ToString("B"); // "{f47ac10b-58cc-4372-a567-0e02b2c3d479}"
string parens = id.ToString("P"); // "(f47ac10b-58cc-4372-a567-0e02b2c3d479)"
// Parse — throws FormatException on invalid input
Guid parsed = Guid.Parse("f47ac10b-58cc-4372-a567-0e02b2c3d479");
// Safe parse — no exception
if (Guid.TryParse("f47ac10b-58cc-4372-a567-0e02b2c3d479", out Guid result))
{
Console.WriteLine($"Parsed: {result}");
}
// Check for empty/null GUID
if (id == Guid.Empty)
{
Console.WriteLine("ID is empty");
}
// Generate multiple
var ids = Enumerable.Range(0, 5).Select(_ => Guid.NewGuid()).ToList();
All UUID Versions
UUID v4 — Random (all .NET versions)
// Available in all .NET versions — zero dependencies Guid id = Guid.NewGuid(); Console.WriteLine(id.ToString()); // → "550e8400-e29b-41d4-a716-446655440000"
UUID v7 — Time-ordered (.NET 9+)
// .NET 9+ — built-in UUID v7 (time-ordered) // IDs generated later always sort after earlier ones Guid id = Guid.CreateVersion7(); Console.WriteLine(id.ToString()); // → "018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a" // With explicit timestamp Guid idWithTs = Guid.CreateVersion7(DateTimeOffset.UtcNow);
Format specifiers
Guid id = Guid.NewGuid();
// "D" (default) — with hyphens
Console.WriteLine(id.ToString("D")); // f47ac10b-58cc-4372-a567-0e02b2c3d479
// "N" — no hyphens (32 chars)
Console.WriteLine(id.ToString("N")); // f47ac10b58cc4372a5670e02b2c3d479
// "B" — with braces
Console.WriteLine(id.ToString("B")); // {f47ac10b-58cc-4372-a567-0e02b2c3d479}
// "X" — hex with 0x prefix components
Console.WriteLine(id.ToString("X")); // {0xf47ac10b,0x58cc,0x4372,{0xa5,0x67,...}}
Real-World Use Cases
1. ASP.NET Core middleware — request tracing
public class RequestIdMiddleware
{
private readonly RequestDelegate _next;
public RequestIdMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var requestId = Guid.NewGuid().ToString("N"); // no hyphens for headers
context.Items["RequestId"] = requestId;
context.Response.Headers["X-Request-ID"] = requestId;
await _next(context);
}
}
// Register in Program.cs:
// app.UseMiddleware<RequestIdMiddleware>();
2. EF Core entity with GUID primary key
using System.ComponentModel.DataAnnotations;
public class Order
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid(); // auto-assigned on creation
public string CustomerName { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
// EF Core automatically maps Guid to the native UUID/uniqueidentifier column type
3. Azure Service Bus message ID
using Azure.Messaging.ServiceBus;
var client = new ServiceBusClient(connectionString);
var sender = client.CreateSender("orders");
var message = new ServiceBusMessage(JsonSerializer.SerializeToUtf8Bytes(order))
{
MessageId = Guid.NewGuid().ToString(), // unique message ID
CorrelationId = correlationId,
ContentType = "application/json",
};
await sender.SendMessageAsync(message);
Common Mistakes
Calling ToString() without a format specifier
The default ToString() uses the "D" format (with hyphens, lowercase). Be explicit with the format specifier when the output format matters — e.g., ToString("N") for no hyphens.
Using null checks instead of Guid.Empty
Guid is a value type — it can never be null (unless wrapped in Guid?). Use id == Guid.Empty to check for an uninitialized GUID, not a null check.
Storing GUIDs as nvarchar(36) in SQL Server
SQL Server has a native uniqueidentifier type (16 bytes). EF Core maps Guid to it automatically. Using nvarchar(36) wastes space and loses index efficiency.
How It Works
Guid.NewGuid() calls the OS CSPRNG — BCryptGenRandom on Windows and /dev/urandom on Linux/macOS via .NET's platform abstraction layer.
Guid is a 16-byte value type (struct) stored on the stack. It implements IComparable, IEquatable, and IFormattable. Zero heap allocation per GUID.
Output Formats
ToString() / "D"
f47ac10b-58cc-4372-a567-0e02b2c3d479
"N" — no hyphens
f47ac10b58cc4372a5670e02b2c3d479
"B" — with braces
{f47ac10b-58cc-4372-a567-0e02b2c3d479}
Best Practices
Use Guid type in C# — only convert to string at API/DB boundaries.
Use Guid.TryParse() for user input — avoids exceptions on invalid strings.
On .NET 9+, use Guid.CreateVersion7() for database PKs — sequential inserts.
Performance
.NET generates roughly 10–20 million GUIDs/second. Guid is a 16-byte value type — stack-allocated, zero heap pressure per GUID.
The ToString() call allocates a string on the heap. For high-throughput scenarios, use TryFormat() with a Span<char> to avoid allocations.
Installation
// No installation needed — System.Guid
// is part of the .NET base class library
Available in all .NET versions (.NET Framework 1.1+, .NET Core, .NET 5+). Guid.CreateVersion7() requires .NET 9+.
Security
Entropy source: OS CSPRNG — BCryptGenRandom on Windows, /dev/urandom on Linux/macOS. Cryptographically secure.
Suitable for session tokens, CSRF tokens, and API keys. Guid.Empty (00000000-0000-0000-0000-000000000000) is not a valid random GUID — never use it as an ID.