Frage

ich einen Typ haben, nennen wir es Data<TKey>. Ich habe auch einen WCF-Service-Vertrag haben, die eine Art akzeptiert (nennen wir es Wrapper) mit einer Eigenschaft vom Typ Object (aus Gründen, ich werde nicht gehen, dies ist nicht optional).

[DataContract]
public class Data<TKey> { ... }

[DataContract]
public class Wrapper
{
    [DataMember]
    public object DataItem { get; set; }
}

Im Moment Ich schicke zwei Klassen IntData und LongData:

[DataContract]
public class IntData : Data<int> { /*empty*/ }

[DataContract]
public class LongData : Data<long> { /*empty*/ }

Sie sind beide in den bekannten Arten konfiguriert Datei config. Die Konfiguration ähnelt etwas wie folgt aus:

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="Wrapper, TheirAssembly">
          <knownType type="IntData, MyAssembly"/>
          <knownType type="LongData, MyAssembly"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>

An diesem Punkt alles funktioniert.

Aber ich bin über einen dritten Typ hinzuzufügen, und ich weiß nicht wie das unnötig, leer .NET-Klassen IntData und LongData haben. Sie bestehen nur, weil ...

Ich weiß nicht, wie generische Typen in WCF-Konfiguration angeben!

Ich mag so etwas wie dies zu tun, aber nicht wissen, die genaue Syntax.

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="Wrapper, TheirAssembly">
          <!-- this syntax is wrong -->
          <knownType type="Data{System.Int32}, MyAssembly"/>
          <knownType type="Data{System.Int64}, MyAssembly"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>

Was ist die korrekte Syntax für das?

(Beachten Sie auch, dass ich nicht [KnownType(...)] Attribute auf Wrapper setzen kann, da es nicht meine Art ist. Config scheint der einzige Weg zu sein.)

Bearbeiten

@ baretta Antwort schön gearbeitet. Beachten Sie jedoch, dass zunächst ich diesen Fehler erhalten:

  

Typ ‚MyAssembly.Data`1 [System.Int64]‘ kann nicht zur Liste der bekannten Typen da eine andere Art hinzugefügt werden ‚MyAssembly.Data`1 [System.Int32]‘ mit dem gleichen Datenvertragsnamen ‚ http://www.mycompany.com/MyAssembly:Data ‘ist bereits vorhanden.

Ich habe es nicht in der ursprünglichen Frage erwähnen, aber meine Art hat einen expliziten Datenvertragsnamen. So etwas wie folgt aus:

[DataContract(Name = "Data")]
public class Data<TKey> { ... }

Der obige Fehler aufgetreten, bis ich den Name Eigenschaftswert aus dem Attribute entfernt. Ich hoffe, dass auch jemand anderes heraus hilft. Ich weiß nicht, welches Format in diesem Szenario funktioniert. Dies tat nicht:

[DataContract(Name = "Data\`1")]
[DataContract(Name = "Data{TKey}")]

Wer weiß, wie dies zu tun?

EDIT 2

Danke nochmal an @baretta der darauf hinwies, dass die richtige Syntax in der Tat:

[DataContract(Name = "Data{0}")]
War es hilfreich?

Lösung

Ein generischer Typ ist instantiable aus einem String, wenn die Zeichenfolge dieses Muster folgt: Klassenname von einem „`“Zeichen, gefolgt von der Anzahl der Parameter des Typs gefolgt (in diesem Fall ist es 1 ist), die durch die Parameter des Typs eingeschlossen innerhalb des„[]“gefolgt, und mit Komma als Typ-Parameter Separator .

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="Wrapper, TheirAssembly">
          <!-- this syntax is all good -->
          <knownType type="Data`1[System.Int32], MyAssembly"/>
          <knownType type="Data`1[System.Int64], MyAssembly"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>

Edit:. Ich könnte auch hinzufügen, dass, wenn Montageinformationen für die Typ-Parameter angegeben werden muss (althoug es für Sachen in mscorlib nicht der Fall ist), dann verschachtelt „[]“ verwendet wird,

<knownType type="Data`1[[System.Int32, mscorlib]], MyAssembly"/>

Edit:. Sie können Namen von generischen Typen in Datenverträge anpassen, die String-Format Muster mit

[DataContract(Name = "Data{0}")]
public class Data<TKey>
{...}

In der Standardeinstellung erzeugt der Name für die Daten Typ ist so etwas wie „DataOfInt32HJ67AK7Y“, wobei „HJ67AK7Y“ ist ein Hash aus dem String erzeugt „urn: default“ oder der Namensraum der Klasse, wenn Sie welche haben. Aber "Data {0}" würde es den Namen "DataInt32".

Mehr hier . Werfen Sie einen Blick auf die „Customizing Datenvertragsnamen für generische Typen“ Teil auf der Seite.

Andere Tipps

hier ...

  

Bekannte   Typen können auch in Config wie folgt definiert werden   unten gezeigt.

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
         <add type="MyCompany.Library.Shape`1,
              MyAssembly, Version=2.0.0.0, Culture=neutral,
              PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
            <knownType type="MyCompany.Library.Circle`1,
                       MyAssembly, Version=2.0.0.0, Culture=neutral,
                       PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
                    <parameter index="0"/>
            </knownType>
         </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>
  

Die obige Config gibt an, dass die   allgemeine Parameter für Kreis ist die   gleiche wie der allgemeine Parameter für die   deklarierten Typ-Form. Die Konfiguration erlaubt   die Definition der bekannten Art von   beliebige Komplexität. Zum Beispiel, wenn   es benötigt wird, um zu definieren,   Kreis > als die   bekannte Art von Form (natürlich dieser   ist rein akademisch) es getan werden kann als   folgt.

<configuration>
  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
         <add type="MyCompany.Library.Shape`1,
              MyAssembly, Version=2.0.0.0, Culture=neutral,
              PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
            <knownType type="MyCompany.Library.Circle`1,
                       MyAssembly, Version=2.0.0.0, Culture=neutral,
                       PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
                   <parameter type="System.Collections.Generic.Dictionary`2">
                      <parameter type="System.String"/>
                      <parameter index="0"/>
                   </parameter>                
            </knownType>
         </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>
</configuration>
  

Beachten Sie die Verwendung config-Element   „Parameter“ mit den ‚Typ‘ Attribute   und ‚Index‘.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top