WCFは、「セット」のないプロパティを制限します。回避策はありますか?


97

サービスメソッドの結果として渡すクラスがいくつかあり、そのクラスには取得専用のプロパティがあります。

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

サービス側で例外が発生しています:

System.Runtime.Serialization.InvalidDataContractException:タイプ「MyNamespace.ErrorBase」のプロパティ「Message」の設定メソッドがありません。

このプロパティはゲッターとしてのみ使用する必要があります。ユーザーに値を割り当てることはできません。使用できる回避策はありますか?または、追加の属性が不足していますか?

回答:


106

Messageをパブリックゲッターで保護されたセッターにします。これにより、サブクラス(およびDataContractSerializer(不正を行うため)のみ)が値を変更できるようになります。


それはきちんとした解決策です!
ラッセル

よろしくお願いいたします。これは実際には、このトリックのいくつかの使用法の1つにすぎません。ゲッターとセッターは技術的に機能しているため、同じ手法を使用して、威圧的なIDataContractSurrogateを使用しなくても、プリミティブ型のカスタムシリアル化(おそらくXMLのカスタム時間形式)を提供できます。
rh。

28
プライベートにすることもできます。シリアライザは、プライベート、パブリック、保護、内部、保護内部のいずれでも問題ありません。
アベル

8
セッターを作るthrow new NotSupportedException()
Simon_Weaver 14年

2
持ってprivate set;使用する場合は作品を[DataContract][DataMember]。それらを省略する場合は、が必要public set;です。
user276648 2017

12

値を更新する必要がない場合でも、WCFSerializerは、setterを使用してオブジェクトを逆シリアル化(および値を再設定)します。

このSOはあなたが求めているものです: WCF DataContracts


1
それで、私が問題を克服する唯一の方法は、それをプロパティの代わりにメソッドにすることですか?繰り返しますが、このプロパティの「設定」を許可することはできません
Andrey

あるいは、メソッド(たとえば、GetMessage(){return "";})にすることもできますが、WCFシリアライザーにそれを無視するように指示できると確信しています。私は、私が見つけ、あなたが知っていることができるかがわかります、。
ラッセル

1
このstackoverflowの質問は頭にくぎ付け
Russell


5

getterしかない場合、なぜプロパティをシリアル化する必要があるのですか?読み取り専用プロパティのDataMember属性を削除でき、シリアライザはプロパティを無視するようです。


3
派生プロパティ(IDプロパティから計算されたURLプロパティなど)を永続ストレージ(データベースなど)にシリアル化することは実際には意味がありません-そのために賛成します-にシリアル化することは理にかなっていますAPIリクエストによって返される表現(JSONやXMLなど)。
フロリアン冬

3

「何もしない」セッターを用意することはできませんか?

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

それともDataContractシリアライザはそれを実行しますか?


14
クライアントAPIを使用している開発者に、プロパティに何かを割り当てることができると考えさせたくありませんでした。
Andrey、

2

DataMember属性を持つプロパティには常にセットが必要です。DataContractメンバーには常に値を割り当てることができるため、クライアントアプリケーションで同様のオブジェクトを書き直す必要があります。


2

ASP.NET MVCでこの問題があり、JSON出力のアイテムの名前を制御できるようにDataContractSerializerを使用したいと思っていました。最終的に私はシリアライザーをJSON.NETに切り替えました。これは、セッターなしのプロパティ(DataContractSerializerはサポートしていません)とプロパティ名の制御(ASP.NET MVCの組み込みJSONシリアライザーはサポートしていません)を介してサポートしています[JsonProperty(PropertyName = "myName")]


2

これが実行可能なオプションである場合ErrorBaseは、基本クラスとして持つ代わりに、次のように定義します。

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

            // leave unattributed
            set;
        }
    }

現在、セッターは存在しますが、WCFチャネルを介してクライアントからアクセスできないため、まるでプライベートであるかのようです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.