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"];