WCF, "ayarlanmamış" özelliklerde tıkanır. Herhangi bir çözüm var mı?


98

Bir hizmet yönteminin sonucu olarak geçirdiğim bir sınıfım var ve bu sınıfın yalnızca alma özelliği var:

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message { get { return ""; } }
}

Servis tarafında bir istisna alıyorum:

System.Runtime.Serialization.InvalidDataContractException: 'MyNamespace.ErrorBase' türünde 'Message' özelliği için ayarlı bir yöntem yok.

Bu özelliğe sadece alıcı olarak sahip olmam gerekiyor, kullanıcıların ona bir değer atamasına izin veremem. Kullanabileceğim herhangi bir çözüm var mı? Yoksa bazı ek özniteliklerim mi eksik?

Yanıtlar:


109

Mesaja genel alıcı ama korumalı ayarlayıcı verin, böylece sadece alt sınıflar (ve hile yaptığı için DataContractSerializer :) değeri değiştirebilir.


Bu harika bir çözüm!
Russell

Teşekkürler, yararlı olmasına sevindim! Bu aslında bu numaranın birkaç kullanımından sadece biridir. Alıcılar ve ayarlayıcılar teknik olarak işlevler olduğundan, bu aynı tekniği, korkutucu IDataContractSurrogate kullanmanıza gerek kalmadan ilkel türlerin (belki de XML'de özel bir zaman formatı) özel serileştirmesini sağlamak için de kullanabilirsiniz.
rh.

29
Hatta özel bile yapabilirsiniz. Serileştirici, özel, genel, korumalı, dahili veya korumalı dahili olup olmadığına aldırmaz.
Abel

8
ve pasör yapthrow new NotSupportedException()
Simon_Weaver

2
Ve private set;kullanıyorsanız bir eser sahibi olmak . Bunları atlarsanız, ihtiyacınız vardır . [DataContract][DataMember]public set;
user276648

12

Değeri güncellemeniz gerekmese bile ayarlayıcı, WCFSerializer tarafından nesnenin serisini kaldırmak (ve değeri yeniden ayarlamak) için kullanılır.

Bu SO, peşinde olduğunuz şey: WCF DataContracts


1
Öyleyse benim için sorunun üstesinden gelmenin tek yolu onu mülkiyet yerine bir yöntem haline getirmek mi? Yine, bu mülkte "ayarlanmasına" izin veremiyorum
Andrey

Bunu bir yöntem haline getirebilirsiniz (ör. GetMessage () {return "";}) alternatif olarak, WCF Serileştiriciye onu yok saymasını söyleyebileceğinizden oldukça eminim. Neler bulabileceğime bakacağım ve size haber vereceğim.,
Russell

1
Bu yığın aşımı sorusu baştaki çiviyi vuruyor: stackoverflow.com/questions/172681/wcf-datacontracts
Russell

11
[DataMember(Name = "PropertyName")]
public string PropertyName
{
    get
    {
        return "";
    }
    private set
    { }
}

5

Yalnızca bir alıcınız varsa, neden mülkü serileştirmeniz gerekiyor? Görünüşe göre, salt okunur özellik için DataMember özniteliğini kaldırabilirsiniz ve serileştirici özelliği yok sayar.


3
Türetilmiş bir özelliği (örneğin, bir kimlik özelliğinden hesaplanan bir URL özelliğini) kalıcı bir depolamaya (örneğin bir veritabanı) serileştirmek gerçekten mantıklı değildir - bunun için oy verin - ancak onu bir bir API isteği tarafından döndürülen temsil (örneğin, JSON veya XML).
Florian Winter

4

"Hiçbir şey yapmama" ayarlayıcınız olamaz mı?

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message 
  {
      get { return ""; } 
      set { }
  }
}

Yoksa DataContract serileştiricisi de bunda barf mı?


14
Kusmuyor, sadece istemci API'sini kullanan geliştiricilerin mülke bir şeyler atayabileceklerini düşünmelerine izin vermek istemedim.
Andrey

2

DataMember özniteliğine sahip özelliklerin her zaman ayarlanması gerekir. DataContract üyelerine her zaman değerler atanabildiğinden, istemci uygulamasında benzer nesneyi yeniden yazmalısınız.


2

ASP.NET MVC ile bu sorunu yaşadım ve JSON çıktısındaki öğeler üzerindeki adları kontrol edebilmek için DataContractSerializer kullanmak istiyorum. Sonunda, serileştiriciyi, ayarlayıcılar (DataContractSerializer'ın yapmadığı) ve özellik adı kontrolü (ASP.NET MVC'deki yerleşik JSON serileştiricisinin desteklemediği) olmadan destekleyen JSON.NET'e değiştirdim [JsonProperty(PropertyName = "myName")].


2

Uygun bir seçenekse ErrorBase, temel sınıf olmak yerine aşağıdaki gibi tanımlayın:

    public interface IError
    {
        string Message
        {
            [OperationContract]
            get;

            // leave unattributed
            set;
        }
    }

Şimdi, bir ayarlayıcı mevcut olsa bile, istemciye WCF kanalı aracılığıyla erişilemez, yani özelmiş gibi.


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.