How to use Ajax to update RenderBody() section wit

2019-04-05 00:55发布

问题:

I've looked at few examples where Ajax can be used to update divs or other elements with ids. I have not been able to find an example that uses Ajax with Razor views to help me with the following.

My page is a standard Menu at the top, body in the middle, and a footer. There is no real need to update the header and footer each time. In fact, my page only requires a section of the Body to be updated based on menu clicks and actionlinks on the page. I'm testing this with the Internet Template that is created using VS 2012 if that helps such that I do not have to clutter this request with a bunch of code snippets. I am using Razor views and C# for coding preferences.

So, given the default _Layout.cshtml file, how would I load the About page i.e. RenderBody() section via Ajax? I've tried adding Ajax.BeginForm(...) to my _Layout.cshtml file around one div with an UpdateTargetId that matches a div that I wrapped around the RenderBody() call, returned a partial view from my controller, but that's not quite right. What I get is my partial view only. (The About page with no menu, footer, etc. just the code on the About page)

Would someone kindly share a link that demonstrates this functionality or kindly share the code that does what I desire i.e. swap index view with about view without a full page refresh? Some explanation of what I'm missing would be nice, but I'm sure I could deduce from a solid example where I went awry. As always, your time is much appreciated.

EDIT: Using Jasen's suggestion _Layout.cshtml

<nav>
    <ul id="menu">
       <li>@Html.ActionLink("Home", "Index", "Home")</li>
       <li>@Ajax.ActionLink("About", "About", "Home", null, new AjaxOptions { HttpMethod = "get", UpdateTargetId = "body" }, new { })</li>
       <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>
</nav>

....

Inside my div id="body"

@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
    @RenderBody()
</section>

..... HomeController.cs

public ActionResult About()
{
    ViewBag.Message = "Your app description page.";

    return PartialView();
}

......

回答1:

Here is a simple example with jquery. The About partial gets injected into the div with id="body".

<button>About</button>
<div id="body"></div>

$(function () {
    $("button").on("click", function(e) {
        $.get("Home/About").done(function(result) {
            $("#body").html(result);
        });
    });
));

Controller Action

[HttpGet]
public ActionResult About()
{
    return PartialView("About");
}

About.cshtml

@{ Layout = null }
<h2>Home/About</h2>
<p>Blah... </p>

Edit: Maybe a better example is to use a link instead

@Html.ActionLink("About", "About", "Home", null, new { @class="menu-button" })
<div id="body"></div>

$(function () {
    $(".menu-button").on("click", function(e) {
        e.preventDefault();
        var url = $(this).attr("href");
        $.get(url).done(function(result) {
            $("#body").html(result);
        });
    });
});

Edit: Without jquery you want to use Ajax.ActionLink() instead of Ajax.BeginForm()

@Ajax.ActionLink("About", "About", "Home", null, new AjaxOptions { HttpMethod = "get", UpdateTargetId = "body" }, new { })
<div id="body"></div>


回答2:

In your HomeController.cs

public PartialViewResult About()
{
    ViewBag.Message = "Your app description page.";

    return PartialView();
}

In your _Layout.cshtml do not forget to import:

    <script src="~/Content/Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="~/Content/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>