我应该如何使用ASP.NET MVC部分视图处理异常?

时间:2010-08-23 17:35:56

标签: asp.net-mvc asp.net-mvc-2 exception-handling

我有一个局部视图(ascx),用于显示一个人的RSS提要的前x篇文章:

<%@ 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提要不应该如此具有破坏性,以至于它会将用户排除在完整的错误页面之外。

解决:

部分视图和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
);

2 个答案:

答案 0 :(得分:3)

更简洁的方法是使用调用操作的RenderAction来加载Feed数据然后捕获错误。

ServicesController上的

RssWidget操作(实际上可以驻留在每个控制器中,无所谓,但我认为,这是一个干净的解决方案):
此操作会从Feed中加载文章。请注意,代码只是演示,您必须通过加载文章的实现替换RssService.GetArticles()。如果一切顺利,将返回一个PartialView(名为RssWidget.ascx),显示文章列表。

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的视图。您可以在任何视图中渲染此“小部件”。 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>
...

答案 1 :(得分:1)

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

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

相关问题