Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Im Beispiel "StronglyTypedExtensions " wird die SyndicationFeed Klasse für die Zwecke des Beispiels verwendet. Die in diesem Beispiel gezeigten Muster können jedoch mit allen Syndication-Klassen verwendet werden, die Erweiterungsdaten unterstützen.
Das Syndication-Objektmodell (SyndicationFeed, SyndicationItem und verwandte Klassen) unterstützt den los getypten Zugriff auf Erweiterungsdaten mithilfe der Eigenschaften AttributeExtensions und ElementExtensions. In diesem Beispiel wird gezeigt, wie Sie stark typisierten Zugriff auf Erweiterungsdaten bereitstellen, indem Sie benutzerdefinierte abgeleitete Klassen von SyndicationFeed und SyndicationItem implementieren, die bestimmte anwendungsspezifische Erweiterungen als stark typisierte Eigenschaften verfügbar machen.
In diesem Beispiel wird gezeigt, wie ein Erweiterungselement implementiert wird, das in der vorgeschlagenen Atom Threading Extensions RFC definiert ist. Dies dient nur zu Demonstrationszwecken, und diese Stichprobe soll keine vollständige Umsetzung der vorgeschlagenen Spezifikation sein.
Beispiel-XML
Das folgende XML-Beispiel zeigt einen Atom 1.0-Eintrag mit einem zusätzlichen <in-reply-to> Erweiterungselement.
<entry>
<id>tag:example.org,2005:1,2</id>
<title type="text">Another response to the original</title>
<summary type="text">
This is a response to the original entry</summary>
<updated>2006-03-01T12:12:13Z</updated>
<link href="http://www.example.org/entries/1/2" />
<in-reply-to p3:ref="tag:example.org,2005:1"
p3:href="http://www.example.org/entries/1"
p3:type="application/xhtml+xml"
xmlns:p3="http://contoso.org/syndication/thread/1.0"
xmlns="http://contoso.org/syndication/thread/1.0">
<anotherElement xmlns="http://www.w3.org/2005/Atom">
Some more data</anotherElement>
<aDifferentElement xmlns="http://www.w3.org/2005/Atom">
Even more data</aDifferentElement>
</in-reply-to>
</entry>
Das <in-reply-to> Element gibt drei erforderliche Attribute (reftypeund href) an und ermöglicht gleichzeitig das Vorhandensein zusätzlicher Erweiterungsattribute und Erweiterungselemente.
Modellieren des In-Reply-To-Elements
In diesem Beispiel wird das <in-reply-to>-Element als CLR modelliert, das IXmlSerializable implementiert, was die Verwendung mit dem DataContractSerializer ermöglicht. Außerdem werden einige Methoden und Eigenschaften für den Zugriff auf die Daten des Elements implementiert, wie im folgenden Beispielcode gezeigt.
[XmlRoot(ElementName = "in-reply-to", Namespace = "http://contoso.org/syndication/thread/1.0")]
public class InReplyToElement : IXmlSerializable
{
internal const string ElementName = "in-reply-to";
internal const string NsUri =
"http://contoso.org/syndication/thread/1.0";
private Dictionary<XmlQualifiedName, string> extensionAttributes;
private Collection<XElement> extensionElements;
public InReplyToElement()
{
this.extensionElements = new Collection<XElement>();
this.extensionAttributes = new Dictionary<XmlQualifiedName,
string>();
}
public Dictionary<XmlQualifiedName, string> AttributeExtensions
{
get { return this.extensionAttributes; }
}
public Collection<XElement> ElementExtensions
{
get { return this.extensionElements; }
}
public Uri Href
{ get; set; }
public string MediaType
{ get; set; }
public string Ref
{ get; set; }
public Uri Source
{ get; set; }
}
Die InReplyToElement Klasse implementiert Eigenschaften für das erforderliche Attribut (HRef, MediaType, und Source) sowie Sammlungen, um AttributeExtensions und ElementExtensions zu halten.
Die InReplyToElement Klasse implementiert die IXmlSerializable Schnittstelle, die die direkte Kontrolle darüber ermöglicht, wie Objektinstanzen ausgelesen und in XML geschrieben werden. Die Methode ReadXml liest zunächst die Werte der Eigenschaften Ref, HRef, Source und MediaType aus dem an sie übergebenen XmlReader. Alle unbekannten Attribute werden in der AttributeExtensions Auflistung gespeichert. Wenn alle Attribute gelesen wurden, wird ReadStartElement() aufgerufen, um den Lesezeiger zum nächsten Element zu bewegen. Da das von dieser Klasse modellierte Element keine erforderlichen untergeordneten Elemente aufweist, werden die untergeordneten Elemente in XElement Instanzen gepuffert und in der ElementExtensions Auflistung gespeichert, wie im folgenden Code gezeigt.
public void ReadXml(System.Xml.XmlReader reader)
{
bool isEmpty = reader.IsEmptyElement;
if (reader.HasAttributes)
{
for (int i = 0; i < reader.AttributeCount; i++)
{
reader.MoveToNextAttribute();
if (reader.NamespaceURI == "")
{
if (reader.LocalName == "ref")
{
this.Ref = reader.Value;
}
else if (reader.LocalName == "href")
{
this.Href = new Uri(reader.Value);
}
else if (reader.LocalName == "source")
{
this.Source = new Uri(reader.Value);
}
else if (reader.LocalName == "type")
{
this.MediaType = reader.Value;
}
else
{
this.AttributeExtensions.Add(new
XmlQualifiedName(reader.LocalName,
reader.NamespaceURI),
reader.Value);
}
}
}
}
reader.ReadStartElement();
if (!isEmpty)
{
while (reader.IsStartElement())
{
ElementExtensions.Add(
(XElement) XElement.ReadFrom(reader));
}
reader.ReadEndElement();
}
}
In WriteXml schreibt die InReplyToElement-Methode zuerst die Werte der Ref, HRef, Source und MediaType Eigenschaften als XML-Attribute. WriteXml ist nicht dafür verantwortlich, das tatsächliche äußere Element selbst zu schreiben; dies wird vom Aufrufer von WriteXml erledigt. Zusätzlich schreibt es den Inhalt von AttributeExtensions und ElementExtensions an den Writer, wie im folgenden Code gezeigt.
public void WriteXml(System.Xml.XmlWriter writer)
{
if (this.Ref != null)
{
writer.WriteAttributeString("ref", InReplyToElement.NsUri,
this.Ref);
}
if (this.Href != null)
{
writer.WriteAttributeString("href", InReplyToElement.NsUri,
this.Href.ToString());
}
if (this.Source != null)
{
writer.WriteAttributeString("source", InReplyToElement.NsUri,
this.Source.ToString());
}
if (this.MediaType != null)
{
writer.WriteAttributeString("type", InReplyToElement.NsUri,
this.MediaType);
}
foreach (KeyValuePair<XmlQualifiedName, string> kvp in
this.AttributeExtensions)
{
writer.WriteAttributeString(kvp.Key.Name, kvp.Key.Namespace,
kvp.Value);
}
foreach (XElement element in this.ElementExtensions)
{
element.WriteTo(writer);
}
}
ThreadedFeed und ThreadedItem
Im Beispiel werden SyndicationItems mit InReplyTo-Erweiterungen von der ThreadedItem Klasse modelliert. Ebenso ist die ThreadedFeed-Klasse eine SyndicationFeed, deren Elemente alle Instanzen von ThreadedItem sind.
Die ThreadedFeed-Klasse erbt von SyndicationFeed und überschreibt OnCreateItem, um ein ThreadedItem zurückzugeben. Außerdem wird eine Methode implementiert, um auf die Items-Auflistung als ThreadedItems zuzugreifen, wie im folgenden Code gezeigt.
public class ThreadedFeed : SyndicationFeed
{
public ThreadedFeed()
{
}
public IEnumerable<ThreadedItem> ThreadedItems
{
get
{
return this.Items.Cast<ThreadedItem>();
}
}
protected override SyndicationItem CreateItem()
{
return new ThreadedItem();
}
}
Die Klasse ThreadedItem erbt von SyndicationItem und macht InReplyToElement zu einer stark typisierten Eigenschaft. Dies ermöglicht einen bequemen programmgesteuerten Zugriff auf die InReplyTo Erweiterungsdaten. Es implementiert zudem TryParseElement und WriteElementExtensions zum Lesen und Schreiben seiner Erweiterungsdaten, wie im folgenden Code gezeigt.
public class ThreadedItem : SyndicationItem
{
private InReplyToElement inReplyTo;
// Constructors
public ThreadedItem()
{
inReplyTo = new InReplyToElement();
}
public ThreadedItem(string title, string content, Uri itemAlternateLink, string id, DateTimeOffset lastUpdatedTime) : base(title, content, itemAlternateLink, id, lastUpdatedTime)
{
inReplyTo = new InReplyToElement();
}
public InReplyToElement InReplyTo
{
get { return this.inReplyTo; }
}
protected override bool TryParseElement(
System.Xml.XmlReader reader,
string version)
{
if (version == SyndicationVersions.Atom10 &&
reader.NamespaceURI == InReplyToElement.NsUri &&
reader.LocalName == InReplyToElement.ElementName)
{
this.inReplyTo = new InReplyToElement();
this.InReplyTo.ReadXml(reader);
return true;
}
else
{
return base.TryParseElement(reader, version);
}
}
protected override void WriteElementExtensions(XmlWriter writer,
string version)
{
if (this.InReplyTo != null &&
version == SyndicationVersions.Atom10)
{
writer.WriteStartElement(InReplyToElement.ElementName,
InReplyToElement.NsUri);
this.InReplyTo.WriteXml(writer);
writer.WriteEndElement();
}
base.WriteElementExtensions(writer, version);
}
}
So können Sie das Beispiel einrichten, erstellen und ausführen
Stellen Sie sicher, dass Sie das One-Time Setup-Verfahren für die Windows Communication Foundation-Beispieleausgeführt haben.
Um die C#- oder Visual Basic .NET-Edition der Lösung zu erstellen, befolgen Sie die Anweisungen in Building the Windows Communication Foundation Samples.
Wenn Sie das Beispiel in einer Konfiguration mit einem Computer oder über Computer hinweg ausführen möchten, folgen Sie den Anweisungen unter Durchführen der Windows Communication Foundation-Beispiele.