我正在尝试找到一种方法来包装带有 jsonp 回调的 json 响应。我遇到的问题是我不想使用“JsonResult”类来构造响应,因为它用自己的对象包装它,就好像我直接返回模型一样,它被正确序列化为 json。
到目前为止,我已经尝试使用“ActionFilter”,但无法找出在执行操作后如何包装结果。
任何方向都将不胜感激
我正在尝试找到一种方法来包装带有 jsonp 回调的 json 响应。我遇到的问题是我不想使用“JsonResult”类来构造响应,因为它用自己的对象包装它,就好像我直接返回模型一样,它被正确序列化为 json。
到目前为止,我已经尝试使用“ActionFilter”,但无法找出在执行操作后如何包装结果。
任何方向都将不胜感激
我一直在走这条路,并且可以提供以下代码,将 JsonP 调用封装到 ActionResult 中,向控制器添加一个方法,允许您优先考虑所需的 ActionResult 类型,以及一些扩展方法来粘合它们一起。唯一的要求是一致地命名您的回调参数,以便可以可靠地从请求中剔除它。
一、派生的ActionResult:
using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;
namespace CL.Enterprise.Components.Web.Mvc
{
/// <summary>
/// Extension of JsonResult to handle JsonP requests
/// </summary>
public class JsonPResult : ActionResult
{
private JavaScriptSerializer _jser = new JavaScriptSerializer();
public Encoding ContentEncoding { get; set; }
public string ContentType { get; set; }
public object Data { get; set; }
public string JsonCallback { get; set; }
public JsonPResult() { }
/// <summary>
/// Package and return the result
/// </summary>
public override void ExecuteResult(ControllerContext Context)
{
//Context.IsChildAction
if (Context == null)
{
throw new ArgumentNullException("Context");
}
JsonCallback = Context.HttpContext.Request["callback"];
if (string.IsNullOrEmpty(JsonCallback))
{
JsonCallback = Context.HttpContext.Request["jsoncallback"];
}
if (string.IsNullOrEmpty(JsonCallback))
{
throw new ArgumentNullException("JsonP callback parameter required for JsonP response.");
}
HttpResponseBase CurrentResponse = Context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
CurrentResponse.ContentType = ContentType;
}
else
{
CurrentResponse.ContentType = "application/json";
}
if (ContentEncoding != null)
{
CurrentResponse.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
CurrentResponse.Write(string.Format("{0}({1});", JsonCallback, _jser.Serialize(Data)));
}
}
}
}
接下来,Controller 扩展方法:
using System.IO;
using System.Web.Mvc;
namespace CL.Enterprise.Components.Web.Mvc
{
/// <summary>
/// Extension methods for System.Web.Mvc.Controller
/// </summary>
public static class ContollerExtensions
{
/// <summary>
/// Method to return a JsonPResult
/// </summary>
public static JsonPResult JsonP(this Controller controller, object data)
{
JsonPResult result = new JsonPResult();
result.Data = data;
//result.ExecuteResult(controller.ControllerContext);
return result;
}
/// <summary>
/// Get the currently named jsonp QS parameter value
/// </summary>
public static string GetJsonPCallback(this Controller controller)
{
return
controller.ControllerContext.RequestContext.HttpContext.Request.QueryString["callback"] ??
controller.ControllerContext.RequestContext.HttpContext.Request.QueryString["jsoncallback"] ??
string.Empty;
}
}
}
最后,将此方法添加到您的控制器中:
/// <summary>
/// Gets an ActionResult, either as a jsonified string, or rendered as normally
/// </summary>
/// <typeparam name="TModel">Type of the Model class</typeparam>
/// <param name="UsingJson">Do you want a JsonResult?</param>
/// <param name="UsingJsonP">Do you want a JsonPResult? (takes priority over UsingJson)</param>
/// <param name="Model">The model class instance</param>
/// <param name="RelativePathToView">Where in this webapp is the view being requested?</param>
/// <returns>An ActionResult</returns>
public ActionResult GetActionResult<T>(T Model, bool UsingJsonP, bool UsingJson, string RelativePathToView)
{
string ViewAsString =
this.RenderView<T>(
RelativePathToView,
Model
);
if (UsingJsonP) //takes priority
{
string Callback = this.GetJsonPCallback();
JsonPResult Result = this.JsonP(ViewAsString.Trim());
return Result;
}
if (UsingJson)//secondary
{
return Json(ViewAsString.Trim(), JsonRequestBehavior.AllowGet);
}
return View(Model); //tertiary
}