Основываясь на обходном пути, опубликованном в отчете об ошибке в Microsoft об этом Я создал XmlReader специально для чтения SyndicationFeeds с нестандартными датами.
Приведенный ниже код немного отличается от кода в обходном пути на сайте Microsoft. Также требуется совет Оппозиционного по использованию паттерна RFC 1123.
Вместо простого вызова XmlReader.Create () вам необходимо создать XmlReader из потока. Я использую класс 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 по ссылке выше. ... за исключением того, что это работает для меня, а тот, что размещен в Microsoft, не.
ПРИМЕЧАНИЕ : один бит настройки, который вам может понадобиться, находится в двух массивах в начале класса. В зависимости от каких-либо посторонних полей, которые может добавить ваш нестандартный фид, вам может понадобиться добавить больше элементов в эти массивы.