Dela via


Exempel på starkt skrivna tillägg

Exemplet StronglyTypedExtensions använder SyndicationFeed klassen i exemplet. De mönster som visas i det här exemplet kan dock användas med alla syndikeringsklasser som stöder tilläggsdata.

Syndikeringsobjektmodellen (SyndicationFeed, SyndicationItemoch relaterade klasser) stöder löst skriven åtkomst till tilläggsdata med hjälp AttributeExtensions av egenskaperna och ElementExtensions . Det här exemplet visar hur du ger starkt skrivskyddad åtkomst till tilläggsdata genom att implementera anpassade härledda klasser av SyndicationFeed och SyndicationItem som gör vissa programspecifika tillägg tillgängliga som starkt inskrivna egenskaper.

Det här exemplet visar till exempel hur du implementerar ett tilläggselement som definierats i den föreslagna RFC:en för Atom Threading Extensions. Detta är endast i demonstrationssyfte och det här exemplet är inte avsett att vara ett fullständigt genomförande av den föreslagna specifikationen.

Xml-exempel

I följande XML-exempel visas en Atom 1.0-post med ytterligare ett <in-reply-to> tilläggselement.

<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>

Elementet <in-reply-to> anger tre obligatoriska attribut (reftypeoch href) samtidigt som det möjliggör förekomst av ytterligare tilläggsattribut och tilläggselement.

Modellera elementet Svar till

I det här exemplet modelleras elementet <in-reply-to> som CLR som implementerar IXmlSerializable, vilket möjliggör dess användning med DataContractSerializer. Den implementerar också vissa metoder och egenskaper för att komma åt elementets data, enligt följande exempelkod.

[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; }
}

Klassen InReplyToElement implementerar egenskaper för det obligatoriska attributet (HRef, MediaType, och Source) samt samlingar som ska lagras AttributeExtensions och ElementExtensions.

Klassen InReplyToElement implementerar IXmlSerializable gränssnittet, vilket ger direkt kontroll över hur objektinstanser läse från och skrivs till XML. Metoden ReadXml läser först värdena för Refegenskaperna , HRef, Sourceoch MediaType från det XmlReader som skickades till den. Alla okända attribut lagras i AttributeExtensions samlingen. När alla attribut har lästs ReadStartElement() anropas för att föra läsaren vidare till nästa element. Eftersom elementet som modelleras av den här klassen inte har några underordnade element som krävs, buffras de underordnade elementen ElementExtensions i XElement instanser och lagras i samlingen, enligt följande kod.

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();
    }
}

I WriteXmlskriver metoden först ut värdena Refför egenskaperna , HRef, Sourceoch MediaType som XML-attribut (WriteXml ansvarar inte för att skriva själva det faktiska yttre elementet, som det som görs av anroparen av WriteXml).InReplyToElement Den skriver också innehållet i AttributeExtensions och ElementExtensions till skrivaren, som du ser i följande kod.

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 och ThreadedItem

I exemplet SyndicationItems modelleras med InReplyTo tillägg av ThreadedItem klassen. ThreadedFeed På samma sätt är klassen en SyndicationFeed vars objekt är alla instanser av ThreadedItem.

Klassen ThreadedFeed ärver från SyndicationFeed och åsidosätter OnCreateItem för att returnera en ThreadedItem. Den implementerar också en metod för att Items komma åt samlingen som ThreadedItems, som visas i följande kod.

public class ThreadedFeed : SyndicationFeed
{
    public ThreadedFeed()
    {
    }

    public IEnumerable<ThreadedItem> ThreadedItems
    {
        get
        {
            return this.Items.Cast<ThreadedItem>();
        }
    }

    protected override SyndicationItem CreateItem()
    {
        return new ThreadedItem();
    }
}

Klassen ThreadedItem ärver från SyndicationItem och gör InReplyToElement som en starkt typad egenskap. Detta ger praktisk programmatisk åtkomst till tilläggsdata InReplyTo . Den implementerar TryParseElement och WriteElementExtensions för att läsa och skriva tilläggsdata, enligt följande kod.

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);
    }
}

Så här konfigurerar du, skapar och kör exemplet

  1. Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.

  2. Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.

  3. Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.