.NET WebAPI Serileştirme k_BackingField Nastiness


86

Aşağıdakileri serileştirdiğimde:

[Serializable]
public class Error
{

    public string Status { get; set; }
    public string Message { get; set; }
    public string ErrorReferenceCode { get; set; }
    public List<FriendlyError> Errors { get; set; }
}

Bu iğrenç karmaşaya kapılıyorum:

<ErrorRootOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance"   xmlns="http://schemas.datacontract.org/2004/07/Printmee.Api">
<_x003C_Errors_x003E_k__BackingField>
An exception has occurred. Please contact printmee support
</_x003C_Errors_x003E_k__BackingField>
<_x003C_LookupCode_x003E_k__BackingField>988232ec-6bc9-48f3-8116-7ff7c71302dd</_x003C_LookupCode_x003E_k__BackingField>
</ErrorRootOfstring>

Ne oluyor? Bunu nasıl güzelleştirebilirim? JSON yanıtları ayrıca k_BackingField içerir


Yanıtlar:


126

Varsayılan olarak ne kullanmanız ne [Serializable]de [DataContract]Web API ile çalışmanız gerekmez .

Modelinizi olduğu gibi bırakın ve Web API tüm genel özellikleri sizin için serileştirecektir.

Yalnızca nelerin dahil edildiği konusunda daha fazla kontrole sahip olmak istiyorsanız, sınıfınızı [DataContract]ve eklenecek özelliklerle dekore edersiniz [DataMember](çünkü hem DCS hem de JSON.NET bu öznitelikleri resmeder).

Herhangi bir nedenle, [Serializable]sınıfınızda sınıfına ihtiyacınız varsa (yani, herhangi bir nedenle bir bellek akışına serileştiriyorsanız, derin kopyalar yapıyorsanız vb.), Arka alan adlarını önlemek için her iki özelliği birlikte kullanmanız gerekir:

[Serializable]
[DataContract]
public class Error
{
    [DataMember]
    public string Status { get; set; }
    [DataMember]
    public string Message { get; set; }
    [DataMember]
    public string ErrorReferenceCode { get; set; }
    [DataMember]
    public List<FriendlyError> Errors { get; set; }
}

6
İşte buydu-- Sadece [Serileştirilebilir] 'i kaldırmam gerekiyordu. Teşekkürler.
Micah

Teşekkürler Filip, önbellek nedeniyle öznitelikleri saklamak zorundayım .. BTW, blogunuzun hevesli bir hayranıyım .. gelmeye devam edin!
Stephen Patten

20
Bu çok kötü. Microsoft neden olamaz HİÇ o serileştirme geldiğinde doğru bir şey yapmak?
Chris Marisic

Aşağıda kendi cevabımda gösterdiğim gibi daha genel bir çözüm var.
JotaBe

Belki de serileştirme ile ilgili sorun "doğru" nun tanımıdır, herkesin kendi yöntemiyle veriye ihtiyacı vardır.
Luiz Felipe

94

Daha genel bir çözüm var: Json Serializer'ı [Serializable]özniteliği yok sayacak şekilde yapılandırabilirsiniz , böylece sınıflarınızdaki öznitelikleri değiştirmek zorunda kalmazsınız.

Bu yapılandırma değişikliğini uygulama başlangıcında, yani Global.asax Application_Startolayında yapmalısınız :

var serializerSettings =
  GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
var contractResolver =
  (DefaultContractResolver)serializerSettings.ContractResolver;
contractResolver.IgnoreSerializableAttribute = true;

Json serileştirmede, tarihleri ​​serileştirmek için formatları belirleme ve diğer pek çok şey gibi başka değişiklikler de yapabilirsiniz.

Bu yalnızca Web API JSON serileştirme için geçerli olacaktır. Uygulamadaki diğer serileştirmeler (Web API XML serileştirme, MVC JsonResult ...) bu ayardan etkilenmeyecektir.


4
Bu çözümü her yerde [DataContract] ve [DataMember] özniteliklerini eklemekten çok daha çok seviyorum. Teşekkür ederim!!
Mark Good

1
Her zaman kullanmanız gereken bir şey değil, ama bu harika bir numara. Modelleri değiştirme veya kod tabanını derinlemesine yeniden düzenleme lüksüne sahip olmadığınız karmaşık durumların üstesinden gelmenize yardımcı olan bir tür levye.
uygar.raf

Haklısın, bunu yapmanın en iyi yolu bu değil. Bununla birlikte, bazı durumlarda yeniden düzenleme sadece bir lüks değil, aynı zamanda hiç de uygulanabilir değil. Örneğin, kod tabanı WCF veya XML Serileştirme kullanıyorsa, Veri Sözleşmesi veya XML serileştirme öznitelikleri gerektirir. Bunu değiştiremezsin. Neyse ki JSON.NET çok güçlüdür: Veri Sözleşmesini, XML serileştirmeyi ve kendi özniteliklerini destekler ve bunları serileştirme için nasıl kullandığını kontrol edebilir, hatta tamamen yok sayabilirsiniz. Hatta kendi uygulamanızı bile ekleyebilirsiniz. Tabii ki, nitelikler olmadan temiz bir sadeliği korumayı tercih ederim.
JotaBe

Varsayılan olarak bu şekilde çalışması gerekir! Neden serileştirilmiş akışımızda arka plan saçmalığı yok?
Byron Whitlock

1
Web api kullanıyorsanız ve .net çerçevesinin 4. sürümünü hedefliyorsanız, bunun çalışması için Netwonsoft.Json paketini güncellemeniz gerekir, yani Update-Package Newtonsoft.Json.
pblack


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.