Как мне обработать исключение с частичным представлением ASP.NET MVC? - PullRequest
3 голосов
/ 23 августа 2010

У меня есть частичное представление (ascx) для отображения первых x статей RSS-канала человека:

<%@ 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 />

    <% } %>

Кроме того, у меня есть метод, который принимает URL-адрес RSS и возвращает IEnumerable типа Article:

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 остались прежними.

Используя Дейва предложения, основной вид был изменен на:

<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 ]

3 голосов
/ 23 августа 2010

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

Действие RssWidget на ServicesController (фактически может находиться вкаждый контроллер не имеет значения, но я думаю, что это чистое решение):
Это действие загружает статьи из канала.Обратите внимание, что код является только демонстрационным, и вы должны заменить 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") указывает платформе выполнить действие RssWidget на ServicesController и вставить результат в фактическое представление.

...
<div id="articleList" class="section">
    <div class="sectionTitle">My Recent Articles</div>
    <hr />
    <div class="sectionBody">
        <% Html.RenderAction("RssWidget", "Services"); %>
    </div>
</div>
...
1 голос
/ 23 августа 2010

Лично я не включил бы поиск статей как часть шаблона представления.Я не думаю, что это четкое разделение сбора и обработки данных (контроллеров и моделей) и представления данных (представлений).

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

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