Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use session in apicontroller in asp.net mvc 4

I am working on an application using asp.net mvc 4. Here I want to use autocomplete extender using JQuery where i want to populate all location of that CityID which is stored in session.

Here is the function for creating the session:

public string Create(string City)
{
    try
    {
        //HttpSessionStateBase Session["c"]=City;
        //HttpContext.Current.Session["City"] = City;
        System.Web.HttpContext.Current.Session["City"] = City;
        long CityID = Convert.ToInt64(System.Web.HttpContext.Current.Session["City"].ToString());

        return City;
    }
    catch (Exception ex)
    {
       throw (ex);
    }
}

This function is called when user select any city from the City dropdownlist.

My JQuery calling for autocomplete extender is:

<script type="text/javascript">
var url = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "ProductApi" })';
$('#txtLocation').autocomplete({
    source: function (request, response) {
        alert(url);
        $.ajax({
            url: url,
            data: { query: request.term },
            dataType: 'json',
            type: 'GET',
            success: function (data) {
                response($.map(data, function (item) {
                    return {
                        label: item.Name
                        //value: item.ID
                    }
                }));
            }
        })
    },
    select: function (event, ui) {
        $('#txtLocation').val(ui.item.label);
        //$('#ID').val(ui.item.value);
        return false;
    },
    minLength: 1
});

My api controller is :

public class ProductApiController : ApiController
{
    SqlConnection cnn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["SQLCONN"].ToString());        

    [HttpGet]
    public IEnumerable<Search> GetProducts(string query = "")
    {
        cnn.Open();
        //string gid = GETSession("t");

        long CityID = Convert.ToInt64(System.Web.HttpContext.Current.Session["City"].ToString());

        SqlCommand cmd = new SqlCommand("Check_PrefixText", cnn);
        cmd.Parameters.AddWithValue("City", CityID);
        cmd.Parameters.AddWithValue("@Prefix", query);

        cmd.CommandType = CommandType.StoredProcedure;

        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        da.Fill(dt);

        //var result = IEnumerable<City>(query);
        Search obj = new Search();
        cnn.Close();
        return dt.AsEnumerable().Select(row =>
        {
            return new Search
            {
                Name = Convert.ToString(row["Name"]),
            };
        });
    }
}

In Global.asax file i have written 2 methods:

protected void Application_PostAuthorizeRequest()
{
    if (IsWebApiRequest())
    {
        HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
    }
}

private bool IsWebApiRequest()
{
    return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative);
}

In webApiConfig Class i have written as follows:

public static string UrlPrefix { get { return "api"; } }
public static string UrlPrefixRelative { get { return "~/api"; } }

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}",
         defaults: new { id = RouteParameter.Optional }
    );
}

But still the value of session["City"] is coming null in ApiController while there there is value stored showing in session["City"].

like image 303
Sunny Sandeep Avatar asked Aug 19 '15 12:08

Sunny Sandeep


3 Answers

Simply, you can't. Web Api adheres to REST, which among other things is stateless. That means no session. Each REST-compliant request must contain all the data it needs for the request in the request itself (either as part of the query string in a GET or body in a POST, PUT, etc).

That said, regular MVC controller actions can return JSON, XML, etc., as well, so you can set up an endpoint for your AJAX request in an MVC controller and touch the session from there. You just can't do it from ApiController.

like image 129
Chris Pratt Avatar answered Oct 22 '22 10:10

Chris Pratt


Using SetSessionStateBehavior you can resolve this issue. Let me explain.

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    ...

    protected void Application_PostAuthorizeRequest()
    {
        if (IsWebApiRequest())
        {
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
        }
    }

    private bool IsWebApiRequest()
    {
        return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative);
    }

}

Write down this two method in global.asax.cs using SetSessionStateBehavior you can access session in ApiController

like image 4
Sender Avatar answered Oct 22 '22 10:10

Sender


Change your API to:

[HttpGet]
public IEnumerable<Search> GetProducts(long cityID, string query = "")
{

then pass your cityID with the data

data: { 
    cityID: $("#cityDropDownId :selected").val(),
    query: request.term 
},

Forget about trying to use "session" - it's not the correct technology for what you are trying to do.

like image 2
freedomn-m Avatar answered Oct 22 '22 10:10

freedomn-m