Claude
Skills
Sign in
Back

dotnet-agent-gotchas

Included with Lifetime
$97 forever

Generating or modifying .NET code. Common agent mistakes: async, NuGet, deprecated APIs, DI.

AI Agents

What this skill does


# dotnet-agent-gotchas

## Overview / Scope Boundary

Common mistakes AI agents make when generating or modifying .NET code, organized by category. Each category provides a brief warning, anti-pattern code, corrected code, and a cross-reference to the canonical skill that owns the deep guidance. This skill does NOT provide full implementation walkthroughs -- it surfaces the mistake and points to the right skill.

**Out of scope:** Deep async/await patterns (owned by [skill:dotnet-csharp-async-patterns]), full dependency injection guidance (owned by [skill:dotnet-csharp-dependency-injection]), NRT usage patterns (owned by [skill:dotnet-csharp-nullable-reference-types]), source generator authoring (owned by [skill:dotnet-csharp-source-generators]), test framework features (owned by [skill:dotnet-testing-strategy]), security vulnerability mitigation (owned by [skill:dotnet-security-owasp]).

## Prerequisites

.NET 8.0+ SDK. Familiarity with SDK-style projects and C# language features.

Cross-references: [skill:dotnet-csharp-async-patterns], [skill:dotnet-csharp-dependency-injection], [skill:dotnet-csharp-nullable-reference-types], [skill:dotnet-csharp-source-generators], [skill:dotnet-testing-strategy], [skill:dotnet-security-owasp].

---

## Category 1: Async/Await Misuse

**Warning:** Agents frequently block on async methods using `.Result` or `.Wait()`, causing deadlocks in ASP.NET Core and UI contexts. Another common mistake is fire-and-forget calls that silently swallow exceptions.

### Anti-Pattern

```csharp
// WRONG: blocking on async -- deadlock risk in synchronization contexts
public Order GetOrder(int id)
{
    var order = _repository.GetOrderAsync(id).Result; // DEADLOCK
    return order;
}

// WRONG: fire-and-forget with no error handling
public void ProcessOrder(Order order)
{
    _ = _emailService.SendConfirmationAsync(order); // exception silently lost
}
```

### Corrected

```csharp
// CORRECT: async all the way
public async Task<Order> GetOrderAsync(int id, CancellationToken ct = default)
{
    var order = await _repository.GetOrderAsync(id, ct);
    return order;
}

// CORRECT: background work via IHostedService or explicit error handling
public async Task ProcessOrderAsync(Order order, CancellationToken ct = default)
{
    await _emailService.SendConfirmationAsync(order, ct);
}
```

See [skill:dotnet-csharp-async-patterns] for full async/await guidance including `ValueTask`, `ConfigureAwait`, and cancellation propagation.

---

## Category 2: NuGet Package Errors

**Warning:** Agents generate incorrect package names, reference pre-release versions without opt-in, or add packages that have been deprecated/replaced. ASP.NET Core shared-framework packages must match the project TFM major version.

### Anti-Pattern

```xml
<!-- WRONG: package name does not exist (correct: Microsoft.EntityFrameworkCore) -->
<PackageReference Include="EntityFrameworkCore" Version="9.0.0" />

<!-- WRONG: hardcoded version for shared-framework package -- must match TFM -->
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<!-- This breaks on net8.0 projects -->

<!-- WRONG: agents add Swashbuckle by default; .NET 9+ templates use built-in OpenAPI -->
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.0.0" />
<!-- Swashbuckle is still valid when Swagger UI is needed, but not the default choice -->
```

### Corrected

```xml
<!-- CORRECT: exact package ID -->
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />

<!-- CORRECT: use version variable or central package management to match TFM -->
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<!-- Version managed via Directory.Packages.props matching project TFM -->

<!-- CORRECT: .NET 9+ templates prefer built-in OpenAPI support -->
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<!-- Swashbuckle remains a valid choice when Swagger UI features are needed -->
```

See [skill:dotnet-csproj-reading] for project file conventions and central package management guidance.

---

## Category 3: Deprecated API Usage

**Warning:** Agents generate code using deprecated and insecure APIs: `BinaryFormatter` (CVE-prone deserialization), `WebClient` (replaced by `HttpClient`), and older cryptography APIs (`RNGCryptoServiceProvider`, `SHA1CryptoServiceProvider`).

### Anti-Pattern

```csharp
// WRONG: BinaryFormatter is banned in .NET 8+ (SYSLIB0011)
var formatter = new BinaryFormatter();
formatter.Serialize(stream, data);

// WRONG: WebClient is obsolete -- use HttpClient via IHttpClientFactory
var client = new WebClient();
var html = client.DownloadString("https://example.com");

// WRONG: obsolete crypto API (SYSLIB0023)
using var rng = new RNGCryptoServiceProvider();
rng.GetBytes(buffer);
```

### Corrected

```csharp
// CORRECT: use System.Text.Json for serialization
var json = JsonSerializer.Serialize(data);
await File.WriteAllTextAsync("data.json", json);

// CORRECT: use IHttpClientFactory (registered via DI)
public class MyService(HttpClient httpClient)
{
    public async Task<string> GetHtmlAsync(CancellationToken ct = default)
        => await httpClient.GetStringAsync("https://example.com", ct);
}

// CORRECT: modern RandomNumberGenerator (static API)
RandomNumberGenerator.Fill(buffer);
```

See [skill:dotnet-security-owasp] for the full deprecated security pattern catalog and OWASP mitigations.

---

## Category 4: Project Structure Mistakes

**Warning:** Agents use wrong SDK types, add `PackageReference` entries for framework-included libraries, or create broken `ProjectReference` paths.

### Anti-Pattern

```xml
<!-- WRONG: using Microsoft.NET.Sdk for a web project -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>
  <!-- Missing WebApplication APIs, Kestrel, etc. -->
</Project>

<!-- WRONG: referencing a package already in the shared framework -->
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
<!-- This is included in Microsoft.NET.Sdk.Web; explicit reference causes version conflicts -->

<!-- WRONG: relative path that doesn't match actual project location -->
<ProjectReference Include="..\..\Core\MyApp.Core.csproj" />
<!-- Actual location is ../MyApp.Core/MyApp.Core.csproj -->
```

### Corrected

```xml
<!-- CORRECT: use the Web SDK for ASP.NET Core projects -->
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>
</Project>

<!-- CORRECT: don't add explicit PackageReference for shared-framework packages -->
<!-- Microsoft.Extensions.Logging is implicitly available via Sdk.Web -->

<!-- CORRECT: verify the actual project path before adding a reference -->
<ProjectReference Include="..\MyApp.Core\MyApp.Core.csproj" />
```

See [skill:dotnet-project-structure] for SDK types, project organization, and project reference conventions.

---

## Category 5: Nullable Reference Type Annotation Errors

**Warning:** Agents misuse the null-forgiving operator (`!`) to silence warnings instead of fixing nullability, or forget to enable the nullable context.

### Anti-Pattern

```csharp
// WRONG: null-forgiving operator hides a real null risk
public string GetUserName(int id)
{
    var user = _db.Users.Find(id);
    return user!.Name; // NullReferenceException if user not found
}

// WRONG: nullable not enabled, so annotations are meaningless
// Missing <Nullable>enable</Nullable> in .csproj
public string? GetOptionalValue() => null; // no compiler warnings without nullable context
```

### Corrected

```csharp
// CORRECT: handle null explicitly
public string GetUserName(int id)
{
    var user = _db.Users.Find(id);
    if (user is null)
    {
        throw new InvalidOperationException($"User {id} not found.");
    }

    return user.Name;
}
```

```xml
<!-- CORRECT: enable nullable context in .csproj -->
<PropertyGroup>

Related in AI Agents