Разбор RSS 1.0 с C # / MVC 2 - PullRequest
       11

Разбор RSS 1.0 с C # / MVC 2

0 голосов
/ 19 апреля 2011

Во-первых, я не могу поверить, что кто-то в 2011 году все еще использует RSS 1.0, думаю, вы действительно узнаете что-то новое. Что ж, я пытаюсь разобрать их фид и разместить контент на моем клиентском сайте (я получил разрешения, поэтому здесь нет нарушений закона). Как вы можете себе представить, моя первая попытка с треском провалилась (был написан код для 2.0), поэтому я вернулся к чертежной доске и вот что я придумал.

RssController

public virtual ActionResult Index()
{
    List<RssFeedItem> rssList = new List<RssFeedItem>();
    XmlDocument doc = new XmlDocument();
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
    manager.AddNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/");

    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php");

    doc.Load(reader);

    XmlNodeList nodes = doc.SelectNodes("/rdf:RDF//rss:item",manager);

        foreach(XmlNode node in nodes)
        {
            XmlNodeList aboutNode = node.SelectNodes("rss:about", manager);
            XmlNodeList titleNode = node.SelectNodes("rss:title", manager);
            XmlNodeList linkNode = node.SelectNodes("rss:link", manager);

            var item = new RssFeedItem
            {
                Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText,
                Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText,
                About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText


            };
            rssList.Add(item);
        }
        return View(rssList); 
}

Я пытаюсь сделать это, используя частичное представление (ascs), и это выглядит так

index.aspx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Models.RssFeedItem>" %>

<%
    foreach (RssFeedItem item in (IEnumerable<RssFeedItem>)ViewData.Model)
    {
        Response.Write(string.Format("<div id={0}><a href={1} target=\"_blank\" /> <strong>{2}</strong></div>",
          Model.About.Truncate(5), Model.Link, Model.Title.Truncate(25)));
    } %>

Затем я пытаюсь использовать RenderPartial в mySite.Master

.
<% Html.RenderPartial("Index");%>

Проблема в том, что сайт никогда даже не загружается или даже выдает какую-то ошибку, он просто вращается, когда вращается значок загрузки FF.

EDIT

Ну, я сделал несколько существенных изменений в своем коде из предыдущего, и тот же результат, без ошибок, и он даже не загружает сайт (просто сидит и вращается). Вот код из контроллера

[MoveFormsScript]
[CanonicalUrlAttribute("Rss")]
public virtual ActionResult Index()
{
    return View(new RssList());
} 

Теперь код из RssList

[UIHint("Feeds")]
public SelectList Feeds { get; private set; }

[Required(ErrorMessage = "Rss Feeduired")]
public string Feed { get; set; }

public RssList()
{
    this.Feeds = GetRssFeed(null);
} 

public SelectList GetRssFeed(string selectedValue)
{
    List<RssFeedItem> rssList = new List<RssFeedItem>();
    XmlDocument doc = new XmlDocument();
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
    manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#");
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/");

    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php");

    doc.Load(reader);

    XmlNodeList nodes = doc.SelectNodes("/rdf:RDF//rss:item", manager);

    foreach (XmlNode node in nodes)
    {
        XmlNodeList aboutNode = node.SelectNodes("rss:about", manager);
        XmlNodeList titleNode = node.SelectNodes("rss:title", manager);
        XmlNodeList linkNode = node.SelectNodes("rss:link", manager);

        var item = new RssFeedItem
        {
            Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText,
            Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText,
            About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText


        };
        rssList.Add(item);
    }
    return new SelectList(rssList, "Link", "Title", selectedValue);
} 

И, наконец, мой частичный взгляд

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Helpers.BusinessDTO.RssList>" %>

<%
    foreach (var item in (IEnumerable<RssList>)ViewData.Model)
    {
        Response.Write(string.Format("<div id=\"{0}\"><a href=\"{1}\" target=\"_blank\" /> <strong>{2}</strong></div>",
           item.Feed[0].ToString().Truncate(10), item.Feed[1], item.Feed[2].ToString().Truncate(100)));

    } %>

Кто-нибудь может мне помочь?

Ответы [ 5 ]

1 голос
/ 21 апреля 2011

Изменить экземпляр XmlNodeList класса RssList на:

XmlNodeList nodes = doc.SelectNodes("//rss:item[./rss:link]", manager);

Затем измените ваш ViewUserControl на:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %><ul>
<%  
    RssList viewModel = ViewData.Model as RssList;

    if (viewModel.Feeds.Count() > 0)
    {
        foreach (SelectListItem item in viewModel.Feeds)
        { %>
<li>
    <%
            Response.Write(String.Format("<a href='{0}' target='_blank'>{1}</a>", item.Value, item.Text));
        }%>
</li>
<%
    }
%></ul>

Кажется, работает на меня.

1 голос
/ 21 апреля 2011

Здесь я вижу несколько проблем. Ваш элемент управления ожидает один RssList, контроллер возвращает список выбора, а ваш foreach перечисляет то, что он считает IEnumerable . Кроме того, вы делаете ручные response.writes в частичном представлении. Разметка будет чище, если вы этого не сделаете.

Давайте сначала начнем с класса RssList. Похоже, ваш первый подход на самом деле был тем, что вы хотели, проблема была в том, что вы делали в частичном представлении.

public class RssList
{
  [UIHint("Feeds")]
  public IEnumerable<RssFeedItem> Feeds { get; private set; }

  [Required(ErrorMessage = "Rss Feed Required")]
  public string Feed { get; set; }

  public RssList()
  {
    this.Feeds = GetRssFeed(null);
  }

  public IEnumerable<RssFeedItem> GetRssFeed(string selectedValue)
  {
    List<RssFeedItem> rssList = new List<RssFeedItem>();
    XmlDocument doc = new XmlDocument();
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
    manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#");
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/");
    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php");
    doc.Load(reader);
    XmlNodeList nodes = doc.SelectNodes(
      "/rdf:RDF//rss:item[./rss:link./rss:title./rss:about]", manager);

    foreach (XmlNode node in nodes)
    {
      XmlNodeList aboutNode = node.SelectNodes("rss:about", manager);
      XmlNodeList titleNode = node.SelectNodes("rss:title", manager);
      XmlNodeList linkNode = node.SelectNodes("rss:link", manager);
      var rssItem = new RssFeedItem
      {
        Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText,
        Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText,
        About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText
      };
      rssList.Add(rssItem);
    }
    return rssList;
  }
}

Теперь вместо SelectList мы возвращаем IEnumerable . Желательно не манипулировать пользовательским интерфейсом из кода, если это возможно. Итак, давайте посмотрим, нужно ли нам творить магию на контроллере. Единственное, что я вижу, это то, что вы можете исключить «Index» из функции View (подразумевается, что это имя операции контроллера.

return PartialView(viewModel);

Теперь перейдем к представлению ... давайте посмотрим, сможем ли мы сделать его лучше

<%@ Control Language="C#"
   Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Helpers.BusinessDTO.RssList>" %>

<%       
    foreach (var rssItem in ViewData.Model.Feeds)
    {
%>
   <div id="<%=rssItem.Title%>">
     <a href="<%=rssItem.Link%>" target="_blank">
     <strong><%=rssItem.Title%></strong>
     </a>
<%
    } 
%>

Там я думаю, что это должно сделать для вас ... дайте мне знать, если у вас возникнут какие-либо проблемы.

1 голос
/ 20 апреля 2011

Я не очень знаком с классом System.Web.Mvc.SelectList, тем более с пространством имен, но я заметил, что вы используете строку для параметра selectedValue.Должен ли это быть объект RssFeedItem вместо этого?

[править] Пробежал раздел кода xml через некоторые препятствия PowerShell, и вот что я получил.

$doc = New-Object Xml.XmlDocument;
$manager = New-Object Xml.XmlNamespaceManager $doc.NameTable;
$manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#");
$manager.AddNamespace("rss", "http://purl.org/rss/1.0/");

$reader = New-Object Xml.XmlTextReader("http://wdfw.wa.gov/news/newsrss.php");

$doc.Load($reader);

#doesn't work
"Doesn't work"
$doc.SelectNodes("//rss:item[./rss:link./rss:title./rss:about]", $manager) | measure | select count
#this is an invalid xpath query, there are no operators between the nodes specified in the [].
#Also, in the xml document we're looking at, there is no node named "about". "about" is an attibute to the "item" node.

#works
"Works"
$doc.SelectNodes("//rss:item[./rss:link and ./rss:title]", $manager) | measure | select count
#Even though we only have the "link" and "title" nodes in the [], everything is returned.
#That's because we're telling SelectNodes to return the "item" nodes themselves.
0 голосов
/ 20 апреля 2011

Внесены некоторые изменения для тех, кто пытается мне помочь. Вот код контроллера

   [MoveFormsScript]
        [CanonicalUrlAttribute("Rss")]
        public virtual ActionResult Index()
        {
            var viewModel = new RssList();
            return PartialView("Index", viewModel);
        }    

Затем я создал класс (RssList), в котором выполняется основная часть работы

RssList

[UIHint("Feeds")]
public SelectList Feeds { get; private set; }

    [Required(ErrorMessage = "Rss Feed Required")]
    public string Feed { get; set; }

    public RssList()
    {
        this.Feeds = GetRssFeed(null);
    }



public SelectList GetRssFeed(string selectedValue)
{
    List<RssFeedItem> rssList = new List<RssFeedItem>();
    XmlDocument doc = new XmlDocument();
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
    manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#");
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/");

    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php");

    doc.Load(reader);

    XmlNodeList nodes = doc.SelectNodes("/rdf:RDF//rss:item[./rss:link./rss:title./rss:about]", manager);

    foreach (XmlNode node in nodes)
    {
        XmlNodeList aboutNode = node.SelectNodes("rss:about", manager);
        XmlNodeList titleNode = node.SelectNodes("rss:title", manager);
        XmlNodeList linkNode = node.SelectNodes("rss:link", manager);

        var rssItem = new RssFeedItem
        {
            Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText,
            Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText,
            About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText


        };
        rssList.Add(rssItem);
    }
    return new SelectList(rssList, "Link", "Title", selectedValue);
}

Это Index.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Helpers.BusinessDTO.RssList>" %>

<%       
    foreach (RssList rssItem in ViewData.Model)
    {
        Response.Write(string.Format("<div id=\"{0}\"><a href=\"{1}\" target=\"_blank\" /> <strong>{2}</strong></div>",
           rssItem.Feed[0].ToString().Truncate(10), rssItem.Feed[1], rssItem.Feed[2].ToString().Truncate(100)));

    } %>

И обычный звонок

 <% Html.RenderPartial("Index");%>

}

FeedItemCass используя Систему; using System.Collections.Generic; использование System.Linq; использование System.Web;

namespace GodsCreationTaxidermy.Models
{
    public class RssFeedItem
    {
        public string Link { get; set; }
        public string Title { get; set; }
        public string About { get; set; }
    }
}
0 голосов
/ 20 апреля 2011

Может ли мод объединить этот фид с этим MVC2 - использовать фид RSS с RDF и пространством имен http://www.w3.org/1999/02/22-rdf-syntax-ns#'. Я забыл, что уже спросил

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...