ASP MVC and jsonp
I need to send some data through a Jsonp response from a MVC application. For Jsonp response method i used a JsonpFilter.
This is my Jsonp response method:
[JsonpFilter]
public JsonResult GetPageName()
{
return new JsonResult
{
Data = Session["Page"],
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
and this is the javascript function:
$.ajax({
type: "GET",
dataType: "jsonp",
url: 'http://localhost:54845/Login/GetPageName',
contentType: "application/json; charset=utf-8",
success: function开发者_开发技巧 (data) {
alert(data.width + "-" + data.height);
}
});
This code works great only on FF. In IE nothing is happening.
What is wrong in my code? Thank you.
Are you actually planning on making cross-domain HTTP GETs of JSON data? If not, why bother with JSONP? Just use JSON.
Firefox is being loosey goosey. The other browsers are being prude dudes.
See: JSONP callback doesn't execute when running at localhost
To quote:
A web site could just go through a list of ports and keep invoking localhost on different ports and paths. 'Localhost' is one of few DNS hostnames that are dynamic in meaning depending on when and where it's queried, making the potential targets vulnerable. And yes, the fact that appending a dot (.) to 'localhost' ('localhost.') produces a working workaround does expose a security vulnerability, but does offer a [tentative] workaround for development puposes.
A better approach is to map the loopback IP to a new hostname entry in the hosts file so that it works locally, isn't prone to be "fixed" by a browser update, and doesn't work anywhere else but on the development workstation.
The problem is with IE session variables. If i replace Session["Page"] with new {var1 = "var1", var2 = "var2"} it works. So i need to find a solution for that. Thank you all.
MVC / JSONP / DataSet Binding
I was able to get JSONP to work with MVC by modifying the code above. This sample directly binds datasets to html elements via JSONP.
Controller
>
public class HomeController : Controller { [HttpGet] public ActionResult HeaderJSONP() { DsPromotion.HeaderDataTable tbl = new DsPromotion.HeaderDataTable(); DsPromotion.HeaderRow row = tbl.NewHeaderRow(); row.imgBanner_src = "/Content/Home/Image/MainBanner.gif"; tbl.Rows.Add(row); return new JsonpResult { Data = tbl }; } }
JSONP Result
> public class JsonpResult : System.Web.Mvc.JsonResult > { > public override void ExecuteResult(ControllerContext context) > { > this.JsonRequestBehavior = JsonRequestBehavior.AllowGet; > if (context == null) > { > throw new ArgumentNullException("context"); > } > > HttpResponseBase response = context.HttpContext.Response; > if (!String.IsNullOrEmpty(ContentType)) > { > response.ContentType = ContentType; > } > else > { > response.ContentType = "application/json"; > } > if (ContentEncoding != null) > { > response.ContentEncoding = ContentEncoding; > } > if (Data != null) > { > HttpRequestBase request = context.HttpContext.Request; > JavaScriptSerializer jsonserializer = new JavaScriptSerializer(); > DataTableConverter serializer = new DataTableConverter(); > response.Write(request.Params["jsoncallback"] + "(" + jsonserializer.Serialize(serializer.Serialize(Data, new JavaScriptSerializer())) + ")"); > } > } > }
Javascript / JQuery JSON Request and Callback
>
function BindDataTable(dataTable) { var tableName; for (tableName in dataTable) { if (tableName.indexOf('') > 0) { tableName = tableName.split('')[0]; } } var elementAndAttrib; for (elementAndAttrib in dataTable[tableName][0]) { var elementID = elementAndAttrib.split('')[0]; var attribName = elementAndAttrib.split('')[1]; var attribValue = dataTable[tableName][0][elementAndAttrib]; $("#" + elementID).attr(attribName, attribValue); } } function GetHomeHeaderCallBack(tblHeader) { BindDataTable(tblHeader); } function GetHomeHeader() { var call = "/Home/HeaderJSONP?jsoncallback=?&" + Math.round(new Date().getTime()); $.getJSON(call, { format: "json" }, GetHomeHeaderCallBack); } $(GetHomeHeader);
Partial View
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
XSD
...
Table Serializer
>
public class DataTableConverter : JavaScriptConverter { public override IEnumerable SupportedTypes { get { return new Type[] { typeof(DataTable) }; } }
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) { throw new NotImplementedException(); } public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) { DataTable listType = obj as DataTable; if (listType != null) { // Create the representation. Dictionary<string, object> result = new Dictionary<string, object>(); ArrayList itemsList = new ArrayList(); foreach (DataRow row in listType.Rows) { //Add each entry to the dictionary. Dictionary<string, object> listDict = new Dictionary<string, object>(); foreach (DataColumn dc in listType.Columns) { listDict.Add(dc.ColumnName, row[dc.ColumnName].ToString()); } itemsList.Add(listDict); } result[listType.TableName] = itemsList; return result; } return new Dictionary<string, object>(); }
}
Enjoy! Mark Brito
精彩评论