根据向 Microsoft 发布的错误报告中发布的解决方法,我制作了一个 XmlReader,专门用于读取具有非标准日期的 SyndicationFeeds。
下面的代码与 Microsoft 网站上的解决方法中的代码略有不同。它还采纳了反对党关于使用 RFC 1123 模式的建议。
您需要从 Stream 创建 XmlReader,而不是简单地调用 XmlReader.Create()。我使用 WebClient 类来获取该流:
WebClient client = new WebClient();
using (XmlReader reader = new SyndicationFeedXmlReader(client.OpenRead(feedUrl)))
{
SyndicationFeed feed = SyndicationFeed.Load(reader);
....
//do things with the feed
....
}
下面是 SyndicationFeedXmlReader 的代码:
public class SyndicationFeedXmlReader : XmlTextReader
{
readonly string[] Rss20DateTimeHints = { "pubDate" };
readonly string[] Atom10DateTimeHints = { "updated", "published", "lastBuildDate" };
private bool isRss2DateTime = false;
private bool isAtomDateTime = false;
public SyndicationFeedXmlReader(Stream stream) : base(stream) { }
public override bool IsStartElement(string localname, string ns)
{
isRss2DateTime = false;
isAtomDateTime = false;
if (Rss20DateTimeHints.Contains(localname)) isRss2DateTime = true;
if (Atom10DateTimeHints.Contains(localname)) isAtomDateTime = true;
return base.IsStartElement(localname, ns);
}
public override string ReadString()
{
string dateVal = base.ReadString();
try
{
if (isRss2DateTime)
{
MethodInfo objMethod = typeof(Rss20FeedFormatter).GetMethod("DateFromString", BindingFlags.NonPublic | BindingFlags.Static);
Debug.Assert(objMethod != null);
objMethod.Invoke(null, new object[] { dateVal, this });
}
if (isAtomDateTime)
{
MethodInfo objMethod = typeof(Atom10FeedFormatter).GetMethod("DateFromString", BindingFlags.NonPublic | BindingFlags.Instance);
Debug.Assert(objMethod != null);
objMethod.Invoke(new Atom10FeedFormatter(), new object[] { dateVal, this });
}
}
catch (TargetInvocationException)
{
DateTimeFormatInfo dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
return DateTimeOffset.UtcNow.ToString(dtfi.RFC1123Pattern);
}
return dateVal;
}
}
同样,这几乎完全是从上面链接中 Microsoft 网站上发布的解决方法复制而来的。...除了这个对我有用,而在微软发布的那个没有。
注意:您可能需要做的一点定制是在课程开始时的两个数组中。根据您的非标准提要可能添加的任何无关字段,您可能需要向这些数组添加更多项目。