public virtual async Task <RssChannel> GetChannel(CancellationToken cancellationToken = default(CancellationToken)) { var project = await ProjectService.GetCurrentProjectSettings(); if (project == null) { return(null); } var itemsToGet = project.DefaultFeedItems; var requestedFeedItems = ContextAccessor.HttpContext?.Request.Query["maxItems"].ToString(); if (!string.IsNullOrWhiteSpace(requestedFeedItems)) { int.TryParse(requestedFeedItems, out itemsToGet); if (itemsToGet > project.MaxFeedItems) { itemsToGet = project.MaxFeedItems; } } var posts = await BlogService.GetRecentPosts(itemsToGet); if (posts == null) { return(null); } var channel = new RssChannel { Title = project.Title, Copyright = project.CopyrightNotice, Generator = Name, RemoteFeedUrl = project.RemoteFeedUrl, RemoteFeedProcessorUseAgentFragment = project.RemoteFeedProcessorUseAgentFragment }; if (!string.IsNullOrEmpty(project.Description)) { channel.Description = project.Description; } else { // prevent error, channel desc cannot be empty channel.Description = "Welcome to my blog"; } if (!string.IsNullOrEmpty(project.ChannelCategoriesCsv)) { var channelCats = project.ChannelCategoriesCsv.Split(','); foreach (var cat in channelCats) { channel.Categories.Add(new RssCategory(cat)); } } var urlHelper = UrlHelperFactory.GetUrlHelper(ActionContextAccesor.ActionContext); if (!string.IsNullOrEmpty(project.Image)) { channel.Image.Url = new Uri(urlHelper.Content(project.Image)); } if (!string.IsNullOrEmpty(project.LanguageCode)) { channel.Language = new CultureInfo(project.LanguageCode); } var baseUrl = string.Concat( ContextAccessor.HttpContext.Request.Scheme, "://", ContextAccessor.HttpContext.Request.Host.ToUriComponent() ); // asp.net bug? the comments for this method say it returns an absolute fully qualified url but it returns relative // looking at latest code seems ok so maybe just a bug in rc1 //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/UrlHelperExtensions.cs //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/Routing/UrlHelper.cs var indexUrl = urlHelper.RouteUrl(BlogRoutes.BlogIndexRouteName); if (indexUrl == null) { indexUrl = urlHelper.Action("Index", "Blog"); } if (indexUrl.StartsWith("/")) { indexUrl = string.Concat(baseUrl, indexUrl); } channel.Link = new Uri(indexUrl); if (!string.IsNullOrEmpty(project.ManagingEditorEmail)) { channel.ManagingEditor = project.ManagingEditorEmail; } if (!string.IsNullOrEmpty(project.ChannelRating)) { channel.Rating = project.ChannelRating; } var feedUrl = string.Concat( ContextAccessor.HttpContext.Request.Scheme, "://", ContextAccessor.HttpContext.Request.Host.ToUriComponent(), ContextAccessor.HttpContext.Request.PathBase.ToUriComponent(), ContextAccessor.HttpContext.Request.Path.ToUriComponent(), ContextAccessor.HttpContext.Request.QueryString.ToUriComponent()); channel.SelfLink = new Uri(feedUrl); channel.TimeToLive = project.ChannelTimeToLive; if (!string.IsNullOrEmpty(project.WebmasterEmail)) { channel.Webmaster = project.WebmasterEmail; } DateTime mostRecentPubDate = DateTime.MinValue; var items = new List <RssItem>(); foreach (var post in posts) { if (!post.PubDate.HasValue) { continue; } if (post.PubDate.Value > mostRecentPubDate) { mostRecentPubDate = post.PubDate.Value; } var rssItem = new RssItem { Author = post.Author }; if (post.Categories.Count > 0) { foreach (var c in post.Categories) { rssItem.Categories.Add(new RssCategory(c)); } } var postUrl = await BlogUrlResolver.ResolvePostUrl(post, project).ConfigureAwait(false); if (string.IsNullOrEmpty(postUrl)) { //TODO: log continue; } if (postUrl.StartsWith("/")) { //postUrl = urlHelper.Content(postUrl); postUrl = string.Concat( ContextAccessor.HttpContext.Request.Scheme, "://", ContextAccessor.HttpContext.Request.Host.ToUriComponent(), postUrl); } var filteredResult = ContentProcessor.FilterHtmlForRss(post, project, baseUrl); rssItem.Description = filteredResult.FilteredContent; if (!filteredResult.IsFullContent) { //TODO: localize var readMore = " <a href='" + postUrl + "'>...read more</a>"; rssItem.Description += readMore; } //rssItem.Enclosures rssItem.Guid = new RssGuid(postUrl, true); rssItem.Link = new Uri(postUrl); rssItem.PublicationDate = post.PubDate.Value; //rssItem.Source rssItem.Title = post.Title; items.Add(rssItem); } channel.PublicationDate = mostRecentPubDate; channel.Items = items; return(channel); }