ASP.NET Core Web API の開発で「新しいフォルダーに置いたクラスを using で参照できない」——この現象は名前空間やプロジェクト設定、IDE のキャッシュのちょっとしたズレが重なったときに起きがちです。ここでは原因の切り分けから最短の解決手順、再発防止までを実務視点でまとめます。VS 2022 かつ .NET 6/7/8/9 いずれでも有効です。
現象の概要
- Visual Studio 2022 の ASP.NET Core Web API プロジェクトで、プロジェクトに新規フォルダーを追加しても、その配下のクラスを
using MyProject.Modelsのように参照できない。 - 古いプロジェクト/新規プロジェクトのどちらでも再現する場合がある。
- フォルダーを「除外→再追加」や「クリーン→リビルド」をしても改善しないことがある。
最短で理解する結論
フォルダー=名前空間ではありません。 フォルダーを作っても、既存ファイルの namespace は自動では変わりません。さらに SDK スタイルの既定では フォルダー配下のすべての .cs をビルド対象に含めます が、設定や一部の操作によって「含めない」状態になることがあります。最初に 名前空間の修正 と .csproj の包含設定 を確認し、次に IDE キャッシュ を疑うのが近道です。
原因と仕組み
名前空間の不一致(最頻出)
次のような状況で using が効かなくなります。
- OS のエクスプローラーでファイルを移動した(VS 上で移動していない)。
- テンプレートやコピー元の
namespaceをそのまま使っている。 - チーム内でルート名前空間が変更されたが、旧ファイルが未追随。
例えば、MyProject/Models/User.cs に置いたのに、ファイルの先頭が次のようになっているケースです。
// 誤り(別プロジェクト由来のまま)
namespace OtherProject.Models;
public sealed class User { /* ... */ }
この場合、コントローラから using MyProject.Models; を追加しても型は見つかりません。修正後は次のようにします。
// 正しい(フォルダー構成と合わせるのが定石)
namespace MyProject.Models;
public sealed class User { /* ... */ }
C# 10 以降のファイル スコープ名前空間(末尾にセミコロン)でも同様です。
namespace MyProject.Models;
public sealed record WeatherForecast(int Id, string Summary);
また、最小 API(Program.cs にエンドポイント直書き)のプロジェクトでは、次のように using を書けば直ちに解決するかを検証できます。
using MyProject.Models;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/forecast", () => new WeatherForecast(1, "Sunny"));
app.Run();
.csproj のインクルード漏れ/除外設定
SDK スタイル(<Project Sdk="Microsoft.NET.Sdk.Web">)では、通常 **\*.cs が自動的にビルド対象になります(Default Compile Items)。しかし次のような設定が入っていると、フォルダー配下がコンパイルされません。
<Compile Remove="Models\**\*.cs" />が存在する。<EnableDefaultItems>false</EnableDefaultItems>または<EnableDefaultCompileItems>false</EnableDefaultCompileItems>を明示している。- 上位ディレクトリの
Directory.Build.props/Directory.Build.targetsでCompileを上書きしている。 global.jsonにより古い SDK を強制していて挙動が異なる。
プロジェクトの実例です。次の Remove 行があると Models 配下がビルドされません。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
修正は次のいずれかです。
Removeを削除する。- やむを得ない場合は個別に
<Compile Include="Models\*.cs" />を定義する。
IDE/環境キャッシュの破損
VS のキャッシュ破損や拡張機能の干渉で「新規プロジェクトでも再現」することがあります。兆候としては以下です。
- ソリューションを跨いで IntelliSense が全面的に壊れている。
- ビルドは成功するのにエディタだけ赤波線が消えない。
- 新規テンプレートから作っても同じ症状。
対処は段階的に行います。
- VS を終了し、
.vsフォルダー(ソリューション直下)、%LocalAppData%\Microsoft\VisualStudio\17.0_xxx\ComponentModelCacheを削除。 - 一時的に拡張機能(例:ReSharper)を無効化。
- VS の設定をリセット(ツール → 設定のインポートとエクスポート → すべてリセット)。
- 「修復」インストール、最終手段として「再インストール」。
その他の落とし穴
- 型名の衝突:同名の型が複数の名前空間に存在すると
CS0104(曖昧)が出ます。global::MyProject.Models.Userのように完全修飾で一時回避し、設計を見直します。 - Global Usings の勘違い:
<ImplicitUsings>enable</ImplicitUsings>は BCL の主要名前空間を暗黙usingするだけで、自分のプロジェクトのMyProject.Modelsを暗黙化するものではありません。自前でGlobalUsings.csを用意すれば共通化可能です。 - 物理パスがプロジェクト外:エクスプローラーで外側に作ったフォルダーを VS から見えているだけ、というケース。既存項目の追加またはドラッグ&ドロップでプロジェクトに取り込みます。
- .gitignore の影響:
*.csを誤って無視していると CI ではビルドできないことがあります。ローカルは動いても、CI で「見つからない」エラーに繋がります。
解決の推奨フロー(実務での定石)
| 手順 | 内容 | 補足 |
|---|---|---|
| ① 名前空間を確認・修正 | 追加フォルダー内の各 .cs を開き、namespace MyProject.Models; のように正しい名前空間へ修正。 | C# 10+ のファイル スコープ名前空間推奨。VS の「名前空間の同期」リファクタリングも有用。 |
| ② .csproj を確認 | プロジェクト右クリック → プロジェクト ファイルの編集。<Compile Remove="..." /> や EnableDefaultItems を確認し、必要なら <Compile Include="Models\*.cs" /> を追記。 | 手動でフォルダー移動・上位の Directory.Build.props の影響に注意。 |
| ③ クリーン → リビルド | ビルド > ソリューションのクリーン → ソリューションの再ビルド。CLI は dotnet clean → dotnet build -v:diag。 | MSBuild 出力を「診断」にすると包含状況がログで分かる。 |
| ④ フォルダー位置の確認 | 物理パスが MyProject/Models 直下かを確認。外部にある場合は「既存項目の追加」で取り込む。 | SDK スタイルはサブフォルダーなら自動包含が原則。 |
| ⑤ 新規ファイルでテスト | 問題のフォルダー配下に 追加 > クラス。自動生成される namespace が正しいか、コントローラから参照できるか検証。 | 新規がOKで既存がNGなら既存ファイル側の設定漏れが濃厚。 |
| ⑥ IDE の修復 | VS 更新 → 設定リセット → 修復インストール。必要なら再インストール。 | 拡張機能やキャッシュ破損が疑われる場合。 |
| ⑦ 拡張機能の無効化 | ReSharper など外部拡張を一時的に無効化して再現性を確認。 | IntelliSense 異常の切り分けに有効。 |
診断の具体例(ログで「含まれていない」を見抜く)
- MSBuild の詳細ログを取得:
dotnet build -v:diagを実行し、CoreCompileに渡されるCompileアイテムを確認。目的のModels\User.csが列挙されていなければ そもそもビルド対象外 です。 - 二重定義の検出:
CS0104が出るときはusingの並び順やglobal usingを精査。using Models = MyProject.Models;のようなエイリアスも活用できます。 - 名前空間の同期:ソリューション エクスプローラーでプロジェクトまたはフォルダーを右クリック → リファクタリング > 名前空間の同期(バージョンにより表記が異なる)。一括で
namespaceをフォルダー構成に合わせられます。
小さな検証で確信を得る(再現用ミニコード)
最小限のコードで using が機能するか確かめます。
// Models/Order.cs
namespace MyProject.Models;
public sealed record Order(int Id, string Item);
// Controllers/OrdersController.cs
using Microsoft.AspNetCore.Mvc;
using MyProject.Models;
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
[HttpGet("{id}")]
public ActionResult Get(int id) => new Order(id, "Book");
}
これでコンパイルが通らない場合は、名前空間の不一致か.csproj の包含漏れが濃厚です。
チェックリスト(30秒でセルフレビュー)
| 確認項目 | 見る場所 | OK の状態 |
|---|---|---|
ファイル先頭の namespace | 各 .cs | namespace MyProject.<Folder>; になっている |
| ビルド包含 | .csproj / Directory.Build.props | Compile Remove や EnableDefaultItems=false が無い |
| 物理パス | エクスプローラー | MyProject の配下に存在 |
| 新規クラスの挙動 | VS の追加テンプレート | 自動生成の namespace が正しく、using で参照可 |
| IDE の健全性 | VS / 拡張機能 | キャッシュ再生成後も問題なし |
再発防止策(チームで効く仕組み化)
- .editorconfig でスタイル統一:
csharp_style_namespace_declarations = file_scoped:suggestionを設定。レビュー時にnamespaceのズレを検出しやすくします。 - CI に
dotnet buildを必須化:プルリク作成時に最小ビルドを走らせ、「ローカルだけ動く」を排除。 - グローバル using の集中管理:
GlobalUsings.csをプロジェクトルートに置き、BCL 系と自前系を分けて記述。 - VS 上でのファイル移動を徹底:OS のファイラで移動すると
namespaceが古いままになりがち。VS のドラッグ&ドロップ+リファクタリングで同期。 - テンプレート化:
ModelsやContractsなどの典型フォルダーに空のプレースホルダーを置き、正しい名前空間とサンプルを含めておく。
ケーススタディ:フォルダーを「Contracts」に改名したら壊れた
既存の Models を Contracts にリネーム後、API から型が見えなくなった事例です。原因はファイル内の namespace MyProject.Models; がそのままだったこと。解決は次の一括置換でした。
- ソリューション全体で
namespace MyProject.Models;を検索。 namespace MyProject.Contracts;に置換。- VS の「名前空間の同期」で漏れをケア。
- ビルドしてエラーゼロを確認。
このとき .csproj に Compile Remove="Models\**\*.cs" が残っていると、Contracts 側に移動してもビルドされません。Remove の見直しを忘れないようにしましょう。
よくあるコンパイルエラーと対処
| エラー番号 | 症状 | 原因の目安 | 対処 |
|---|---|---|---|
CS0246 | 型/名前空間が見つからない | 名前空間の不一致、ビルド包含漏れ | namespace 修正、.csproj の Compile を確認 |
CS0104 | 型名が曖昧 | 同名型の多重定義、余計な using | 完全修飾名にして設計を整理、using を削減 |
CS0433 | 同一型が複数アセンブリに存在 | 参照競合 | 参照の整理、HintPath やバージョン固定の見直し |
付録:作業コマンド&スニペット集
SDK とグローバル設定の確認
dotnet --version
dotnet --info
ビルドのクリーンと診断ログ
dotnet clean
dotnet build -v:diag
# あるいは詳細なバイナリログ
dotnet build /bl
代表的な .csproj(標準設定)
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
意図的に Models のみを個別包含する例
<ItemGroup>
<Compile Include="Models\*.cs" />
</ItemGroup>
除外の間違いを消す例
<ItemGroup>
<!-- 誤って追加された除外設定を削除する -->
<Compile Remove="Models\**\*.cs" /> <!-- この行を削除 -->
</ItemGroup>
グローバル using(BCL と自前の分離)
// GlobalUsings.cs
global using System;
global using System.Linq;
// 自前の共通名前空間
global using MyProject.Contracts;
実務メモ:VS 側の便利アクション
- スコープ付き名前空間へ変換:従来の
namespace { ... }をファイルスコープに変換すると、宣言の見落としが減り、PR レビューが楽になります。 - 移動と同期のセット運用:フォルダー移動と同時に「名前空間の同期」をルール化する(コードレビューのチェック項目に入れる)。
- 新規テンプレートのカスタム:チームで統一のテンプレート(正しい
namespaceを含む)を用意すると、新人のつまずきを激減できます。
結果とまとめ
ある事例では、あらゆる対処を試しても改善せず、Visual Studio 2022 の再インストールで最終的に解消しました。ただし現場経験では、ほとんどのケースが 「名前空間の修正」+「.csproj の包含確認」+「クリーンビルド」の三点で収まります。
フォルダーの追加はプロジェクト構造の整理であり、型が認識されるかどうかは最終的に namespace と .csproj の設定次第です。手を動かす順序を定型化しておけば、再発時も数分で復旧できます。
最後に:すぐ使えるテンプレ版チェック
□ ファイル先頭の namespace は MyProject.<Folder> になっている
□ .csproj に Compile Remove/EnableDefaultItems=false が無い
□ 物理パスはプロジェクト配下、VS から正式に取り込まれている
□ 新規クラスで using が効く(既存だけ効かないなら既存が原因)
□ VS のキャッシュをクリア、拡張機能の影響を除外済み
これらを踏めば、「フォルダーを追加したのに using できない」トラブルは怖くありません。チームの標準作業に落とし込み、安定した ASP.NET Core Web API 開発を進めましょう。
参考:ミニマル API と名前空間の関係を理解する
ミニマル API は Program.cs が事実上のエントリポイントで、コントローラーを使わない構成でも名前空間の整合性は重要です。API のヘルパーや DTO を Models、契約を Contracts、永続化を Infrastructure といった具合に分けるとき、フォルダーを作っただけでは可視化されません。namespace と global using をセットで運用することで、using 問題の芽を摘めます。
要点の再掲
- フォルダー構成は「見た目の整理」。名前空間は明示的に管理する。
- .csproj の Compile/Remove と EnableDefaultItems が包含を決める。
- 直らなければ IDE キャッシュや拡張機能を疑い、段階的に治療。

コメント