代码之家  ›  专栏  ›  技术社区  ›  Forgotten Semicolon adrianm

我应该如何处理异常ASP.NETMVC局部视图?

  •  3
  • Forgotten Semicolon adrianm  · 技术社区  · 15 年前

    我有一个局部视图(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 />
    
        <% } %>
    

    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提要不能被检索,就不应该造成如此大的破坏性,以至于它会将用户丢弃到一个完整的错误页面。

    分辨率:

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

    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 回复  |  直到 9 年前
        1
  •  3
  •   davehauser    15 年前

    更干净的方法是 RenderAction 这将调用一个操作,该操作加载提要数据,然后可以捕获错误。

    RSwidget操作 在ServicesController上(实际上可以驻留在每个控制器中,这无关紧要,但我认为,这是一个干净的解决方案):
    此操作从提要加载文章。请注意,该代码只是演示,您必须替换 RssService.GetArticles() 通过你的实现载入文章。如果一切顺利rswidget.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");
            }
        }
    }
    

    rswidget.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")

    ...
    <div id="articleList" class="section">
        <div class="sectionTitle">My Recent Articles</div>
        <hr />
        <div class="sectionBody">
            <% Html.RenderAction("RssWidget", "Services"); %>
        </div>
    </div>
    ...
    
        2
  •  1
  •   Sean Copenhaver    15 年前

    我个人不会把文章的检索作为视图模板的一部分。我不认为这是一个干净的分离收集和处理数据(控制器和模型)和数据(视图)的表现。

    您可能希望尝试在控制器甚至模型中检索该项目列表,这取决于您如何处理服务样式依赖项(为此,我更倾向于控制器)。然后让您的视图能够处理将项目列表传递给partial(如果它有一个或显示在数据收集过程中发生的任何异常)。