Problem z sesją

0

Kochani robię sklep internetowy,
problem polega na tym, że HttpContext.Current.Session pobiera prawidłowo sesję podczas przechodzenia pomiędzy stronami itd. ale podczas gdy wejdę w jedną ze stron (strona dotycząca szczegółów produktu) HttpContext.Current.Session zwraca mi wartość null na co nie jest przygotowany mój "get"... Ktoś może mi doradzić co może być powodem takiej sytuacji?

0

Może po prostu sesja wygasła?

0

No niestety nie... Sprawdzałem kilkakrotnie... Nawet po odświeżeniu portalu stan koszyka jest dalej taki sam więc sesja nie wygasła... Coś dla tej jednej strony ustawia wartość sesji na null?

1

Cały Session jest null czy tylko jakaś wartość?

0

cały Session jest null`em

1

A w jakiej technologii ta aplikacja?

0

asp.net mvc

1

To tak:

  1. Masz session prawidłowo skonfigurowane w web.config?
  2. W którym momencie się do niej odwołujesz, może po prostu zbyt wcześnie i jeszcze nie jest spopulowana.
  3. Do czego w ogóle używasz Session w MVC?
0

O widzę konkretny gość ;) Mam nadzieję, że uda się rozwiązać ;)
1.ani w web.cofingu w Views ani w tym globalnym nie mam wpisu o ustawieniach httpcontext.. Nie dodawałem nic ponieważ chodziło dla innychpodstron.
2.Jest to w momencie kiedy załadowuje się storna detalu produktu i ładuje resztę layoutu... Wteyd działa akcja, która ma pokazać ilość elementów w koszyku i ma byc pobrana dla niego wartosc sesji. w tym celu uruchamiany jest cartMenager, który ma za zadanie pobrać aktualną sesję... i tu następuje błąd

       public T Get<T>(string key)
        {
            return (T)_session[key];
        }

Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.
3.Session jest mi właśnie potrzebne do tego, żeby bez rejestracji można było wczytać jakieś produkty do koszyka...

Jeśli po prostu nie uda mi się tego naprawić zrobię bez opcji dodawania do koszyka bez rejestracji...

1

Ad 2. Chodziło mi o miejsce w kodzie w kontekście cyklu życia strony. Czy to konstruktor kontrolera, czy jakiś model binder, czy zdarzenie, czy akcja, czy inny WTF.
Ogólnie bez kodu to można sobie tylko wróżyć.

0

Tak, W konstruktorze kontrolera dzieje sie taka akcja:

        public CartController()
        {
            this.sessionManager = new SessionManager();
            this.shoppingCartManager = new ShoppingCartManager(this.sessionManager, this.db);

        }

I w

 this.sessionManager = new SessionManager();

w konnstruktorze SessionMenager`a

        public SessionManager()
        {
            _session = HttpContext.Current.Session;
        }

W Tym momencie właśnie Curren.Session ma wartość null

1

No właśnie... W konstruktorze kontrolera nie ma dostępu do Session, ten obiekt wówczas nie jest jeszcze ustawiony przez runtime. Ma to sens, bo konstruktory służą do ustawiania i konfigurowania zależności obiektu, a nie do pobierania danych.

0

W jaki sposób mogę to przerobić ?

1

No najprościej odwołać się do danych z Session w akcji kontrolera.
Pobieraj dane z HttpContext.Current.Session w metodach SessionManager, bez ustawiania tego najpierw w polu _session. Ono w ogóle nie ma sensu, skoro nie może być dowolnie ustawione i jest na zawsze związane z HttpContext.Current.

0

O tyle to jest śmieszne, że to wszystko jest podczas gdy ja się odwołuję w leyoucie do długości elementów w koszyku (po to,żeby w rogu pokazywało ile elementrów jest w koszyku) i to podczas wykonywania tej akcji dzieją się takie cyrki tylko i wyłącznie gdy włączam detal produktu... Kiedy dodam coś do koszyka i przeglądam inne strony wszystko jest ok

0

Problem jest dalej... Jakby w ogóle do HttpContext.Current. nie przypisywało żadnych informacji na temat sesji...

1

Masz błąd w 15 linijce.

Już Ci odpowiedziałem - odwołujesz się do Session przed jego ustawieniem przez runtime. Jeśli nie chcesz pokazać kodu, to dokładnego błędu musisz szukać sam.

0

Nie mogę niestety dojsć... Dopiero zauważyłem, żę faktycznie problem występuje za każdym razem kiedy chce się ponownie załadować layout....

Tu kod kontrollera:

using MojSklepMVC.DAL;
using MojSklepMVC.Infrastucture;
using MojSklepMVC.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MojSklepMVC.Controllers
{
    public class CartController : Controller
    {
        private ShoppingCartManager shoppingCartManager;
        private ISessionManager sessionManager { get; set; }
        private StoreContext db = new StoreContext();

        public CartController()
        {

            this.sessionManager = new SessionManager();
            this.shoppingCartManager = new ShoppingCartManager(this.sessionManager, this.db);

        }


        public ActionResult Index()
        {

            var cartItems = shoppingCartManager.GetCart();
            var cartTotalPrice = shoppingCartManager.GetCartTotalPrice();

            CartViewModel cartVM = new CartViewModel() { CartItems = cartItems, TotalPrice = cartTotalPrice };

            return View(cartVM);
        }

        public ActionResult AddToCart(int id)
        {

            shoppingCartManager.AddToCart(id);

            return RedirectToAction("Index");
        }

        public int GetCartItemsCount()
        {
            
            return shoppingCartManager.GetCartItemsCount();
        }

        public ActionResult RemoveFromCart(int albumID)
        {
           

            int itemCount = shoppingCartManager.RemoveFromCart(albumID);
            int cartItemsCount = shoppingCartManager.GetCartItemsCount();
            decimal cartTotal = shoppingCartManager.GetCartTotalPrice();


            var result = new CartRemoveViewModel
            {
                RemoveItemId = albumID,
                RemovedItemCount = itemCount,
                CartTotal = cartTotal,
                CartItemsCount = cartItemsCount
            };

            return Json(result);
        }

    }
}

Tu kod Session Menagera:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;

namespace MojSklepMVC.Infrastucture
{
    public class SessionManager : ISessionManager
    {
        private HttpSessionState _session;


        public SessionManager()
        {
            this._session = HttpContext.Current.Session;
        }



        public void Abandon()  // czyszczenie
        {

            _session.Abandon();
        }

        public T Get<T>(string key)
        {

            return (T)_session[key];
        }

        public T Get<T>(string key, Func<T> createDefault)
        {

            T retval;

            if (_session[key] != null && _session[key].GetType() == typeof(T))
            {
                retval = (T)_session[key];
            }
            else
            {
                retval = createDefault();
                _session[key] = retval;
            }

            return retval;
        }

        public void Set<T>(string name, T value)
        {

            _session[name] = value;
        }

        public T TryGet<T>(string key)
        {

            try
            {
                return (T)_session[key];
            }
            catch (NullReferenceException)
            {
                return default(T);
            }
        }
    }
}

W stronie w tym momencie odwołujemy się do tej akcji:

KOSZYK (<span id="cart-header-items-count">@Html.Action("GetCartItemsCount", "Cart")</span>)

Dorzucam jeszcze shoppingCartMenager

using MojSklepMVC.DAL;
using MojSklepMVC.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MojSklepMVC.Infrastucture
{
    public class ShoppingCartManager
    {
        private StoreContext db;
        private ISessionManager session;
        public const string CartSessionKey = "CartData";


        public ShoppingCartManager(ISessionManager session, StoreContext db)
        {
            this.session = session;
            this.db = db;
        }


        public void AddToCart(int albumid)
        {
            var cart = this.GetCart();

            var cartItem = cart.Find(c => c.Album.AlbumId == albumid);

            if (cartItem != null)
                cartItem.Quantity++;
            else
            {
                // Find album and add it to cart
                var albumToAdd = db.Albums.Where(a => a.AlbumId == albumid).SingleOrDefault();
                if (albumToAdd != null)
                {
                    var newCartItem = new CartItem()
                    {
                        Album = albumToAdd,
                        Quantity = 1,
                        TotalPrice = albumToAdd.Price
                    };

                    cart.Add(newCartItem);
                }
            }

            session.Set(CartSessionKey, cart);
        }

        public List<CartItem> GetCart()
        {
            List<CartItem> cart;

            if (session.Get<List<CartItem>>(CartSessionKey) == null)
            {
                cart = new List<CartItem>();
            }
            else
            {
                cart = session.Get<List<CartItem>>(CartSessionKey) as List<CartItem>;
            }

            return cart;
        }

        public int RemoveFromCart(int albumid)
        {
            var kartazakupow = this.GetCart();
            var album = kartazakupow.Find(c => c.Album.AlbumId == albumid);

            if (album != null)
            {
                if (album.Quantity > 1)
                {
                    album.Quantity--;
                    return album.Quantity;
                }
                else
                    kartazakupow.Remove(album);
            }
            return 0;
        }

        public decimal GetCartTotalPrice()
        {
            var cart = this.GetCart();
            return cart.Sum(c => (c.Quantity * c.Album.Price));
        }


        public int GetCartItemsCount()
        {
            var cart = this.GetCart();
            int count = cart.Sum(c => c.Quantity);

            return count;
        }

        public Order CreateOrder(Order newOrder, string userId)
        {
            var cart = this.GetCart();

            newOrder.DateCreated = DateTime.Now;
            newOrder.UserId = userId;

            this.db.Orders.Add(newOrder);

            if (newOrder.OrderItems == null)
                newOrder.OrderItems = new List<OrderItem>();

            decimal cartTotal = 0;

            foreach (var cartItem in cart)
            {
                var newOrderItem = new OrderItem()
                {
                    AlbumId = cartItem.Album.AlbumId,
                    Quantity = cartItem.Quantity,
                    UnitPrice = cartItem.Album.Price
                };

                cartTotal += (cartItem.Quantity * cartItem.Album.Price);

                newOrder.OrderItems.Add(newOrderItem);
            }

            newOrder.TotalPrice = cartTotal;

            this.db.SaveChanges();

            return newOrder;
        }

        public void EmptyCart()
        {
            session.Set<List<CartItem>>(CartSessionKey, null);
        }
        
    }
}
1

No i problem jest cały czas ten sam. W SessionManager ustawiasz sobie _session na null, a potem z tego null próbujesz wyciągać jakieś wartości. Zamiast tego, w metodach SessionManager operuj po prostu na HttpContext.Current.

0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;

namespace MojSklepMVC.Infrastucture
{
    public class SessionManager : ISessionManager
    {
         HttpSessionState _session = HttpContext.Current.Session;


        public SessionManager()
        {
            //this._session = HttpContext.Current.Session;
        }



        public void Abandon()  // czyszczenie
        {

            HttpContext.Current.Session.Abandon();
        }

        public T Get<T>(string key)
        {

            return (T)HttpContext.Current.Session[key];
        }

        public T Get<T>(string key, Func<T> createDefault)
        {

            T retval;

            if (HttpContext.Current.Session[key] != null && HttpContext.Current.Session[key].GetType() == typeof(T))
            {
                retval = (T)HttpContext.Current.Session[key];
            }
            else
            {
                retval = createDefault();
                HttpContext.Current.Session[key] = retval;
            }

            return retval;
        }

        public void Set<T>(string name, T value)
        {

            HttpContext.Current.Session[name] = value;
        }

        public T TryGet<T>(string key)
        {

            try
            {
                return (T)HttpContext.Current.Session[key];
            }
            catch (NullReferenceException)
            {
                return default(T);
            }
        }
    }
}

Ustawiłem tak i widzę, że HttpContext.Current.Session przyjmuje zawsze wartosc zerową... Czyli problem od początku leżał zupełnie gdzie indziej :/ Tak jakby w ogóle domyslnie nie podpisywał tam, żadnej wartości

0

Ech, no w pracy tego nie zdebuguję, spróbuję przysiąść wieczorem jakbyś nie znalazł rozwiązania wcześniej.

0

I jak udało się dojrzeć błąd ?

0

Zrobiłem pusty projekt, wkleiłem Twój kod i Session mam normalnie wypełniony.

W której wersji MVC pracujesz?
Nie masz nic w web.config zmieniającego ustawienia sesji?
Ten kod: KOSZYK (<span id="cart-header-items-count">@Html.Action("GetCartItemsCount", "Cart")</span>) masz po prostu w jakimś widoku cshtml powiązanym z CartController czy to jakiś partial view, layout, albo jeszcze coś innego?

0

Hmm..... Czyli jednak to ustawienia...
-To jest MVC 5.2.3
web.cofing do view`sów

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="MojSklepMVC" />
        <add namespace="MvcSiteMapProvider.Web.Html" />
        <add namespace="MvcSiteMapProvider.Web.Html.Models" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>
  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>
  <system.webServer>
    <handlers>
      <remove name="BlockViewHandler" />
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
  <system.web>
    <compilation>
      <assemblies>
        <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
    </compilation>
  </system.web>
</configuration>

confing globalny

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301880
  -->
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  </configSections>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="MvcSiteMapProvider_IncludeAssembliesForScan" value="MojSklepMVC" />
    <add key="MvcSiteMapProvider_UseExternalDIContainer" value="false" />
    <add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="true" />
  </appSettings>
  <connectionStrings>
    <add name="connString" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=GlownaBazaD;Integrated Security=SSPI; AttachDBFilename=|DataDirectory|\GlownaBazaD.mdf" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" requestPathInvalidCharacters="&lt;,&gt;,*,%,:,\,?" />
    <httpModules>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
    </httpModules>
    <pages>
      <namespaces>
        <add namespace="MvcSiteMapProvider.Web.Html" />
        <add namespace="MvcSiteMapProvider.Web.Html.Models" />
      </namespaces>
    </pages>
  </system.web>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
      <remove name="UrlRoutingModule-4.0" />
      <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
    </modules>
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="System.Data.SqlServerCe.4.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SqlServerCe.4.0" />
      <add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
      <remove invariant="MySql.Data.MySqlClient" />
      <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
  </system.data>
</configuration>

-kod znajduje się w layout`cie

0

To też mam 5.2.3, nic złego też w web.config nie widzę.
Zrób nowy projekt od zera i wklej ten swój kod, i wtedy zobacz. Tu się jakaś magia dzieje...
A, i spróbuj może przeczyścić katalogi tymczasowe IIS/IIS Express i C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files.

0

Tak analizowałem jeszcze raz kod... Czy ta linia nie odpowiada za konfigurację?

 <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
0

To jedna z wielu linijek konfiguracyjnych, ale niezwiązana z Session. W czystym projekcie ta linijka wygląda tak samo.

0

Podany przez Ciebie folder jest u mnie pusty
I niestety z tego co wychodzi błąd jest gdzieś u mnie w kodzie bo wrzuciłem do nowego projektu i faktycznie działa...
wrzuciłem to nawet w ten sposób jak było wcześniej, że wywołanie było w konstruktorze i też działało

1 użytkowników online, w tym zalogowanych: 0, gości: 1