2010-08-23 101 views
3

我有用于显示一个人的RSS提要顶的X文章的局部视图(ASCX):我应该如何处理ASP.NET MVC部分视图的异常?

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

    <% foreach (var item in Model) { %> 

     <a href="<%: item.Url %>"><%: item.Title %></a><br /> 
     <%: String.Format("{0:g}", item.Date) %><br /> 
     <%: item.Body %> 
     <br /> 

    <% } %> 

另外,我有需要的RSS URL,并返回一个IEnumerable类型物品的方法:

public static class ArticleFeedHelper 
{ 
    public static IEnumerable<Models.Article> GetArticles(string feedUrl) 
    { 
     // Uncaught exception can happen here (e.g. 404, malformed RSS, etc.) 
    } 
} 

在我的视图中的一个,我称这样的局部视图:

<div id="articleList" class="section"> 
    <div class="sectionTitle">My Recent Articles</div> 
    <hr /> 
    <div class="sectionBody"> 
     <% Html.RenderPartial("ArticleList", ArticleFeedHelper.GetArticles(Model.RSSFeed)); %> 
    </div> 
</div> 

的问题是,我想表面的错误消息到主视图。仅仅因为RSS提要不能被检索到,不应该如此具有破坏性,以至于无法将用户投放到完整的错误页面。

RESOLUTION:

局部视图,和ArticleFeedHelper保持不变。

使用Dave's建议,主视图改变为:

<div id="articleList" class="section"> 
    <div class="sectionTitle">My Recent Articles</div> 
    <hr /> 
    <div class="sectionBody"> 
     <% Html.RenderAction("ArticleList", "ArticleList", new { feedUrl = Model.RSSFeed }); %> 
    </div> 
</div> 

加入甲局部控制器:

public class ArticleListController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [ChildActionOnly] 
    public ActionResult ArticleList(string feedUrl) 
    { 
     try 
     { 
      IEnumerable<Models.Article> articles = Helpers.ArticleFeedHelper.GetArticles(feedUrl); 
      return PartialView(articles); 
     } 
     catch (Exception ex) 
     { 
      // Handle the error and return an error partial view 
     } 
    } 
} 

并加入路线:

routes.MapRoute(
    "ArticleList", // Route name 
    "{controller}/{action}/{feedUrl}", // URL with parameters 
    new { controller = "ArticleList", action = "ArticleList", feedUrl = "" } // Parameter defaults 
); 

回答

3

更简洁的方法是使用RenderAction调用一个动作,该动作加载馈送数据,然后可以捕获错误。

上ServicesController RssWidget行动(实际上可以驻留在每个控制器,无所谓,但我觉得,这是一个干净的解决方案):
这个动作装载来自饲料中的文章。请注意,代码仅用于演示,您必须通过加载文章的实施来替换RssService.GetArticles()。如果一切正常,则返回PartialView(名为RssWidget.ascx),该PartialView显示文章列表。

public ServicesController : Controller 
{ 
    public ActionResult RssWidget() 
    { 
     try 
     { 
      var articles = RssService.GetArticles() // or whatever the articles' 
                // source is 
      return PartialView(articles); 
     } 
     catch 
     { 
      return PartialView("Error"); 
     } 
    } 
} 

RssWidget.ascx:这是用于呈现的物品列表中的(局部的)图。不要忘记您的实际类型替换为Article文章:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Article>>" %> 

<% foreach(var article in Model) { %> 
    <div class="article"> 
     <h3><%= Html.Encode(article.Title) %></h3> 
     ... 
    </div> 
<% } %> 

其中显示RssWidget观。你可以在任何视图中渲染这个“widget”。RenderAction("RssWidget", "Services")通知框架在ServicesController上执行RssWidget操作并将结果插入到实际视图中。

... 
<div id="articleList" class="section"> 
    <div class="sectionTitle">My Recent Articles</div> 
    <hr /> 
    <div class="sectionBody"> 
     <% Html.RenderAction("RssWidget", "Services"); %> 
    </div> 
</div> 
... 
+0

我喜欢这个想法,但是Model是如何传递给控制器​​的? – 2010-08-23 21:30:01

+0

对不起,我混了一些东西。我现在已经扩大了我的答案,我希望现在更清楚。 – davehauser 2010-08-24 18:33:03

1

我个人将不包括检索作为视图模板一部分的文章。我不认为这是对数据(控制器和模型)的收集和处理以及数据(视图)的呈现的纯粹分离。

您可能想尝试检索控制器甚至模型中的文章列表,具体取决于您如何处理服务风格依赖关系(我更偏重于此控制器)。然后让您的视图能够处理将文章列表传递给部分,如果它有一个或显示收集数据期间发生的任何异常。