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. This works just fine if I use a .aspx page, but any master.page content is then doubled (like the and any 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 pa开发者_如何学JAVAge is displayed without the master.page content.
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. This leads to a lot duplication though, as every user control needs it's own .aspx page.
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?
We've solved this by using a baseController class that all controllers inherit from, and using an override for 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. This works fine as long as all aspx pages that can be called with ajax only uses this placeholder.
What about making an ActionMethod that changes what it renders depending on the type of http request it gets? 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)?
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).
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);
}
精彩评论