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ưng13.0.0.0mớ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>trongapp.confighoặcweb.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 --outdatedthườ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ặc13.*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.jsonhoặ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.

