/// <summary> /// Sets the response header information. /// </summary> /// <param name="context"> /// An <see cref="HttpContext"/> object that provides references to the intrinsic server objects (for example, <b>Request</b>, <b>Response</b>, <b>Session</b>, and <b>Server</b>) used to service HTTP requests. /// </param> /// <param name="items"> /// The collection of <see cref="IPublishable"/> instances used when setting the response header details. /// </param> /// <param name="format"> /// The format of the syndication feed being generated. /// </param> /// <exception cref="ArgumentNullException"> /// The <paramref name="context"/> is a null reference (Nothing in Visual Basic) -or- the <paramref name="items"/> is a null reference (Nothing in Visual Basic). /// </exception> private static void SetHeaderInformation( HttpContext context, IEnumerable <IPublishable> items, SyndicationFormat format) { var lastModified = new DateTime(1900, 1, 3); // don't use DateTime.MinValue here, as Mono doesn't like it foreach (var item in items) { if (item.DateModified.AddHours(-BlogSettings.Instance.Timezone) > lastModified) { lastModified = item.DateModified.AddHours(-BlogSettings.Instance.Timezone); } } switch (format) { case SyndicationFormat.Atom: context.Response.ContentType = "application/atom+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=atom.xml"); break; case SyndicationFormat.Rss: context.Response.ContentType = "application/rss+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=rss.xml"); break; } if (Utils.SetConditionalGetHeaders(lastModified)) { context.Response.End(); } }
//============================================================ // PUBLIC METHODS //============================================================ #region WriteFeed(SyndicationFormat format, Stream stream, List<IPublishable> publishables) /// <summary> /// Writes a generated syndication feed that conforms to the supplied <see cref="SyndicationFormat"/> using the supplied <see cref="Stream"/> and collection. /// </summary> /// <param name="format">A <see cref="SyndicationFormat"/> enumeration value indicating the syndication format to generate.</param> /// <param name="stream">The <see cref="Stream"/> to which you want to write the syndication feed.</param> /// <param name="publishables">The collection of <see cref="IPublishable"/> objects used to generate the syndication feed content.</param> /// <param name="title">The title of the RSS channel</param> public void WriteFeed(SyndicationFormat format, Stream stream, List <IPublishable> publishables, string title) { if (stream == null) { throw new ArgumentNullException("stream"); } if (publishables == null) { throw new ArgumentNullException("publishables"); } if (!stream.CanWrite) { throw new ArgumentException(String.Format(null, "Unable to generate {0} syndication feed. The provided stream does not support writing.", format), "stream"); } //------------------------------------------------------------ // Write syndication feed based on specified format //------------------------------------------------------------ switch (format) { case SyndicationFormat.Atom: this.WriteAtomFeed(stream, publishables, title); break; case SyndicationFormat.Rss: this.WriteRssFeed(stream, publishables, title); break; } }
public FeedItem(ISyndicationItem item, SyndicationFormat sourceFormat) { Title = item.Title.Text; PubDate = item.PublishedDate.DateTime; Author = item.Authors[0].Name; Content = sourceFormat == SyndicationFormat.Atom10 ? item.Content.Text : item.Summary.Text; }
protected ActionResult SyndicationResult(IEnumerable <Post> posts, string format = "rss") { SyndicationFormat sf = SyndicationFormat.Rss; if (!Enum.TryParse(format, true, out sf)) { return(NotFound()); } using (MemoryStream ms = new MemoryStream()) { if (sf == SyndicationFormat.Rss) { WriteRssXml(ms, posts); } else if (sf == SyndicationFormat.Atom) { WriteAtomXml(ms, posts); } else { return(NotFound()); } string result = Encoding.UTF8.GetString(ms.ToArray()); return(Content(result, "text/xml")); } }
/// <summary> /// Enables processing of HTTP Web requests by a custom HttpHandler that implements /// the <see cref="T:System.Web.IHttpHandler"></see> interface. /// </summary> /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides references /// to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests. /// </param> public void ProcessRequest(HttpContext context) { string title = RetrieveTitle(context); SyndicationFormat format = RetrieveFormat(context); List <IPublishable> list = GenerateItemList(context); list = CleanList(list); if (string.IsNullOrEmpty(context.Request.QueryString["post"])) { // Shorten the list to the number of posts stated in the settings, except for the comment feed. int max = Math.Min(BlogSettings.Instance.PostsPerFeed, list.Count); list = list.FindAll(delegate(IPublishable item) { return(item.IsVisible == true); }); list = list.GetRange(0, max); } SetHeaderInformation(context, list, format); if (BlogSettings.Instance.EnableHttpCompression) { HttpModules.CompressionModule.CompressResponse(context); } SyndicationGenerator generator = new SyndicationGenerator(BlogSettings.Instance, Category.Categories); generator.WriteFeed(format, context.Response.OutputStream, list, title); }
private FeedDataEntry _ReadFeedDataEntryFrom (SyndicationItem syndicationItem, SyndicationFormat syndicationFormat) { var feedDataEntry = new FeedDataEntry (); if (syndicationItem.Title != null && syndicationItem.Title.Text != null) { feedDataEntry.Title = syndicationItem.Title.Text; } if (syndicationItem.PublishedDate != null) { feedDataEntry.PublishedDate = syndicationItem.PublishedDate.DateTime; } if (syndicationItem.Authors != null && syndicationItem.Authors.Count > 0) { feedDataEntry.Author = syndicationItem.Authors[0].Name.ToString (); } switch (syndicationFormat) { case SyndicationFormat.Atom10: { if (syndicationItem.Content != null && syndicationItem.Content.Text != null) { feedDataEntry.Content = syndicationItem.Content.Text; } if (syndicationItem.Id != null) { feedDataEntry.Link = new Uri (syndicationItem.Id); } break; } case SyndicationFormat.Rss20: { if (syndicationItem.Summary != null && syndicationItem.Summary.Text != null) { feedDataEntry.Content = syndicationItem.Summary.Text; } if (syndicationItem.Links != null && syndicationItem.Links.Count > 0) { feedDataEntry.Link = syndicationItem.Links[0].Uri; } break; } } return feedDataEntry; }
public FeedItem(ISyndicationItem item, SyndicationFormat sourceFormat) { Title = item.Title.Text; PubDate = item.PublishedDate.DateTime; Author = item.Authors[0].Name; Content = sourceFormat == SyndicationFormat.Atom10 ? item.Content.Text : item.Summary.Text; }
public static FeedItem ToFeedItem(this SyndicationItem item, SyndicationFormat format) { string content = string.Empty; Uri link = null; FeedItem feedItem = new FeedItem(); if (item.Title != null && !string.IsNullOrEmpty(item.Title.Text)) { feedItem.Title = item.Title.Text; } if (item.PublishedDate != null) { feedItem.PubDate = item.PublishedDate.DateTime; } if (item.Authors != null && item.Authors.Any()) { feedItem.Author = item.Authors.First().Name; } switch (format) { case SyndicationFormat.Atom10: if (item.Content != null && !string.IsNullOrEmpty(item.Content.Text)) { content = item.Content.Text; } if (!string.IsNullOrEmpty(item.Id)) { Uri.TryCreate(item.Id, UriKind.Absolute, out link); } break; case SyndicationFormat.Rss20: if (item.Summary != null && !string.IsNullOrEmpty(item.Summary.Text)) { content = item.Summary.Text; } if (item.Links != null && item.Links.Any()) { link = item.Links.First().Uri; } break; default: throw new NotSupportedException("Unhandled SyndicationFormat value."); } feedItem.Content = content; feedItem.Link = link; return feedItem; }
/// <summary> /// Writes a generated syndication feed that conforms to the supplied <see cref="SyndicationFormat"/> using the supplied <see cref="Stream"/> and collection. /// </summary> /// <param name="format"> /// A <see cref="SyndicationFormat"/> enumeration value indicating the syndication format to generate. /// </param> /// <param name="stream"> /// The <see cref="Stream"/> to which you want to write the syndication feed. /// </param> /// <param name="publishables"> /// The collection of <see cref="IPublishable"/> objects used to generate the syndication feed content. /// </param> /// <param name="title"> /// The title of the RSS channel /// </param> public void WriteFeed(SyndicationFormat format, Stream stream, List<IPublishable> publishables, string title) { if (stream == null) { throw new ArgumentNullException("stream"); } if (publishables == null) { throw new ArgumentNullException("publishables"); } if (!stream.CanWrite) { throw new ArgumentException( String.Format( null, "Unable to generate {0} syndication feed. The provided stream does not support writing.", format), "stream"); } // ------------------------------------------------------------ // Write syndication feed based on specified format // ------------------------------------------------------------ switch (format) { case SyndicationFormat.Atom: this.WriteAtomFeed(stream, publishables, title); break; case SyndicationFormat.Rss: this.WriteRssFeed(stream, publishables, title); break; } }
/// <summary> /// Sets the response header information. /// </summary> /// <param name="context"> /// An <see cref="HttpContext"/> object that provides references to the intrinsic server objects (for example, <b>Request</b>, <b>Response</b>, <b>Session</b>, and <b>Server</b>) used to service HTTP requests. /// </param> /// <param name="items"> /// The collection of <see cref="IPublishable"/> instances used when setting the response header details. /// </param> /// <param name="format"> /// The format of the syndication feed being generated. /// </param> /// <exception cref="ArgumentNullException"> /// The <paramref name="context"/> is a null reference (Nothing in Visual Basic) -or- the <paramref name="items"/> is a null reference (Nothing in Visual Basic). /// </exception> private static void SetHeaderInformation( HttpContext context, IEnumerable<IPublishable> items, SyndicationFormat format) { var lastModified = new DateTime(1900, 1, 3); // don't use DateTime.MinValue here, as Mono doesn't like it foreach (var item in items) { if (item.DateModified.AddHours(-BlogSettings.Instance.Timezone) > lastModified) { lastModified = item.DateModified.AddHours(-BlogSettings.Instance.Timezone); } } switch (format) { case SyndicationFormat.Atom: context.Response.ContentType = "application/atom+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=atom.xml"); break; case SyndicationFormat.Rss: context.Response.ContentType = "application/rss+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=rss.xml"); break; } if (Utils.SetConditionalGetHeaders(lastModified)) { context.Response.End(); } }
private Feed ProcessFeed(XmlReader feedReader, bool cachedStream) { ArrayList items = new ArrayList(); Hashtable optionalElements = new Hashtable(); string feedLink = String.Empty; string feedDescription = String.Empty; string feedTitle = String.Empty; string maxItemAge = String.Empty; SyndicationFormat feedFormat = SyndicationFormat.Unknown; DateTime defaultItemDate = DateTime.MinValue; DateTime channelBuildDate = DateTime.Now.ToUniversalTime(); Feed feed = null; string rssNamespaceUri = String.Empty; feedReader.MoveToContent(); object localname = feedReader.LocalName; try { if ((localname == nameRefs[(int)NameTableIndexes.rdf]) && feedReader.NamespaceURI.Equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#")) { //RSS 0.9 or 1.0 feedReader.Read(); //go to end of 'RDF' start tag feedReader.MoveToContent(); //go to the next element feedFormat = SyndicationFormat.Rdf; localname = feedReader.LocalName; //figure out if 0.9 or 1.0 by peeking at namespace URI of <channel> element if (localname == nameRefs[(int)NameTableIndexes.channel]) { rssNamespaceUri = feedReader.NamespaceURI; } else { //no channel, just assume RSS 1.0 rssNamespaceUri = "http://purl.org/rss/1.0/"; } } else if (localname == nameRefs[(int)NameTableIndexes.rss]) { //RSS 0.91 or 2.0 feedFormat = SyndicationFormat.Rss; rssNamespaceUri = feedReader.NamespaceURI; do { feedReader.Read(); //go to end of 'rss' start tag feedReader.MoveToContent(); //go to the next element localname = feedReader.LocalName; } while (localname != nameRefs[(int)NameTableIndexes.channel]); } else if (feedReader.NamespaceURI.Equals("http://purl.org/atom/ns#") && (localname == nameRefs[(int)NameTableIndexes.feed])) { //Atom 0.3 rssNamespaceUri = feedReader.NamespaceURI; if (feedReader.MoveToAttribute("version") && feedReader.Value.Equals("0.3")) { feedFormat = SyndicationFormat.Atom; feedReader.MoveToElement(); //move back to 'feed' start element } else { throw new ApplicationException("ExceptionUnsupportedAtomVersion"); } } else { throw new ApplicationException("ExceptionUnknownXmlDialect"); } feed = new Feed(); ProcessFeedElements(feed, feedReader, rssNamespaceUri, feedFormat, optionalElements, items, defaultItemDate); } finally { feedReader.Close(); } feedReader = null; nameRefs = null; // if (feed != null) // { // feed.Items = (FeedItem[])items.ToArray(typeof(FeedItem)); // } return(feed); }
private static void ProcessFeedElements(Feed feed, XmlReader reader, string rssNamespaceUri, SyndicationFormat format, Hashtable optionalElements, ArrayList items, DateTime defaultItemDate) { bool matched = false; //indicates whether this is a known element bool nodeRead = false; //indicates whether the last node was read using XmlDocument.ReadNode() //string feedTitle = ""; //string feedDescription = ""; //string feedLink = ""; DateTime channelBuildDate = DateTime.MinValue; if ((format == SyndicationFormat.Rdf) || (format == SyndicationFormat.Rss)) { while ((nodeRead || reader.Read()) && reader.NodeType != XmlNodeType.EndElement) { object localname = reader.LocalName; object namespaceuri = reader.NamespaceURI; matched = false; nodeRead = false; if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.NamespaceURI.Equals(rssNamespaceUri) || reader.NamespaceURI.Equals(String.Empty)) { if (localname == nameRefs[(int)NameTableIndexes.title]) { if (!reader.IsEmptyElement) { feed.Title = ReadElementString(reader); } matched = true; } else if (localname == nameRefs[(int)NameTableIndexes.description]) { if (!reader.IsEmptyElement) { feed.Description = ReadElementString(reader); } matched = true; } else if (localname == nameRefs[(int)NameTableIndexes.link]) { if (!reader.IsEmptyElement) { feed.Link = ReadElementString(reader); } matched = true; } else if (localname == nameRefs[(int)NameTableIndexes.lastbuilddate]) { try { if (!reader.IsEmptyElement) { feed.LastBuildDate = DateTimeExt.Parse(ReadElementString(reader)); } } catch (FormatException fex) { System.Diagnostics.Debug.WriteLine(fex.ToString()); //_log.Warn("Error parsing date from channel {" + feedTitle + // "} from feed {" + (feedLink == null ? f.title : feedLink) + "}: ", fex); } finally { matched = true; } } else if (localname == nameRefs[(int)NameTableIndexes.items]) { reader.Skip(); matched = true; } else if ((localname == nameRefs[(int)NameTableIndexes.image]) && format == SyndicationFormat.Rdf) { reader.Skip(); matched = true; } else if (localname == nameRefs[(int)NameTableIndexes.item]) { if (!reader.IsEmptyElement) { FeedItem rssItem = MakeFeedItem(reader, defaultItemDate); if (rssItem != null) { rssItem.Parent = feed; //items.Add(rssItem); feed.Items.Add(rssItem); } } matched = true; } } else if (namespaceuri == nameRefs[(int)NameTableIndexes.ns_bandit_2003]) { if (localname == nameRefs[(int)NameTableIndexes.maxitemage]) { if (!reader.IsEmptyElement) { // get the old v1.2 value from cached feed // We used the TimeSpan.Parse() / maxItemAge.ToString() there, so we cannot simply take over the string. // Instead we convert to TimeSpan, then convert to valid xs:duration datatype to proceed correctly //f.maxitemage = XmlConvert.ToString(TimeSpan.Parse(ReadElementString(reader))); //f.maxitemage = ReadElementString(reader); } matched = true; } } if (!matched) { XmlQualifiedName qname = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI); XmlNode optionalNode = optionalElementsDoc.ReadNode(reader); if (!optionalElements.Contains(qname)) { optionalElements.Add(qname, optionalNode); } nodeRead = true; } //if(!matched) } //while if (format == SyndicationFormat.Rdf) { reader.ReadEndElement(); //move to <image> or first <item>. do { object localname = reader.LocalName; nodeRead = false; if ((localname == nameRefs[(int)NameTableIndexes.image]) && reader.NamespaceURI.Equals(rssNamespaceUri)) { //RSS 1.0 can have <image> outside <channel> XmlNode optionalNode = optionalElementsDoc.ReadNode(reader); ((XmlElement)optionalNode).SetAttribute("xmlns", String.Empty); //change namespace decl to no namespace XmlQualifiedName qname = new XmlQualifiedName(optionalNode.LocalName, optionalNode.NamespaceURI); if (!optionalElements.Contains(qname)) { optionalElements.Add(qname, optionalNode); } nodeRead = true; } if ((localname == nameRefs[(int)NameTableIndexes.item]) && reader.NamespaceURI.Equals(rssNamespaceUri)) { if (!reader.IsEmptyElement) { FeedItem rssItem = MakeFeedItem(reader, defaultItemDate); if (rssItem != null) { items.Add(rssItem); } } } } while (nodeRead || reader.Read()); } // if(format == SyndicationFormat.Rdf) } else if (format == SyndicationFormat.Atom) { while ((nodeRead || reader.Read()) && reader.NodeType != XmlNodeType.EndElement) { object localname = reader.LocalName; object namespaceuri = reader.NamespaceURI; matched = false; nodeRead = false; if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.NamespaceURI.Equals(rssNamespaceUri) || reader.NamespaceURI.Equals(String.Empty)) { if (localname == nameRefs[(int)NameTableIndexes.title]) { if (!reader.IsEmptyElement) { feed.Title = ReadElementString(reader); } matched = true; } else if (localname == nameRefs[(int)NameTableIndexes.tagline]) { if (!reader.IsEmptyElement) { feed.Description = ReadElementString(reader); } matched = true; } else if (localname == nameRefs[(int)NameTableIndexes.link]) { string rel = reader.GetAttribute("rel"); string href = reader.GetAttribute("href"); if (feed.Link == String.Empty) { if ((rel != null) && (href != null) && rel.Equals("alternate")) { feed.Link = href; matched = true; } } } else if (localname == nameRefs[(int)NameTableIndexes.modified]) { try { if (!reader.IsEmptyElement) { feed.LastBuildDate = DateTimeExt.Parse(ReadElementString(reader)); } } catch (FormatException fex) { System.Diagnostics.Debug.WriteLine(fex.ToString()); //_log.Warn("Error parsing date from channel {" + feedTitle + // "} from feed {" + (feedLink == null ? f.title : feedLink) + "}: ", fex); } finally { matched = true; } } else if (localname == nameRefs[(int)NameTableIndexes.entry]) { if (!reader.IsEmptyElement) { FeedItem rssItem = MakeFeedItem(reader, defaultItemDate); if (rssItem != null) { items.Add(rssItem); } } matched = true; } } else if (namespaceuri == nameRefs[(int)NameTableIndexes.ns_bandit_2003]) { if (localname == nameRefs[(int)NameTableIndexes.maxitemage]) { if (!reader.IsEmptyElement) { // get the old v1.2 value from cached feed // We used the TimeSpan.Parse() / maxItemAge.ToString() there, so we cannot simply take over the string. // Instead we convert to TimeSpan, then convert to valid xs:duration datatype to proceed correctly TimeSpan maxItemAgeTS = TimeSpan.Parse(ReadElementString(reader)); if (maxItemAgeTS != TimeSpan.MaxValue) { //f.maxitemage = XmlConvert.ToString(maxItemAgeTS); } } matched = true; } } if (!matched) { XmlQualifiedName qname = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI); XmlNode optionalNode = optionalElementsDoc.ReadNode(reader); if (!optionalElements.Contains(qname)) { optionalElements.Add(qname, optionalNode); } nodeRead = true; } //if(!matched) } //while } }
/// <summary> /// Create each item from the SyndicationItem. Necesary to format the Content property with RemoveUnusedElementsAsync /// </summary> /// <param name="item"></param> /// <param name="format"></param> /// <param name="i"></param> /// <returns></returns> private FeedItem CreateFeedItem(SyndicationItem item, SyndicationFormat format, int i) { if (item == null) throw new ArgumentNullException(nameof(item)); var feedItem = new FeedItem {Format = format}; if (item.Title != null) feedItem.Title = item.Title.Text; feedItem.PubDate = item.PublishedDate.DateTime; feedItem.PubDateShow = ApiHelper.GetCustomFormattedDate(item.PublishedDate.DateTime); foreach (var author in item.Authors) { feedItem.Author = author.NodeValue; } if (format == SyndicationFormat.Atom10) { feedItem.Content = item.Content.Text; } else if (format == SyndicationFormat.Rss20) { feedItem.Content = item.Summary.Text; } feedItem.ImageUrl = GeekyHelper.ExtractFirstImageFromHtml(feedItem.Content); feedItem.Content = string.Empty; if (item.Links.Count > 0) { feedItem.Link = item.Links.FirstOrDefault().Uri; } if (i == 0 || i == 1) { feedItem.ColSpan = 2; feedItem.RowSpan = 2; } else { feedItem.ColSpan = 1; feedItem.RowSpan = 1; } return feedItem; }
/// <summary> /// Sets the response header information. /// </summary> /// <param name="context">An <see cref="HttpContext"/> object that provides references to the intrinsic server objects (for example, <b>Request</b>, <b>Response</b>, <b>Session</b>, and <b>Server</b>) used to service HTTP requests.</param> /// <param name="items">The collection of <see cref="IShowed"/> instances used when setting the response header details.</param> /// <param name="format">The format of the syndication feed being generated.</param> /// <exception cref="ArgumentNullException">The <paramref name="context"/> is a null reference (Nothing in Visual Basic) -or- the <paramref name="posts"/> is a null reference (Nothing in Visual Basic).</exception> private static void SetHeaderInformation(HttpContext context, List<IShowed> items, SyndicationFormat format) { DateTime lastModified = DateTime.Now; bool notModified = false; string eTag = context.Request.Headers["If-None-Match"]; string ifModifiedSince = context.Request.Headers["if-modified-since"]; if (items.Count > 0) { lastModified = (items[0].DateModified > items[0].DateCreated ? items[0].DateModified : items[0].DateCreated); } if (!String.IsNullOrEmpty(eTag)) { notModified = eTag.Equals(lastModified.Ticks.ToString()); } else { if (!String.IsNullOrEmpty(ifModifiedSince)) { // ifModifiedSince can have a length param in there // If-Modified-Since: Wed, 29 Dec 2004 18:34:27 GMT; length=126275 if (ifModifiedSince.IndexOf(";") > -1) { ifModifiedSince = ifModifiedSince.Split(';').GetValue(0).ToString(); } DateTime ifModifiedDate; if (DateTime.TryParse(ifModifiedSince, out ifModifiedDate)) { notModified = (lastModified <= ifModifiedDate); } } } if (notModified) { context.Response.StatusCode = 304; context.Response.SuppressContent = true; context.Response.End(); } else { context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.Cache.SetLastModified(DateTime.Now); context.Response.Cache.SetETag(lastModified.Ticks.ToString()); switch (format) { case SyndicationFormat.Atom: context.Response.ContentType = "application/atom+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=atom.xml"); break; case SyndicationFormat.Rss: context.Response.ContentType = "application/rss+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=rss.xml"); break; } } }
/// <summary> /// Sets the response header information. /// </summary> /// <param name="context">An <see cref="HttpContext"/> object that provides references to the intrinsic server objects (for example, <b>Request</b>, <b>Response</b>, <b>Session</b>, and <b>Server</b>) used to service HTTP requests.</param> /// <param name="items">The collection of <see cref="IPublishable"/> instances used when setting the response header details.</param> /// <param name="format">The format of the syndication feed being generated.</param> /// <exception cref="ArgumentNullException">The <paramref name="context"/> is a null reference (Nothing in Visual Basic) -or- the <paramref name="posts"/> is a null reference (Nothing in Visual Basic).</exception> private static void SetHeaderInformation(HttpContext context, List <IPublishable> items, SyndicationFormat format) { DateTime lastModified = DateTime.MinValue; foreach (IPublishable item in items) { if (item.DateModified > lastModified) { lastModified = item.DateModified; } } switch (format) { case SyndicationFormat.Atom: context.Response.ContentType = "application/atom+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=atom.xml"); break; case SyndicationFormat.Rss: context.Response.ContentType = "application/rss+xml"; context.Response.AppendHeader("Content-Disposition", "inline; filename=rss.xml"); break; } if (Utils.SetConditionalGetHeaders(lastModified)) { context.Response.End(); } }