简体   繁体   English

什么是使用MVC + Ajax(jquery)加载页面内容,aspx或ascx或两者的最佳方法

[英]Whats the best way of using MVC + ajax (jquery) to load page content, aspx or ascx or both

I want to have a menu that when I click replaces the content of a "main" div with content from a mvc view. 我想要一个菜单​​,当我单击该菜单时,会将“主” div的内容替换为来自mvc视图的内容。 This works just fine if I use a .aspx page, but any master.page content is then doubled (like the and any css/js). 如果我使用.aspx页面,则效果很好,但随后将任何master.page内容都加倍(如the和任何css / js)。 If I do the same but uses a .ascx user control the content is loaded without the extras, but if any browser loads the menu item directly (ie search bot's or someone with JS disabled), the page is displayed without the master.page content. 如果我做同样的事情,但是使用.ascx用户控件,则加载内容而没有其他功能,但是如果任何浏览器直接加载菜单项(即搜索bot或禁用JS的人),则显示的页面不包含master.page内容。 。

The best solution I've found so far is to create the content as a .ascx page, then have a .aspx page load this if it's called directly from the menu link, while the ajax javascript would modify the link to use only the .ascx. 到目前为止,我发现的最好的解决方案是将内容创建为.ascx页面,然后如果直接从菜单链接调用它,则让.aspx页面加载此内容,而ajax javascript会将链接修改为仅使用。 ascx。 This leads to a lot duplication though, as every user control needs it's own .aspx page. 但是,这导致了很多重复,因为每个用户控件都需要它自己的.aspx页。

I was wondering if there is any better way of doing this? 我想知道是否还有更好的方法? Could for example the master.page hide everything that's not from the .aspx page if it was called with parameter ?ajax=true? 例如,如果使用参数?ajax = true调用了master.page,它是否可以隐藏.aspx页以外的所有内容?

We've solved this by using a baseController class that all controllers inherit from, and using an override for OnActionExecuted: 我们通过使用所有控制器都继承自的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);
    }

The "Ajax" master page is a then a simple masterpage with only 1 contentPlaceHolder. “ Ajax”母版页是一个只有1个contentPlaceHolder的简单母版页。 This works fine as long as all aspx pages that can be called with ajax only uses this placeholder. 只要可以用ajax调用的所有aspx页面仅使用此占位符,此方法就可以正常工作。

What about making an ActionMethod that changes what it renders depending on the type of http request it gets? 如何制作一个ActionMethod来根据它获取的http请求的类型来更改其呈现的内容? So if it is an ajax request it would render the ascx but if it is not, then it can render the whole view (or redirect to another action that renders the whole view)? 因此,如果它是ajax请求,它将呈现ascx,但是如果不是,则可以呈现整个视图(或重定向到另一个呈现整个视图的动作)?

something like 就像是

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

    return View("section.aspx");
}

and i guess section.aspx coud have inside a RenderPartial(section1.ascx) (so you dont do the page twice). 我猜section.aspx可能在RenderPartial(section1.ascx)内部(所以您不会两次执行该页面)。

Here is an example of the method I use with great success: 这是我成功使用的方法的示例:

In the View: 在视图中:

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

In the Controller: 在控制器中:

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

    if (Request.IsAjaxRequest()) return View("ajaxStuff", returnData);
    return View(returnData);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM