Aplikasi yang saya gunakan tidak berfungsi ketika saya mencoba membuat serial.
Pernyataan seperti
XmlSerializer lizer = new XmlSerializer(typeof(MyType));
menghasilkan:
System.IO.FileNotFoundException occurred
Message="Could not load file or assembly '[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
Source="mscorlib"
FileName="[Containing Assembly of MyType].XmlSerializers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
FusionLog=""
StackTrace:
at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
Saya tidak mendefinisikan serializers khusus untuk kelas saya.
Bagaimana saya bisa memperbaiki masalah ini?
c#
xml-serialization
Irwin
sumber
sumber
Generate serialization assembly
tarik-turun ke "Aktif", alih-alih "Otomatis".Jawaban:
Percaya atau tidak, ini adalah perilaku normal. Pengecualian dilemparkan tetapi ditangani oleh XmlSerializer, jadi jika Anda abaikan saja semuanya akan berlanjut dengan baik.
Saya telah menemukan ini sangat menjengkelkan, dan ada banyak keluhan tentang ini jika Anda mencari di sekitar sedikit, tetapi dari apa yang saya baca Microsoft tidak berencana melakukan apa pun tentang hal itu.
Anda dapat menghindari popup Pengecualian setiap saat saat debugging jika Anda mematikan pengecualian kesempatan pertama untuk pengecualian khusus itu. Di Visual Studio, buka Debug -> Pengecualian (atau tekan Ctrl+ Alt+ E), Pengecualian Waktu Bersama Bahasa Umum -> System.IO -> System.IO.FileNotFoundException .
Anda dapat menemukan informasi tentang cara lain di sekitarnya dalam posting blog C # XmlSerializer FileNotFound pengecualian (yang membahas alat Chris Sells ' XmlSerializerPreCompiler ).
sumber
Seperti kata Martin Sherburn, ini adalah perilaku normal. Konstruktor XmlSerializer pertama kali mencoba menemukan rakitan yang bernama [YourAssembly] .XmlSerializers.dll yang harus berisi kelas yang dihasilkan untuk serialisasi tipe Anda. Karena DLL tersebut belum dihasilkan (mereka tidak secara default), FileNotFoundException dilemparkan. Ketika itu terjadi, konstruktor XmlSerializer menangkap pengecualian itu, dan DLL dihasilkan secara otomatis saat runtime oleh konstruktor XmlSerializer (ini dilakukan dengan membuat file sumber C # dalam direktori% temp% komputer Anda, kemudian mengompilasinya menggunakan kompiler C #). Konstruksi tambahan XmlSerializer untuk tipe yang sama hanya akan menggunakan DLL yang sudah dibuat.
Pengecualian ditangani oleh konstruktor XmlSerializer. Tidak perlu melakukan apa pun sendiri, Anda cukup mengklik 'Lanjutkan' (F5) untuk melanjutkan menjalankan program Anda dan semuanya akan baik-baik saja. Jika Anda terganggu oleh pengecualian menghentikan eksekusi program Anda dan muncul pembantu pembantu, Anda baik 'Just My Code' dimatikan, atau Anda memiliki FileNotFoundException diatur untuk menghentikan eksekusi ketika dilempar, bukan ketika 'Pengguna- tidak tertangani '.
Untuk mengaktifkan 'Just My Code', buka Tools >> Options >> Debugging >> General >> Enable Just My Code. Untuk mematikan penghentian eksekusi ketika FileNotFound dilempar, buka Debug >> Pengecualian >> Temukan >> masukkan 'FileNotFoundException' >> hapus centang kotak centang 'Dilempar' dari System.IO.FileNotFoundException.
sumber
FileNotFoundException
akan dilempar. Perbedaannya bukan pada bagaimana keberadaan majelis diperiksa, tetapi bagaimana menghasilkannya begitu ditentukan bahwa itu hilang. Sebelumnya, digunakan generasi kode C # tekstual dengan panggilan ke kompiler C # untuk membuat IL. Dimulai dengan .NET 4.5, ia memancarkan IL secara langsung, tanpa menggunakan kompiler.File.Exists()
mungkin tidak cukup. Mencari lokasi bukan urusan sederhana, runtime terlihat di beberapa lokasi dan saya yakin perilaku berubah sesuai dengan lingkungan (aplikasi konsol vs di-host di IIS, dll). Saya kira apa yang seharusnya diimplementasikan adalahTryLoadAssembly()
atau sesuatu yang serupa.Dalam properti proyek Visual Studio ("Build" halaman, jika saya ingat benar) ada opsi yang mengatakan "menghasilkan perakitan serialisasi". Coba nyalakan untuk proyek yang menghasilkan [Containing Assembly of MyType] .
sumber
Ada solusi untuk itu. Jika Anda menggunakan
harus menghindari pengecualian itu. Ini berhasil untuk saya.
PERINGATAN: Jangan gunakan beberapa kali, atau Anda akan memiliki kebocoran memori
Anda akan membocorkan memori seperti orang gila jika Anda menggunakan metode ini untuk membuat instance
XmlSerializer
untuk jenis yang sama lebih dari sekali!Ini karena metode ini mem-bypass caching bawaan yang disediakan
XmlSerializer(type)
danXmlSerializer(type, defaultNameSpace)
konstruktor (semua konstruktor lain juga memotong cache).Jika Anda menggunakan metode apa pun untuk membuat XmlSerializer yang tidak melalui dua konstruktor ini, Anda harus menerapkan caching Anda sendiri atau Anda akan kehabisan memori.
sumber
XmlSerializer
untuk jenis yang sama lebih dari sekali! Ini karena metode ini mem-bypass caching bawaan yang disediakanXmlSerializer(type)
danXmlSerializer(type, defaultNameSpace)
konstruktor (semua konstruktor lain juga memotong cache). Jika Anda menggunakan metode apa pun untuk membuatXmlSerializer
yang tidak melalui dua konstruktor ini, Anda harus menerapkan caching Anda sendiri atau Anda akan mengalami pendarahan memori.FromTypes
tampaknya mengisi cache. Jadi itu harus menjadi cara yang valid untuk menghangatkanXmlSerializer
cache kosong dalam satu pernyataan (seperti artikel menyarankan), tetapi cara yang sangat buruk untuk mengambil sesuatu dari itu (hanya boleh dilakukan melalui konstruktor paling sederhana). Bagaimanapun, saya tidak tahu itu bug, saya selalu berpikir apa pun yang bocor seharusnya bocor (sepertiXmlSerializer
konstruktor yang lebih maju ). Saya bahkan tidak akan mempertimbangkan untuk menggunakanFromTypes()
karena Anda bisa melakukannyatypes.Select(t => new XmlSerializer(t))
.FromTypes
memang memiliki daya tariknya - bahkan jika pengecualian yang dilemparkan semuanya tertangkap, ini adalah operasi yang murni; pendekatan 'tembolok cara Anda sendiri' tampaknya menjadi satu-satunya solusi, karena satu-satunya perbaikan yang didukung secara resmi terlihat dalam perakitan berbasis web yang tidak jelas. (sunting: terus terang, saya siap untuk mengirim semuanya ke kontrak data :))Saya mengalami masalah ini dan tidak bisa mengatasinya dengan solusi yang disebutkan.
Lalu akhirnya saya menemukan solusinya. Tampaknya serializer tidak hanya membutuhkan tipe, tetapi tipe bersarang juga. Mengubah ini:
Untuk ini:
Memperbaiki masalah untuk saya. Tidak ada lagi pengecualian atau apapun.
sumber
var xmlSerializer = new XmlSerializer(typeof(T), typeof(T).GetNestedTypes());
Solusi saya adalah langsung ke refleksi untuk membuat serializer. Ini memotong pemuatan file aneh yang menyebabkan pengecualian. Saya mengemas ini dalam fungsi pembantu yang juga menangani caching serializer.
sumber
Untuk menghindari pengecualian, Anda perlu melakukan dua hal:
Tambahkan atribut System.Xml.Serialization.XmlSerializerAssembly ke kelas Anda. Ganti 'MyAssembly' dengan nama majelis tempat MyClass berada.
Hasilkan file serialisasi menggunakan utilitas sgen.exe dan menyebarkannya dengan perakitan kelas.
'sgen.exe MyAssembly.dll' akan menghasilkan file MyAssembly.XmlSerializers.dll
Dua perubahan ini akan menyebabkan .net untuk menemukan perakitan secara langsung. Saya memeriksanya dan bekerja pada .NET framework 3.5 dengan Visual Studio 2008
sumber
Pengecualian ini juga dapat dijebak oleh asisten debugging terkelola (MDA) yang disebut BindingFailure.
MDA ini berguna jika aplikasi Anda dirancang untuk dikirimkan dengan rakitan serialisasi pra-bangun. Kami melakukan ini untuk meningkatkan kinerja aplikasi kami. Hal ini memungkinkan kami untuk memastikan bahwa rakitan serialisasi pra-dibangun sedang dibangun dengan benar oleh proses pembuatan kami, dan dimuat oleh aplikasi tanpa dibangun kembali dengan cepat.
Ini benar-benar tidak berguna kecuali dalam skenario ini, karena seperti yang dikatakan poster lainnya, ketika kesalahan pengikatan terperangkap oleh konstruktor Serializer, perakitan serialisasi dibangun kembali saat runtime. Jadi biasanya Anda bisa mematikannya.
sumber
Fungsi XmlSerializer.FromTypes tidak melempar pengecualian, tetapi bocor memori. Itulah mengapa Anda perlu men-cache serializer tersebut untuk setiap jenis untuk menghindari kebocoran memori untuk setiap instance yang dibuat.
Buat pabrik XmlSerializer Anda sendiri dan gunakan hanya:
Pabriknya terlihat seperti:
Versi yang lebih rumit tanpa kemungkinan kebocoran memori (tolong seseorang tinjau kodenya):
sumber
Pemecahan masalah kesalahan kompilasi di sisi lain sangat rumit. Masalah-masalah ini memanifestasikan dirinya dalam FileNotFoundException dengan pesan:
Anda mungkin bertanya-tanya apa hubungan file yang tidak ditemukan dengan instantiating objek serializer, tetapi ingat: konstruktor menulis file C # dan mencoba untuk mengompilasinya. Tumpukan panggilan pengecualian ini memberikan beberapa informasi yang baik untuk mendukung kecurigaan itu. Pengecualian terjadi ketika XmlSerializer berusaha memuat rakitan yang dihasilkan oleh CodeDOM yang memanggil metode System.Reflection.Assembly.Load. Pengecualian tidak memberikan penjelasan mengapa perakitan yang seharusnya dibuat oleh XmlSerializer tidak ada. Secara umum, rakitan tidak hadir karena kompilasi gagal, yang mungkin terjadi karena, dalam keadaan langka, atribut serialisasi menghasilkan kode yang gagal dikompilasi oleh kompiler C #.
Catatan Kesalahan ini juga terjadi ketika XmlSerializer berjalan di bawah akun atau lingkungan keamanan yang tidak dapat mengakses direktori temp.
Sumber : http://msdn.microsoft.com/en-us/library/aa302290.aspx
sumber
Dalam properti proyek Visual Studio ada opsi yang mengatakan "menghasilkan perakitan serialisasi". Coba nyalakan untuk proyek yang menghasilkan [Containing Assembly of MyType].
sumber
Kelas khusus untuk membuat serial:
Saya telah melampirkan cuplikan kode. Mungkin ini bisa membantu Anda.
sumber
Saya mengalami masalah yang sama, dan mengabaikan pengecualian tidak berhasil untuk saya. Kode saya memanggil konfigurasi NServiceBus
Configure.With(...).XmlSerializer()...
Apa yang diperbaiki bagi saya adalah mengubah platform untuk proyek saya.
sumber
Sama seperti referensi. Mengambil dari jawaban dan komentar DB, saya datang dengan solusi yang dekat dengan solusi DB. Ini berfungsi dengan baik dalam semua kasus saya dan aman utasnya. Saya tidak berpikir bahwa menggunakan ConcurrentDictionary akan ok.
Pemakaian:
sumber
Jenis Anda dapat mereferensikan majelis lain yang tidak dapat ditemukan di GAC maupun di folder bin lokal Anda ==> ...
Bisakah Anda memberikan contoh tipe yang ingin Anda serialkan?
Catatan: Pastikan jenis Anda mengimplementasikan Serializable.
sumber
Saya mendapatkan kesalahan yang sama, dan itu karena jenis saya mencoba deserialize tidak memiliki konstruktor tanpa parameter default . Saya menambahkan konstruktor, dan mulai bekerja.
sumber
Saya memiliki masalah yang sama sampai saya menggunakan alat Pihak ke-3 untuk menghasilkan Kelas dari XSD dan itu berhasil! Saya menemukan bahwa alat itu menambahkan beberapa kode tambahan di bagian atas kelas saya. Ketika saya menambahkan kode yang sama ini ke bagian atas kelas asli saya itu berhasil. Inilah yang saya tambahkan ...
sumber
Terlihat banyak rekomendasi untuk menggunakan
ConcurrentDictionary
, tetapi tidak ada contoh yang solid tentang itu, jadi saya akan melemparkan topi saya ke ras solusi ini. Saya bukan pengembang thread-aman, jadi jika kode ini tidak solid, silakan berbicara demi mereka yang mengikuti.Saya telah melihat posting lain yang melibatkan
ConcurrentDictionary
danLazy
memuat nilainya. Saya tidak yakin apakah itu relevan di sini atau tidak, tapi ini kode untuk itu:sumber