ASP.NET AJAX:如何使用 Session 获得 JSON 响应?
ASP.NET AJAX: How to get a JSON response obtained using also Session?
我是 ASP.NET 的新手,但我必须快速而有力地处理它(我知道我在问天空,但我必须这样做 ;))。
我有一个页面使用 google 地图来显示许多标记。所以我想异步地向服务器询问坐标。我认为最好的方法是让他们通过 AJAX 进行 json 序列化,并通过 ASP 会话跟踪已经发送给客户端的地图部分,并只发送那些新的。
我尝试了很多方法,但我发现总是有问题打破了魔力。
我的JS代码是:
function map2Json() {
return JSON.stringify({ "categories": $("#typeSelector input:checked").map(function () {
return $(this).val();
}).get(),
"bounds": boundsDecorator(map.getBounds())
})
};
function getMarkers() {
$.ajax({
type: "POST",
url: "GetMarkers",
data: map2Json(),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: OnFailure
});
}
而我的 ASP.NET C# 代码 (WebService.cs) 是:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetMarkers(List<string> categories, Bounds bounds)
{
System.Diagnostics.Debug.WriteLine(categories.ToString());
System.Diagnostics.Debug.WriteLine(bounds.SouthWest.lat);
return JsonConvert.SerializeObject(getMarkers(categories, bounds));
}
private string getRectangle(Bounds bounds)
{
return string.Format("polygon(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", bounds.NorthEast.lng.ToString(CultureInfo.InvariantCulture), bounds.NorthEast.lat.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lng.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lat.ToString(CultureInfo.InvariantCulture));
}
private string STpolygon(string polygon)
{
return string.Format("geography :: STGeomFromText('{0}', 4326)", polygon);
}
private string typologiesListString(List<string> typologies)
{
return string.Format("({0})", string.Join(",", typologies));
}
private string formatMapNew(List<MapViewed> maps)
{
return string.Join(" OR ", maps.Select(x => string.Format("{0}.STIntersects(GeoLocation) = 1 and Tipologia = {1}", x.lastPatch.ToString(), x.typology)));
}
private DataSet getCoordinatesInPolygon(List<MapViewed> maps)
{
SqlCommand Command_coord = new SqlCommand();
Command_coord.CommandType = CommandType.Text;
SqlConnection conn = new SqlConnection("Server=localhost\SQLEXPRESS;Database=geotagging;Trusted_Connection=Yes;Integrated Security=SSPI;");
Command_coord.Connection = conn;
string query = string.Format(@"
select [Ragione sociale], GeoLocation, Tipologia, Dettagli
from GEOTAG
where {0}", formatMapNew(maps));
Command_coord.CommandText = query;
DataSet coordinatesDS = new DataSet();
SqlDataAdapter coordinatesDA = new SqlDataAdapter();
coordinatesDA.SelectCommand = Command_coord;
try
{
coordinatesDA.Fill(coordinatesDS);
}
catch (System.Data.SqlClient.SqlException e)
{
System.Diagnostics.Debug.WriteLine("Error query: \n{0}\n Message = {1}", query, e.Message);
}
return coordinatesDS;
}
private bool IsEmpty(DataSet dataSet)
{
foreach (DataTable table in dataSet.Tables)
if (table.Rows.Count != 0) return false;
return true;
}
private List<Marker> getDBMarkers(DataSet coordinatesDS)
{
List<Marker> markers = new List<Marker>();
SqlGeography point;
Marker marker;
if (!IsEmpty(coordinatesDS))
{
foreach (DataRow row in coordinatesDS.Tables[0].Rows)
{
point = (SqlGeography)row[1];
marker = new Marker((string)row[0], new Point(point.Lat.Value, point.Long.Value), (string)row[2], (string)row[3]);
markers.Add(marker);
}
}
return markers;
}
private List<Marker> getMarkers(List<string> typologies, Bounds bounds)
{
return getDBMarkers(getCoordinatesInPolygon(updatedMaps(bounds, typologies)));
}
private List<MapViewed> updatedMaps(Bounds bounds, List<string> typologies)
{
List<MapViewed> maps = new List<MapViewed>();
MapViewed map;
foreach (string typology in typologies)
{
if (Session["mapViewed-" + typology] == null) Session["mapViewed-" + typology] = new MapViewed(typology);
map = (MapViewed)Session["mapViewed-" + typology];
map.mergeAndGetDiff(getRectangle(bounds));
maps.Add(map);
}
return maps;
}
请不要过分关注我代码的丑陋之处。我也尝试在页面后面的代码中使用几乎相同的代码,但我使用的每个方法都应该是静态的,所以我不能使用会话变量。
问题
你会怎么做?
备注
我没有把在地图上插入标记的代码放上去,因为不需要。
解决方案
谢谢大家的指教。按照您的建议,我将这段代码放在后面的代码中,效果很好:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Globalization;
using Microsoft.SqlServer.Types;
using System.Data.SqlTypes;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
static SqlConnection conn = new SqlConnection("Server=localhost\SQLEXPRESS;Database=geotagging;Trusted_Connection=Yes;Integrated Security=SSPI;");
protected void Page_Load(object sender, EventArgs e)
{
string[] typologies = new string[] { "Ricambi", "Concessionario", "Motocicli", "Officina" };
foreach (string typology in typologies)
{
HttpContext.Current.Session["mapViewed-"+typology] = new MapViewed(typology);
}
}
private static string getRectangle(Bounds bounds)
{
return string.Format("polygon(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", bounds.NorthEast.lng.ToString(CultureInfo.InvariantCulture), bounds.NorthEast.lat.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lng.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lat.ToString(CultureInfo.InvariantCulture));
}
private static string STpolygon(string polygon)
{
return string.Format("geography :: STGeomFromText('{0}', 4326)", polygon);
}
private string typologiesListString(List<string> typologies)
{
return string.Format("({0})", string.Join(",", typologies));
}
private static string formatMapNew(List<MapViewed> maps)
{
return string.Join(" OR ", maps.Select(x => string.Format("{0}.STIntersects(GeoLocation) = 1 and Tipologia = '{1}'", STpolygon(x.lastPatch.ToString()), x.typology)));
}
private static DataSet getCoordinatesInPolygon(List<MapViewed> maps)
{
SqlCommand Command_coord = new SqlCommand();
Command_coord.CommandType = CommandType.Text;
Command_coord.Connection = conn;
string query = string.Format(@"
select [Ragione sociale], GeoLocation, Tipologia, Dettagli
from GEOTAG
where {0}", formatMapNew(maps));
Command_coord.CommandText = query;
DataSet coordinatesDS = new DataSet();
SqlDataAdapter coordinatesDA = new SqlDataAdapter();
coordinatesDA.SelectCommand = Command_coord;
try
{
coordinatesDA.Fill(coordinatesDS);
}
catch (System.Data.SqlClient.SqlException e)
{
System.Diagnostics.Debug.WriteLine("Error query: \n{0}\n Message = {1}", query, e.Message);
}
return coordinatesDS;
}
private static bool IsEmpty(DataSet dataSet)
{
foreach (DataTable table in dataSet.Tables)
if (table.Rows.Count != 0) return false;
return true;
}
private static List<Marker> getDBMarkers(DataSet coordinatesDS)
{
List<Marker> markers = new List<Marker>();
SqlGeography point;
Marker marker;
if (!IsEmpty(coordinatesDS))
{
foreach (DataRow row in coordinatesDS.Tables[0].Rows)
{
point = (SqlGeography)row[1];
marker = new Marker((string)row[0], new Point(point.Lat.Value, point.Long.Value), (string)row[2], (string)row[3]);
markers.Add(marker);
}
}
return markers;
}
private static List<Marker> getMarkers(List<string> typologies, Bounds bounds)
{
return getDBMarkers(getCoordinatesInPolygon(updatedMaps(bounds, typologies)));
}
private static List<MapViewed> updatedMaps(Bounds bounds, List<string> typologies)
{
List<MapViewed> maps = new List<MapViewed>();
MapViewed map;
foreach (string typology in typologies)
{
map = (MapViewed)HttpContext.Current.Session["mapViewed-" + typology];
map.mergeAndGetDiff(getRectangle(bounds));
maps.Add(map);
}
return maps;
}
[System.Web.Services.WebMethod(EnableSession = true)]
public static List<Marker> GetMarkers(List<string> categories, Bounds bounds)
{
return getMarkers(categories, bounds);
}
}
使用static HttpContext.Current property to access the Session变量:
HttpContext.Current.Session
你可以像这样在静态方法中使用会话
//Store value in session
HttpContext.Current.Session["mysession"]=value;
//Get value from session
var sessionvaue=HttpContext.Current.Session["mysession"];
我是 ASP.NET 的新手,但我必须快速而有力地处理它(我知道我在问天空,但我必须这样做 ;))。 我有一个页面使用 google 地图来显示许多标记。所以我想异步地向服务器询问坐标。我认为最好的方法是让他们通过 AJAX 进行 json 序列化,并通过 ASP 会话跟踪已经发送给客户端的地图部分,并只发送那些新的。 我尝试了很多方法,但我发现总是有问题打破了魔力。
我的JS代码是:
function map2Json() {
return JSON.stringify({ "categories": $("#typeSelector input:checked").map(function () {
return $(this).val();
}).get(),
"bounds": boundsDecorator(map.getBounds())
})
};
function getMarkers() {
$.ajax({
type: "POST",
url: "GetMarkers",
data: map2Json(),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: OnFailure
});
}
而我的 ASP.NET C# 代码 (WebService.cs) 是:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetMarkers(List<string> categories, Bounds bounds)
{
System.Diagnostics.Debug.WriteLine(categories.ToString());
System.Diagnostics.Debug.WriteLine(bounds.SouthWest.lat);
return JsonConvert.SerializeObject(getMarkers(categories, bounds));
}
private string getRectangle(Bounds bounds)
{
return string.Format("polygon(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", bounds.NorthEast.lng.ToString(CultureInfo.InvariantCulture), bounds.NorthEast.lat.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lng.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lat.ToString(CultureInfo.InvariantCulture));
}
private string STpolygon(string polygon)
{
return string.Format("geography :: STGeomFromText('{0}', 4326)", polygon);
}
private string typologiesListString(List<string> typologies)
{
return string.Format("({0})", string.Join(",", typologies));
}
private string formatMapNew(List<MapViewed> maps)
{
return string.Join(" OR ", maps.Select(x => string.Format("{0}.STIntersects(GeoLocation) = 1 and Tipologia = {1}", x.lastPatch.ToString(), x.typology)));
}
private DataSet getCoordinatesInPolygon(List<MapViewed> maps)
{
SqlCommand Command_coord = new SqlCommand();
Command_coord.CommandType = CommandType.Text;
SqlConnection conn = new SqlConnection("Server=localhost\SQLEXPRESS;Database=geotagging;Trusted_Connection=Yes;Integrated Security=SSPI;");
Command_coord.Connection = conn;
string query = string.Format(@"
select [Ragione sociale], GeoLocation, Tipologia, Dettagli
from GEOTAG
where {0}", formatMapNew(maps));
Command_coord.CommandText = query;
DataSet coordinatesDS = new DataSet();
SqlDataAdapter coordinatesDA = new SqlDataAdapter();
coordinatesDA.SelectCommand = Command_coord;
try
{
coordinatesDA.Fill(coordinatesDS);
}
catch (System.Data.SqlClient.SqlException e)
{
System.Diagnostics.Debug.WriteLine("Error query: \n{0}\n Message = {1}", query, e.Message);
}
return coordinatesDS;
}
private bool IsEmpty(DataSet dataSet)
{
foreach (DataTable table in dataSet.Tables)
if (table.Rows.Count != 0) return false;
return true;
}
private List<Marker> getDBMarkers(DataSet coordinatesDS)
{
List<Marker> markers = new List<Marker>();
SqlGeography point;
Marker marker;
if (!IsEmpty(coordinatesDS))
{
foreach (DataRow row in coordinatesDS.Tables[0].Rows)
{
point = (SqlGeography)row[1];
marker = new Marker((string)row[0], new Point(point.Lat.Value, point.Long.Value), (string)row[2], (string)row[3]);
markers.Add(marker);
}
}
return markers;
}
private List<Marker> getMarkers(List<string> typologies, Bounds bounds)
{
return getDBMarkers(getCoordinatesInPolygon(updatedMaps(bounds, typologies)));
}
private List<MapViewed> updatedMaps(Bounds bounds, List<string> typologies)
{
List<MapViewed> maps = new List<MapViewed>();
MapViewed map;
foreach (string typology in typologies)
{
if (Session["mapViewed-" + typology] == null) Session["mapViewed-" + typology] = new MapViewed(typology);
map = (MapViewed)Session["mapViewed-" + typology];
map.mergeAndGetDiff(getRectangle(bounds));
maps.Add(map);
}
return maps;
}
请不要过分关注我代码的丑陋之处。我也尝试在页面后面的代码中使用几乎相同的代码,但我使用的每个方法都应该是静态的,所以我不能使用会话变量。
问题
你会怎么做?
备注
我没有把在地图上插入标记的代码放上去,因为不需要。
解决方案
谢谢大家的指教。按照您的建议,我将这段代码放在后面的代码中,效果很好:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Globalization;
using Microsoft.SqlServer.Types;
using System.Data.SqlTypes;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
static SqlConnection conn = new SqlConnection("Server=localhost\SQLEXPRESS;Database=geotagging;Trusted_Connection=Yes;Integrated Security=SSPI;");
protected void Page_Load(object sender, EventArgs e)
{
string[] typologies = new string[] { "Ricambi", "Concessionario", "Motocicli", "Officina" };
foreach (string typology in typologies)
{
HttpContext.Current.Session["mapViewed-"+typology] = new MapViewed(typology);
}
}
private static string getRectangle(Bounds bounds)
{
return string.Format("polygon(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", bounds.NorthEast.lng.ToString(CultureInfo.InvariantCulture), bounds.NorthEast.lat.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lng.ToString(CultureInfo.InvariantCulture), bounds.SouthWest.lat.ToString(CultureInfo.InvariantCulture));
}
private static string STpolygon(string polygon)
{
return string.Format("geography :: STGeomFromText('{0}', 4326)", polygon);
}
private string typologiesListString(List<string> typologies)
{
return string.Format("({0})", string.Join(",", typologies));
}
private static string formatMapNew(List<MapViewed> maps)
{
return string.Join(" OR ", maps.Select(x => string.Format("{0}.STIntersects(GeoLocation) = 1 and Tipologia = '{1}'", STpolygon(x.lastPatch.ToString()), x.typology)));
}
private static DataSet getCoordinatesInPolygon(List<MapViewed> maps)
{
SqlCommand Command_coord = new SqlCommand();
Command_coord.CommandType = CommandType.Text;
Command_coord.Connection = conn;
string query = string.Format(@"
select [Ragione sociale], GeoLocation, Tipologia, Dettagli
from GEOTAG
where {0}", formatMapNew(maps));
Command_coord.CommandText = query;
DataSet coordinatesDS = new DataSet();
SqlDataAdapter coordinatesDA = new SqlDataAdapter();
coordinatesDA.SelectCommand = Command_coord;
try
{
coordinatesDA.Fill(coordinatesDS);
}
catch (System.Data.SqlClient.SqlException e)
{
System.Diagnostics.Debug.WriteLine("Error query: \n{0}\n Message = {1}", query, e.Message);
}
return coordinatesDS;
}
private static bool IsEmpty(DataSet dataSet)
{
foreach (DataTable table in dataSet.Tables)
if (table.Rows.Count != 0) return false;
return true;
}
private static List<Marker> getDBMarkers(DataSet coordinatesDS)
{
List<Marker> markers = new List<Marker>();
SqlGeography point;
Marker marker;
if (!IsEmpty(coordinatesDS))
{
foreach (DataRow row in coordinatesDS.Tables[0].Rows)
{
point = (SqlGeography)row[1];
marker = new Marker((string)row[0], new Point(point.Lat.Value, point.Long.Value), (string)row[2], (string)row[3]);
markers.Add(marker);
}
}
return markers;
}
private static List<Marker> getMarkers(List<string> typologies, Bounds bounds)
{
return getDBMarkers(getCoordinatesInPolygon(updatedMaps(bounds, typologies)));
}
private static List<MapViewed> updatedMaps(Bounds bounds, List<string> typologies)
{
List<MapViewed> maps = new List<MapViewed>();
MapViewed map;
foreach (string typology in typologies)
{
map = (MapViewed)HttpContext.Current.Session["mapViewed-" + typology];
map.mergeAndGetDiff(getRectangle(bounds));
maps.Add(map);
}
return maps;
}
[System.Web.Services.WebMethod(EnableSession = true)]
public static List<Marker> GetMarkers(List<string> categories, Bounds bounds)
{
return getMarkers(categories, bounds);
}
}
使用static HttpContext.Current property to access the Session变量:
HttpContext.Current.Session
你可以像这样在静态方法中使用会话
//Store value in session
HttpContext.Current.Session["mysession"]=value;
//Get value from session
var sessionvaue=HttpContext.Current.Session["mysession"];