那麼你很幸運,因爲我寫了一個TON代碼來做類似的事情,這也考慮到了,如果你想返回模型作爲JSON對象或視圖。它還將所有的Ajax調用包裝到一個包裝響應元素中,基本上如果你有一個UI人員做東西,你永遠不需要知道他想要什麼,讓他編寫視圖或者調用AJAX調用,這完全分離來自C#開發人員的UI人員(只要他了解如何編寫MVC Views,他根本不需要知道控制器是如何工作的,只需通過該模型即可)
ControllerBase
cla SS:
public abstract class MyControllerBase : Controller
{
// could be moved to web.config
private const _jsonDataType = "JsonDataType";
public bool IsAjaxRequest
{
get
{
return this.HttpContext.Request.IsAjaxRequest();
}
}
public bool IsAjaxHtmlRequest
{
get
{
return string.Equals(this.Request.Headers[MyControllerBase._jsonDataType], "html", StringComparison.CurrentCultureIgnoreCase);
}
}
private JsonResponse GetAjaxResponse()
{
JsonResponse result = new JsonResponse();
result.IsValid = true;
return result;
}
private JsonResponse<T> GetAjaxResponse<T>(T model)
{
JsonResponse<T> result = new JsonResponse<T>();
result.Data = model;
result.IsValid = true;
return result;
}
private JsonResponse<string> GetAjaxHtmlResponse()
{
JsonResponse<string> result = new JsonResponse<string>();
result.Data = this.PartialViewToString(this.ControllerContext.RouteData.Values["Action"].ToString(), null);
result.IsValid = true;
return result;
}
private JsonResponse<string> GetAjaxHtmlResponse<T>(T model)
{
JsonResponse<string> result = new JsonResponse<string>();
result.Data = this.PartialViewToString(this.ControllerContext.RouteData.Values["Action"].ToString(), model);
result.IsValid = true;
return result;
}
private JsonResponse<string> GetAjaxHtmlResponse<T>(T model, string viewName)
{
JsonResponse<string> result = new JsonResponse<string>();
result.Data = this.PartialViewToString(viewName, model);
result.IsValid = true;
return result;
}
public ActionResult ViewOrAjax()
{
return this.ViewOrAjax(JsonRequestBehavior.DenyGet);
}
public ActionResult ViewOrAjax(JsonRequestBehavior jsonRequestBehavior)
{
if (this.ControllerContext.IsChildAction)
{
return this.PartialView(this.ControllerContext.RouteData.Values["Action"].ToString(), null);
}
if (this.IsAjaxRequest)
{
if (this.IsAjaxHtmlRequest)
{
return this.Json(this.GetAjaxHtmlResponse(), jsonRequestBehavior);
}
return this.Json(this.GetAjaxResponse(), jsonRequestBehavior);
}
return this.View(this.ControllerContext.RouteData.Values["Action"].ToString(), null);
}
public ActionResult ViewOrAjax<T>(T model)
{
return this.ViewOrAjax<T>(model, JsonRequestBehavior.DenyGet);
}
public ActionResult ViewOrAjax<T>(T model, JsonRequestBehavior jsonRequestBehavior)
{
if (this.ControllerContext.IsChildAction)
{
return this.PartialView(model);
}
if (this.IsAjaxRequest)
{
if (this.IsAjaxHtmlRequest)
{
return this.Json(this.GetAjaxHtmlResponse(model), jsonRequestBehavior);
}
return this.Json(this.GetAjaxResponse<T>(model), jsonRequestBehavior);
}
return this.View(model);
}
public ActionResult ViewOrAjax<T>(IView view, T model, JsonRequestBehavior jsonRequestBehavior)
{
if (this.ControllerContext.IsChildAction)
{
return this.PartialView(model);
}
if (this.IsAjaxRequest)
{
if (this.IsAjaxHtmlRequest)
{
return this.Json(this.GetAjaxHtmlResponse(model), jsonRequestBehavior);
}
return this.Json(this.GetAjaxResponse<T>(model), jsonRequestBehavior);
}
return this.View(view, model);
}
public ActionResult ViewOrAjax<T>(string viewName, T model)
{
return this.ViewOrAjax<T>(viewName, model, JsonRequestBehavior.DenyGet);
}
public ActionResult ViewOrAjax<T>(string viewName, T model, JsonRequestBehavior jsonRequestBehavior)
{
if (this.ControllerContext.IsChildAction)
{
return this.PartialView(model);
}
if (this.IsAjaxRequest)
{
if (this.IsAjaxHtmlRequest)
{
return this.Json(this.GetAjaxHtmlResponse(model, viewName), jsonRequestBehavior);
}
return this.Json(this.GetAjaxResponse<T>(model), jsonRequestBehavior);
}
return this.View(viewName, model);
}
public ActionResult ViewOrAjax<T>(string viewName, string masterName, T model)
{
return this.ViewOrAjax<T>(viewName, masterName, model, JsonRequestBehavior.DenyGet);
}
public ActionResult ViewOrAjax<T>(string viewName, string masterName, T model, JsonRequestBehavior jsonRequestBehavior)
{
if (this.ControllerContext.IsChildAction)
{
return this.PartialView(model);
}
if (this.IsAjaxRequest)
{
if (this.IsAjaxHtmlRequest)
{
return this.Json(this.GetAjaxHtmlResponse(model, viewName), jsonRequestBehavior);
}
return this.Json(this.GetAjaxResponse(model), jsonRequestBehavior);
}
return this.View(viewName, masterName, model);
}
protected internal new ViewResult View(string viewName, string masterName, object model)
{
if (model != null)
{
ViewData.Model = model;
}
ViewResult result = new ViewResult
{
ViewName = viewName,
MasterName = masterName,
ViewData = ViewData,
TempData = TempData
};
return result;
}
}
適合於Ajax的JsonResponse<>
全球包裝呼叫:
public class JsonResponse
{
public JsonResponse()
{
}
public bool IsValid { get; set; }
public bool IsAjaxRequestUnsupported { get; set; }
public string RedirectTo { get; set; }
public string CanonicalUrl { get; set; }
}
public class JsonResponse<T> : JsonResponse
{
public JsonResponse() : base()
{
}
public T Data { get; set; }
}
的JavaScript global_getJsonResponse
代碼(需要的jQuery):
function global_getJsonResult(Controller, View, data, successCallback, completeCallback, methodType, returnType, jsonDataType) {
if (IsString(Controller)
&& IsString(View)
&& !IsUndefinedOrNull(data)) {
var ajaxData;
var ajaxType;
if (typeof (data) == "string") {
ajaxData = data;
ajaxType = "application/x-www-form-urlencoded"
}
else {
ajaxData = JSON.stringify(data);
ajaxType = "application/json; charset=utf-8";
}
var method = 'POST';
if (methodType) {
method = methodType;
}
var dataType = 'json';
if (returnType) {
dataType = returnType;
}
var jsonType = 'html';
if (jsonDataType) {
jsonType = jsonDataType;
}
var jqXHR = $.ajax({
url: '/' + Controller + '/' + View,
headers: { JsonDataType: jsonType },
data: ajaxData,
type: method,
dataType: dataType,
contentType: ajaxType,
success: function (jsonResult) {
if (!IsUndefinedOrNull(jsonResult)
&& jsonResult.hasOwnProperty("RedirectTo")
&& !IsUndefinedOrNull(jsonResult.RedirectTo)
&& jsonResult.RedirectTo.length > 0) {
$.fn.notify('error', 'Login Expired', 'You have been inactive for a prolonged period of time, and have been logged out of the system.');
window.setTimeout(function() { window.location = jsonResult.RedirectTo }, 5000);
}
else if (IsFunction(successCallback)) {
successCallback(jsonResult, Controller + '/' + View);
}
},
error: function (jqXHR, textStatus, errorThrown) {
if (errorThrown != 'abort') {
$.fn.notify('error', 'Whoops! Something went wrong.', 'We have been notified of the error.'/* textStatus + ': ' + errorThrown*/);
}
log('ERROR IN global_getJsonResult() : ', textStatus, errorThrown, jqXHR);
},
complete: function (jqXHR, textStatus) {
if (IsFunction(completeCallback)) {
completeCallback(jqXHR, textStatus, Controller + '/' + View);
}
}
});
return jqXHR;
}
}
該代碼同時支持服務器端和客戶端超時通過Handling session timeout in ajax calls,改變如下:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = new JsonResponse<bool>
{
IsValid = false,
RedirectTo = FormsAuthentication.LoginUrl
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
一對夫婦控制器擴展方法,讓你恢復文本渲染的局部視圖,在JSON(此代碼是從SO,我通常記錄這些,但我失去了它):
internal static class ControllerExtensions
{
public static string PartialViewToString(this Controller instance, object model)
{
string viewName = instance.ControllerContext.RouteData.GetRequiredString("action");
return ControllerExtensions.PartialViewToString(instance, viewName, model);
}
public static string PartialViewToString(this Controller instance, string viewName, object model)
{
string result;
ViewDataDictionary viewData = instance.ViewData;
viewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(instance.ControllerContext, viewName);
var viewContext = new ViewContext(instance.ControllerContext, viewResult.View, viewData, instance.TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(instance.ControllerContext, viewResult.View);
result = sw.GetStringBuilder().ToString();
}
return result;
}
}
現在推導(可悲的是)所有的控制器從這個基本控制器:
public HomeController : MyBaseController
{
public ActionResult Index()
{
var viewModel = new MyViewModel();
return this.ViewOrAjax(viewModel);
}
}
現在,如果頁面被瀏覽器調用作爲標準的GET,你得到一個佈局(又名this.View(viewModel)
)通常呈現的頁面。
如果你把它通過JavaScript的使用Ajax:
global_getJsonResult("Home", // Controller or 'Area/Home' for areas
"Index", // View
$('#form').serialize(), // Json object or a serialized Form
jsCallBack, // call back function or null
"Post", // Get or Post
"Html"); // "Html" to return a Partial View in "Data"
// or "Json" to return a serialized view model in "Data"
這會讓你的代碼在一個私人貼什麼方法並返回一個呼叫給它? –
問題在於何時使用視圖返回模型。例如'返回視圖(「someview」,somemodel);'所以如果我構造一個方法,我將不得不爲每個對象/模型重複構造相同的方法,這種方法會破壞方法的目的。另一方面,我可能會嘗試變種 –
。 –