返回局部视图,如果动作是AJAX或儿童普遍的行动 [英] Return partial view if action is ajax or child action universally

查看:98
本文介绍了返回局部视图,如果动作是AJAX或儿童普遍的行动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

家伙,您好我已经烧起来了谷歌试图建立某种类的,这将决定的通用如果它是一个AJAX调用或儿童行为或行动,使我的控制器可以决定是否返回部分视图或全视图。到目前为止,我还没有多少运气。目前我使用下面的code来实现这个

Hi guys I have burned up google trying to construct some kind of class that will determine UNIVERSALLY if it is a AJAX call or child action or action so that my controllers can determine whether to return a partial view or a full view. So far I havent had much luck. At the moment I am using the following code to achieve this

 if (Request.IsAjaxRequest() || ControllerContext.IsChildAction)
            {
                return PartialView();
            }
 return View();

问题是你必须这样做,在一个控制器和每一个条件,你遇到的每一个动作,但我相信有一种方法通过一个帮手来实现这一点,但找不出如何。可以请你点我的任何链接/例如code来实现这一目标。

The problem is you have to do this in every action in a controller and every Condition you encounter but I am sure there is a way to achieve this via a helper but cant figure out how. Can you please point me to any links/example code to achieve this.

编辑:

@Aron我已经发布了一块code作为整个控制器就太长了。但是你可以看到我的predicament。返回包含查看和对象/型号K。

@Aron I have posted a piece of code as whole controller would be too long. But you can see my predicament. The return contains a View and a Object/Model "k".

public ActionResult _Details_Message(int id = 0, int CId = 0)
        {
            ViewBag.MrnSortParm = CId;
            if (id != 0)
            {
                var k = mrn.MRNS.Where(u => u.Id == id).SingleOrDefault();
                if (k.To == User.Identity.Name)
                {
                    if (k.Type == 0) // message
                    {
                        k.Read = true;
                        mrn.Entry(k).State = EntityState.Modified;
                        mrn.SaveChanges();
                    }
                    return PartialView("_Details_Message", k);//replace the above code here
                }
                if (k.From == User.Identity.Name)
                {
                    return PartialView("_Sent", k); //replace the above code here
                }
            }
            var m = new message();
            m.CourierId = CId;
            return PartialView("_Create_Message", m); //replace the above code here
        }

编辑2
我已经发现一个答案它不是一个辅助功能,但在该视图的变形例。链接是<一个href=\"http://stackoverflow.com/questions/5318385/mvc-3-how-to-render-a-view-without-its-layout-page\">here 。可以标记我自己的问题是重复的:(

Edit 2 I have found an answer it isn't an helper function but a modification in the view. The link is here . Can mark my own question as duplicate :(

推荐答案

那么你很幸运,因为我写了code一吨做同样的事情。如果你想在模型返回一个JSON对象或查看这也考虑到了。它还包装所有Ajax调用变成一个包装反应元件

Well you're in luck because I wrote a TON of code to do something similar. This also takes into account if you want to return the model as a JSON object or a View. It also wraps all the Ajax calls into a wrapper response element

基本上,如果你有一个UI的家伙做的东西,你永远不需要知道他想要什么。让他写的意见,或进行AJAX调用。这完全解耦从C#开发的UI人(只要他懂得如何编写MVC的看法,他并不需要在所有的控制器是如何工作的,传递的只是模型知道)。

Basically if you have a UI guy doing stuff, you NEVER need to know what he wants. Let him write the views, or make AJAX calls. This completely decouples the UI person from the C# developer (as long as he understands how to write MVC Views, he doesn't need to know at all how the controller works, just the model being passed).

ControllerBase 类:

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;
    }
}

JsonResponse&LT;&GT; 阿贾克斯全球包装呼叫:

The JsonResponse<> global wrapper for Ajax Calls:

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 code(需要jQuery的):

The Javascript global_getJsonResponse code (require 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;
    }
}

这code支持通过<一个包括服务器端和客户端超时href=\"http://stackoverflow.com/questions/5238854/handling-session-timeout-in-ajax-calls/5242746#5242746\">Handling在阿贾克斯会话超时调用,像一个变化:

This code supports both server side and client side TimeOuts via Handling session timeout in ajax calls, with a change like:

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文本(这code是从SO,我通常这样的文件,但我失去了它)呈现局部视图:

A couple of Extension Methods on controller to allow you to return rendered partial views as text in json (this code was from SO, I usually document such but I lost it):

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;
  }
}

现在得到(可惜)所有的控制器从这个基本控制器:

Now derive (sadly) all your controllers from this base controller:

public HomeController : MyBaseController
{
  public ActionResult Index()
  {
    var viewModel = new MyViewModel();

    return this.ViewOrAjax(viewModel);
  }
}

现在如果页面是由浏览器作为标准被调用,你会得到一个正常的布局呈现在页面(又名 this.View(视图模型)

Now if the page is called by the browser as your standard get, you get the page rendered normally with a Layout (aka this.View(viewModel)).

如果你调用它通过JavaScript的使用Ajax:

If you call it using Ajax via the Javascript:

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"

这篇关于返回局部视图,如果动作是AJAX或儿童普遍的行动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆