Saya menggunakan API web MVC 4 dan formulir web asp.net 4.0 untuk membangun API sisanya. Ini bekerja dengan baik:
[HttpGet]
public HttpResponseMessage Me(string hash)
{
HttpResponseMessage httpResponseMessage;
List<Something> somethings = ...
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK,
new { result = true, somethings = somethings });
return httpResponseMessage;
}
Sekarang saya perlu mencegah beberapa properti untuk serial. Saya tahu saya dapat menggunakan beberapa LINQ di daftar dan hanya mendapatkan properti yang saya butuhkan, dan umumnya ini adalah pendekatan yang baik, tetapi dalam skenario ini something
objeknya terlalu kompleks, dan saya memerlukan set properti yang berbeda dalam metode yang berbeda, jadi lebih mudah untuk menandai, pada saat runtime, setiap properti harus diabaikan.
Apakah ada cara untuk melakukan itu?
c#
asp.net
asp.net-mvc
asp.net-web-api
pengguna1330271
sumber
sumber
Jawaban:
ASP.NET Web API menggunakan
Json.Net
sebagai formatter default, jadi jika aplikasi Anda hanya menggunakan JSON sebagai format data, Anda dapat menggunakan[JsonIgnore]
untuk mengabaikan properti untuk serialisasi:Tapi, cara ini tidak mendukung format XML. Jadi, jika aplikasi Anda harus mendukung format XML lebih banyak (atau hanya mendukung XML), alih-alih menggunakan
Json.Net
, Anda harus menggunakan[DataContract]
yang mendukung JSON dan XML:Untuk lebih memahami, Anda bisa membaca artikel resmi .
sumber
Menurut halaman dokumentasi API Web JSON dan XML Serialization di ASP.NET Web API untuk secara eksplisit mencegah serialisasi pada properti yang bisa Anda gunakan
[JsonIgnore]
untuk serializer Json atau[IgnoreDataMember]
untuk serializer XML default.Namun dalam pengujian saya perhatikan bahwa
[IgnoreDataMember]
mencegah serialisasi untuk permintaan XML dan Json, jadi saya akan merekomendasikan menggunakan itu daripada mendekorasi properti dengan banyak atribut.sumber
[IgnoreDataMember]
tampaknya tidak berfungsi dengan objek proxy EF 6 yang malas (properti virtual).[DataContract]
dan[DataMember]
lakukan.Alih-alih membiarkan semuanya serialisasi secara default, Anda dapat mengambil pendekatan "opt-in". Dalam skenario ini, hanya properti yang Anda tentukan diizinkan untuk diserialisasi. Anda melakukan ini dengan
DataContractAttribute
danDataMemberAttribute
, ditemukan di System.Runtime.Serialization namespace.Ini
DataContactAttribute
diterapkan ke kelas, danDataMemberAttribute
diterapkan untuk setiap anggota yang Anda ingin serialkan:Berani saya katakan ini adalah pendekatan yang lebih baik karena memaksa Anda untuk membuat keputusan eksplisit tentang apa yang akan atau tidak akan membuatnya melalui serialisasi. Itu juga memungkinkan kelas model Anda untuk hidup dalam sebuah proyek sendiri, tanpa mengambil ketergantungan pada JSON.net hanya karena di tempat lain Anda membuat cerita bersambung dengan JSON.net.
sumber
Ini bekerja untuk saya: Buat penyelesai kontrak khusus yang memiliki properti publik yang disebut AllowList dari tipe array string Dalam tindakan Anda, modifikasi properti itu tergantung pada apa yang diperlukan tindakan untuk mengembalikan.
1. buat penyelesai kontrak khusus:
2. gunakan penyelesaian kontrak kustom dalam tindakan
Pendekatan ini memungkinkan saya untuk mengizinkan / melarang permintaan spesifik alih-alih memodifikasi definisi kelas. Dan jika Anda tidak memerlukan serialisasi XML, jangan lupa untuk mematikannya di
App_Start\WebApiConfig.cs
API Anda atau Anda akan mengembalikan properti yang diblokir jika klien meminta xml alih-alih json.sumber
Saya akan menunjukkan kepada Anda 2 cara untuk mencapai apa yang Anda inginkan:
Cara pertama: Hiasi bidang Anda dengan atribut JsonProperty untuk melewati serialisasi bidang itu jika itu nol.
Cara kedua: Jika Anda bernegosiasi dengan beberapa skenario kompleks maka Anda dapat menggunakan konvensi Web Api ("ShouldSerialize") untuk melewati serialisasi bidang itu tergantung pada beberapa logika tertentu.
WebApi menggunakan JSON.Net dan menggunakan refleksi ke serialisasi sehingga ketika telah mendeteksi (misalnya) metode ShouldSerializeFieldX () bidang dengan nama FieldX tidak akan serial.
sumber
Saya terlambat ke permainan, tetapi benda anonim akan melakukan trik:
sumber
Coba gunakan
IgnoreDataMember
propertisumber
Hampir sama dengan jawaban greatbear302, tetapi saya membuat ContractResolver per permintaan.
1) Buat ContractResolver kustom
2) Gunakan penyelesai kontrak khusus dalam tindakan
Edit:
Itu tidak berfungsi seperti yang diharapkan (isolasikan resolver per permintaan). Saya akan menggunakan benda anonim.
sumber
Anda mungkin dapat menggunakan AutoMapper dan menggunakan
.Ignore()
pemetaan lalu mengirim objek yang dipetakansumber
Bekerja dengan baik hanya dengan menambahkan: [IgnoreDataMember]
Di atas propertyp, seperti:
Ini berfungsi dengan ApiController. Kode:
sumber
Untuk beberapa alasan
[IgnoreDataMember]
tidak selalu berhasil untuk saya, dan saya terkadang mendapatkanStackOverflowException
(atau serupa). Jadi sebagai gantinya (atau sebagai tambahan) saya sudah mulai menggunakan pola yang terlihat seperti ini ketikaPOST
masukObjects
ke API saya:Jadi pada dasarnya saya mengirimkan
JObject
dan mengonversinya setelah menerima masalah aviod yang disebabkan oleh serializer built-in yang terkadang menyebabkan loop tak terbatas saat mengurai objek.Jika seseorang mengetahui alasan bahwa ini adalah ide yang buruk, tolong beri tahu saya.
Mungkin perlu dicatat bahwa ini adalah kode berikut untuk properti Kelas EntityFramework yang menyebabkan masalah (Jika dua kelas merujuk satu sama lain):
sumber