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

17,465

Solution 1

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.

Solution 2

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.

Solution 3

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

Share:
17,465
Sunny Sandeep
Author by

Sunny Sandeep

Updated on June 15, 2022

Comments

  • Sunny Sandeep
    Sunny Sandeep almost 2 years

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