Sửa lỗi 'Could not load file or assembly' trong ứng dụng .NET trên Windows

intermediate🪟 Windows2026-05-20| Windows 10/11, .NET Framework 4.x / .NET 6/7/8, Visual Studio 2019/2022, NuGet packages

Error Message

Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
#dotnet#assembly#dll#nuget#binding-redirect

Lỗi

Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.

Build thành công. Ứng dụng crash. Đó là phần điên rồ nhất — đây là lỗi runtime, không phải compile-time. IDE của bạn không hề cảnh báo gì trước khi nó phát nổ trên production.

Nguyên nhân

CLR (Common Language Runtime) yêu cầu khớp phiên bản chính xác khi tải assembly. Lệch dù chỉ một minor version là nó từ chối. Có ba nguyên nhân gây ra điều này:

  • Không khớp phiên bản: Một package tham chiếu Newtonsoft.Json 12.0.0.0, nhưng 13.0.0.0 mới là thứ được đưa vào thư mục output. CLR tìm version 12, thấy version 13, từ chối tải.
  • Thiếu DLL: Assembly không được sao chép vào thư mục output hoặc publish — bị bỏ qua như một dependency hoặc bị loại bỏ trong quá trình publish.
  • Binding redirect bị lỗi: Ứng dụng .NET Framework dùng <bindingRedirect> trong app.config hoặc web.config để nói "version 12 được, dùng version 13 đi." Không có redirect — hoặc redirect sai — thì runtime sẽ chết ở đây.

Fix 1: Khôi phục NuGet Packages

Chín lần trên mười, khi pull từ git hoặc chuyển branch thì cache package local bị hỏng. Hãy bắt đầu từ đây trước khi làm bất cứ điều gì khác.

# Trong thư mục project hoặc solution
dotnet restore

# Hoặc dùng NuGet CLI
nuget restore YourSolution.sln

Sau đó rebuild:

dotnet build --configuration Release

Kiểm tra xem DLL có thực sự xuất hiện trong output không:

dir bin\Release\net6.0\Newtonsoft.Json.dll

Nếu nó không có ở đây thì crash là hoàn toàn có lý. Hãy sửa bước copy này trước khi động vào bất cứ thứ gì khác.

Fix 2: Thêm hoặc sửa Binding Redirect (.NET Framework)

Trên .NET Framework, runtime dùng App.config hoặc Web.config để giải quyết xung đột phiên bản. Mở file ra và tìm phần <runtime>. Không có binding redirect cho assembly bị lỗi? Thêm vào:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json"
                          publicKeyToken="30ad4fe6b2a6aeed"
                          culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-13.0.0.0"
                         newVersion="13.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Thay 13.0.0.0 bằng phiên bản thực sự được cài. Kiểm tra bằng lệnh:

dotnet list package | findstr Newtonsoft

Không muốn chỉnh sửa XML thủ công? Visual Studio có thể tự động tái tạo chúng. Vào Tools → NuGet Package Manager → Manage Packages for Solution, hợp nhất các phiên bản lại, và để nó tự viết lại config cho bạn.

Fix 3: Đồng nhất phiên bản Package trên toàn bộ Projects

Solution nhiều project mới là nơi mọi thứ rối rắm. ProjectA dùng Newtonsoft.Json 12.0.3. ProjectB dùng 13.0.3. Khi runtime chạy, phiên bản nào thua kèo sẽ bị thiếu, và CLR phàn nàn.

Trước tiên tìm tất cả các tham chiếu trong solution:

# PowerShell — tìm tất cả tham chiếu Newtonsoft.Json trong các project
Get-ChildItem -Recurse -Filter "*.csproj" | Select-String "Newtonsoft.Json"

Sau đó ghim tất cả về cùng một phiên bản:

dotnet add package Newtonsoft.Json --version 13.0.3

Để có giải pháp lâu dài, dùng file Directory.Packages.props (Central Package Management) để định nghĩa phiên bản một lần cho toàn bộ solution:

<!-- Directory.Packages.props -->
<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
  </ItemGroup>
</Project>

Sau đó, xóa Version="..." khỏi mọi file .csproj — chúng sẽ kế thừa từ file trung tâm. Việc phiên bản bị lệch nhau sẽ trở nên bất khả thi về mặt thiết kế.

Fix 4: Buộc sao chép vào thư mục Output

Đôi khi DLL nằm trong NuGet cache nhưng không bao giờ được đưa vào build output. Kiểm tra file .csproj xem có cờ ExcludeAssets hoặc PrivateAssets nào chặn việc sao chép runtime không:

<PackageReference Include="Newtonsoft.Json" Version="13.0.3">
  <!-- Xóa bất kỳ ExcludeAssets hoặc PrivateAssets nào chặn runtime -->
</PackageReference>

Với tham chiếu assembly trực tiếp (không từ NuGet), đặt Private thành true để nó được sao chép trong mỗi lần build:

<Reference Include="Newtonsoft.Json">
  <HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
  <Private>true</Private>
</Reference>

Fix 5: Xóa NuGet Cache

Một entry cache bị hỏng gây ra đúng loại bóng ma này — package có vẻ đã được cài, nhưng DLL xuất hiện trong output lại sai hoặc bị cắt ngắn. Xóa sạch và bắt đầu lại từ đầu:

# Xóa tất cả NuGet cache
dotnet nuget locals all --clear

# Sau đó restore lại từ đầu
dotnet restore

Fix 6: Kiểm tra Publish Profile

Lỗi chỉ xuất hiện sau khi publish, không phải khi dev local? Publish profile có thể đang trim assembly. Tắt tính năng này đi:

# Publish self-contained không trimming
dotnet publish -c Release --self-contained true -r win-x64 /p:PublishTrimmed=false

Hoặc mở publish profile tại Properties/PublishProfiles/*.pubxml và xác nhận rằng PublishTrimmed không được đặt thành true cho các assembly mà ứng dụng cần khi runtime.

Kiểm tra kết quả

Sau khi sửa, xác nhận rằng nó thực sự hoạt động — đừng chỉ giả định:

  • Rebuild: dotnet build -c Release
  • Kiểm tra output xem có đúng phiên bản DLL không:dir bin\Release\**\Newtonsoft.Json.dll /s
  • Chạy ứng dụng và xác nhận lỗi đã biến mất.
  • Với ứng dụng .NET Framework có binding redirect, dùng Fusion Log Viewer (fuslogvw.exe, có trong Windows SDK). Bật logging, tái hiện lỗi, rồi đọc các log entry — nó hiển thị toàn bộ chuỗi probe assembly và làm cho redirect bị cấu hình sai trở nên rõ ràng trong vài giây.
# Khởi chạy Fusion Log Viewer
fuslogvw.exe

Phòng ngừa

  • Central Package Management loại bỏ hoàn toàn tình trạng lệch phiên bản trong solution nhiều project. Một file props, một nguồn sự thật duy nhất, không bất ngờ.
  • Kiểm tra định kỳ: chạy dotnet list package --outdated thường xuyên. Khoảng cách dependency bắc cầu dễ thu hẹp hơn nhiều khi chỉ lệch hai phiên bản, không phải mười phiên bản.
  • Cấm floating version trong CI — không dùng * hoặc 13.* trong production build. Ghim vào phiên bản cụ thể và cập nhật có chủ đích.
  • Khi kiểm tra *.deps.json hoặc các JSON manifest khác mà .NET tạo ra bên cạnh build output, JSON Formatter của ToolCraft cho phép bạn validate và khám phá cấu trúc mà không cần khởi động IDE.

Related Error Notes