Каков наилучший способ использования MVC + ajax (jquery) для загрузки содержимого страницы, aspx или ascx или обоих - PullRequest
0 голосов
/ 29 марта 2010

Я хочу иметь меню, которое при щелчке заменяет содержимое «основного» div содержимым из представления mvc. Это прекрасно работает, если я использую страницу .aspx, но любое содержимое master.page затем удваивается (как и любые css / js). Если я делаю то же самое, но использую пользовательский элемент управления .ascx, содержимое загружается без дополнений, но если какой-либо браузер загружает элемент меню напрямую (т.е. поисковый бот или кто-то с отключенным JS), страница отображается без содержимого master.page ,

Лучшее решение, которое я нашел на данный момент, - это создать контент в виде страницы .ascx, а затем загрузить страницу .aspx, если она вызывается непосредственно из ссылки меню, в то время как javascript ajax изменит ссылку для использования. только .ascx. Это приводит к значительному дублированию, поскольку каждому пользовательскому элементу управления нужна своя страница .aspx.

Мне было интересно, есть ли лучший способ сделать это? Например, может ли master.page скрыть все, что не находится на странице .aspx, если он был вызван с параметром? Ajax = true?

Ответы [ 3 ]

1 голос
/ 19 апреля 2010

Мы решили это с помощью класса baseController, от которого наследуются все контроллеры, и с помощью переопределения для OnActionExecuted:

    /// <summary>
    /// Changes the masterpage to a slim version in AjaxRequest
    /// </summary>
    /// <param name="filterContext"></param>
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var action = filterContext.Result as ViewResult;
        if (action != null && Request.IsAjaxRequest())
        {
            action.MasterName = "Ajax";
        }
        base.OnActionExecuted(filterContext);
    }

Мастер-страница Ajax - это простая мастер-страница, содержащая только 1 contentPlaceHolder. Это прекрасно работает, если все страницы aspx, которые могут быть вызваны с помощью ajax, используют только этот заполнитель.

0 голосов
/ 29 марта 2010

Вот пример метода, который я использую с большим успехом:

В представлении:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Namespace.Stuff>>" %>

<asp:Content ID="Content3" ContentPlaceHolderID="head" runat="server">
    <script type="text/javascript">
     $(document).ready(function(){
        $("#optionsForm").submit(function() {
            $("#loading").dialog('open');
            $.ajax({
                type: $("#optionsForm").attr("method"),
                url: $("#optionsForm").attr("action"),
                data: $("#optionsForm").serialize(),
                success: function(data, textStatus, XMLHttpRequest) {
                    $("#reports").html(data); //replace the reports html.
                    $("#loading").dialog('close'); //hide loading dialog.
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    $("#loading").dialog('close'); //hide loading dialog.
                    alert("Yikers! The AJAX form post didn't quite go as planned...");
                }
            });
            return false; //prevent default form action
        });
    });
    </script>
</asp:Content>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

    <div id="someContent">
        <% using (Html.BeginForm("Index", "Reports", FormMethod.Post, new{ id = "optionsForm" }))
          { %>

          <fieldset class="fieldSet">
            <legend>Date Range</legend>
            From: <input type="text" id="startDate" name="startDate" value="<%=ViewData["StartDate"] %>" />
            To: <input type="text" id="endDate" name="endDate" value="<%=ViewData["EndDate"] %>" />
            <input type="submit" value="submit" />
          </fieldset>

        <%} %>
    </div>

    <div id="reports">
        <%Html.RenderPartial("ajaxStuff", ViewData.Model); %>
    </div>

    <div id="loading" title="Loading..." ></div>
</asp:Content>

В контроллере:

public ActionResult Index(string startDate, string endDate)
{
    var returnData = DoSomeStuff();

    if (Request.IsAjaxRequest()) return View("ajaxStuff", returnData);
    return View(returnData);
}
0 голосов
/ 29 марта 2010

А как насчет создания ActionMethod, который меняет то, что он отображает, в зависимости от типа получаемого http-запроса? Таким образом, если это ajax-запрос, он будет отображать ascx, но если это не так, то он может отображать весь вид (или перенаправлять на другое действие, которое отображает весь вид)?

что-то вроде

public ActionResult Section1()
{
    if (Request.IsAjaxRequest())
    {
        return PartialView("section1.ascx");
    }

    return View("section.aspx");
}

и я предполагаю, что section.aspx coud есть внутри RenderPartial (section1.ascx) (так что вы не делаете страницу дважды).

...