2017-05-22 1 views
4

Salut s'il vous plaît aidez-moi Im essayant de tester les sessions dans le noyau de asp.net mais quand je mets la session et l'obtenir d'un autre contrôleur, il semble être nulleImpossible d'accéder à la session asp.net core

Heres mon démarrage

public class Startup 
{ 

    public IConfigurationRoot Configuration { get; } 
    public Startup(IHostingEnvironment env) 
    { 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
      .AddEnvironmentVariables(); 
     Configuration = builder.Build(); 
    } 


    // This method gets called by the runtime. Use this method to add services to the container. 
    public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     services.AddMvc().AddJsonOptions(options => { 
      options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
     }); 

     // Adds a default in-memory implementation of IDistributedCache. 
     services.AddDistributedMemoryCache(); 

     services.AddSession(options => 
     { 
      // Set a short timeout for easy testing. 
      options.IdleTimeout = TimeSpan.FromSeconds(600); 
      options.CookieHttpOnly = true; 
     }); 


     services.AddSingleton<IConfiguration>(Configuration); 
     services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>(); 
     services.AddTransient<IApiHelper, ApiHelper>(); 



    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     app.UseSession(); 
     app.UseDeveloperExceptionPage(); 
     if (env.IsDevelopment()) 
     { 
      app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { 
       HotModuleReplacement = true, 
       ReactHotModuleReplacement = true 
      }); 
     } 

     //var connectionString = Configuration.GetSection("ConnectionStrings").GetSection("ClientConnection").Value; 


     app.UseStaticFiles(); 
     loggerFactory.AddConsole(); 


     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
      routes.MapSpaFallbackRoute(
       name: "spa-fallback", 
       defaults: new { controller = "Home", action = "Index" }); 
     }); 
    } 

    public static void Main(string[] args) { 
     var host = new WebHostBuilder() 
      .UseContentRoot(Directory.GetCurrentDirectory()) 
      .UseIISIntegration() 
      .UseKestrel() 
      .UseStartup<Startup>() 
      .Build(); 

     host.Run(); 
    } 
} 

et voici comment je mets la session

public class HomeController : Controller 
{ 
    public IActionResult Index() 
    { 

     HttpContext.Session.SetString("Test", "Ben Rules!"); 

     return View(); 
    } 

    public IActionResult Error() 
    { 
     return View(); 
    } 
} 

et ici mon exemple de code d'obtenir la session à nouveau, mais il semble être nulle

[HttpGet("[action]")] 
    public IEnumerable<JobDescription> GetJobDefinitions() 
    { 
     //this is always null 
     var xd = HttpContext.Session.GetString("Test"); 


     var x = _apiHelper.SendRequest<Boolean>($"api/JobRequest/GetJobRequest",null); 
     var returnValue = new List<JobDescription>(); 
     returnValue = jobDescriptionManager.GetJobDescriptions(); 
     return returnValue; 


    } 

Merci pour l'aide

+0

Assurez-vous que vous avez fourni un cookie de session à votre demande GET 'GetJobDefinitions'. Le cookie doit être envoyé au serveur avec chaque requête. Le serveur utilise l'ID de session du cookie pour extraire les données de session. –

+0

Salut illya merci de répondre, pouvez-vous me donner un exemple brut merci –

+1

Faites une requête GET dans le navigateur et recherchez un cookie nommé '.AspNet.Session' dans devtools. Le navigateur l'ajoute automatiquement aux prochaines demandes dans une session de navigateur. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state –

Répondre

0

Pour accéder à une session, vous voulez utiliser le HttpContext.Current pour préciser la session souhaitée. Cependant, une approche plus appropriée serait:

public interface MemoryStorageService<T> where T : class 
{ 
    IEnumerable<T> Get(); 
} 

public class ExampleService : MemoryStorageService<Example> 
{ 
    private IExampleFactory factory; 
    public ExampleService(IExampleFactory factory) 
    { 
      this.factory = factory; 
    } 

    public IEnumerable<Example> Get() 
    { 
     using(var context = factory.CreateExampleRepository()) 
       return context.GetExamples(); 
    } 
} 

Puis dans votre injection de dépendance, ou dans votre base simple, IServiceCollection ajouter le services.AddCaching();. Cela ajoutera la capacité MemoryCache à votre application.

public class SampleController : Controller 
{ 
    private readonly IMemoryCache cache; 
    private readonly IMemoryStorageService<Example> service; 

    public SampleController(IMemoryCache cache, IMemoryStorageService<Example> service) 
    { 
     this.cache = cache; 
     this.service = service; 
    } 

    private List<Employee> SetGetMemoryCache() 
    { 
      string key = "MyMemoryKey-Cache"; 
      List<Example> examples; 

      if (!cache.TryGetValue(key, out examples)) 
      { 
       examples = service.Get().ToList(); 
       cache.Set(key, examples, 
        new MemoryCacheEntryOptions() 
        .SetAbsoluteExpiration(TimeSpan.FromMinutes(1))); 
      } 
      else 
      { 
       examples = cache.Get(key) as List<Example>; 
      } 

      return examples; 
    } 
} 
+0

Il s'agit d'un simple cache en mémoire sans fonctionnalité essentielle de 'Session '. Comment cela pourrait aider à OP? –

+0

@IlyaChumakov Le noyau Asp.Net spécifiquement Microsoft recommande l'approche ci-dessus plutôt que d'utiliser Session. – Greg

+0

il n'y a aucun mot à ce sujet dans la documentation officielle https://docs.microsoft.com/fr-fr/aspnet/core/fondamentaux/app-state En outre, votre code ne résout pas le problème de partage des données de l'utilisateur entre les demandes. –

0

Pour VS2017, suivez cet article officiel MSDN concernant Session and Application state in ASP.NET Core. Vous pouvez tester votre scénario dans l'exemple suivant que j'ai créé. Remarque: Bien que le code ci-dessous semble long, vous n'aurez, en fait, apporté que des modifications mineures à l'application par défaut créée à partir du modèle ASP.NET Core par défaut. Il suffit de suivre les étapes ci-dessous:

  1. Créer une application ASP.NET MVC base en utilisant le modèle par défaut sur VS2017

  2. Modifier la valeur par défaut Home controller comme indiqué ci-dessous

  3. Assurez-vous que le fichier a Startup.cs entrées liées à la session en tant que montré en Startup.cs fichier ci-dessous

  4. Lancez l'application et cliquez sur le lien Home dans la barre du haut. Ce stockera les valeurs de session ci-dessous (Nam Wam, 2017 et current date)

  5. Cliquez sur le lien About sur la barre supérieure. Vous remarquerez que les valeurs de session ont été transmises au contrôleur About. Mais je sais que n'était pas votre question car cela ne fait que tester le passage des valeurs de la session à une autre action sur le contrôleur same. Donc, pour répondre à votre question, suivez les 3 prochaines étapes.

  6. Créer un autre contrôleur AnotherController - comme indiqué ci-dessous - avec une nouvelle action Test() et une vue Test.cshtml dans un Views\Test dossier

  7. En _Layout.cshtml ajouter un autre lien <li><a asp-area="" asp-controller="Another" asp-action="Test">Test View</a></li> droit après <li>...Contact...</li> lien comme indiqué ci-dessous

  8. Exécutez à nouveau l'application et cliquez d'abord sur le lien Home dans la barre supérieure . Ensuite, cliquez sur le lien Test dans la barre supérieure. Vous remarquerez que les valeurs de session ont été transmises de HomController au AnotherController et ont été affichées avec succès sur la vue Test.

HomeController:

using System; 
using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Http; 
using Newtonsoft.Json; 

namespace MyProject.Controllers 
{ 
    public class HomeController : Controller 
    { 
     const string SessionKeyName = "_Name"; 
     const string SessionKeyFY = "_FY"; 
     const string SessionKeyDate = "_Date"; 

     public IActionResult Index() 
     { 
      HttpContext.Session.SetString(SessionKeyName, "Nam Wam"); 
      HttpContext.Session.SetInt32(SessionKeyFY , 2017); 
      // Requires you add the Set extension method mentioned in the SessionExtensions static class. 
      HttpContext.Session.Set<DateTime>(SessionKeyDate, DateTime.Now); 

      return View(); 
     } 

     public IActionResult About() 
     { 
      ViewBag.Name = HttpContext.Session.GetString(SessionKeyName); 
      ViewBag.FY = HttpContext.Session.GetInt32(SessionKeyFY); 
      ViewBag.Date = HttpContext.Session.Get<DateTime>(SessionKeyDate); 

      ViewData["Message"] = "Session State In Asp.Net Core 1.1"; 

      return View(); 
     } 

     public IActionResult Contact() 
     { 
      ViewData["Message"] = "Contact Details"; 

      return View(); 
     } 

     public IActionResult Error() 
     { 
      return View(); 
     } 

    } 

    public static class SessionExtensions 
    { 
     public static void Set<T>(this ISession session, string key, T value) 
     { 
      session.SetString(key, JsonConvert.SerializeObject(value)); 
     } 

     public static T Get<T>(this ISession session, string key) 
     { 
      var value = session.GetString(key); 
      return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value); 
     } 
    } 
} 

About.cshtml [Session valeurs variables du contrôleur same Affichage]

@{ 
    ViewData["Title"] = "ASP.Net Core !!"; 
} 
<h2>@ViewData["Title"].</h2> 
<h3>@ViewData["Message"]</h3> 


<table class="table table-responsive"> 
    <tr> 
     <th>Name</th> 
     <th>Fiscal Year</th> 
    </tr> 
    <tr> 
     <td>@ViewBag.Name</td> 
     <td>@ViewBag.FY</td> 
    </tr> 
</table> 

<label>Date : @(ViewBag.Date.ToString("dd/MM/yyyy") != "01/01/0001" ? ViewBag.Date.ToString("dd/MM/yyyy") : "")</label> 

AnotherController [Un contrôleur différent de HomeController] :

using System; 
using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Http; 

public class AnotherController : Controller 
{ 
    const string SessionKeyName = "_Name"; 
    const string SessionKeyFY = "_FY"; 
    const string SessionKeyDate = "_Date"; 

    // GET: /<controller>/ 
    public IActionResult Test() 
    { 
     ViewBag.Name = HttpContext.Session.GetString(SessionKeyName); 
     ViewBag.FY = HttpContext.Session.GetInt32(SessionKeyFY); 
     ViewBag.Date = HttpContext.Session.Get<DateTime>(SessionKeyDate); 

     ViewData["Message"] = "Session State passed to different controller"; 
     return View(); 
    } 
} 

Test.cshtml: [Session Affichage des valeurs variables transmises de contrôleur Home à Another contrôleur]

@{ 
    ViewData["Title"] = "View sent from AnotherController"; 
} 
<h2>@ViewData["Title"].</h2> 
<h3>@ViewData["Message"]</h3> 


<table class="table table-responsive"> 
    <tr> 
     <th>Test-Name</th> 
     <th>Test-FY</th> 
    </tr> 
    <tr> 
     <td>@ViewBag.Name</td> 
     <td>@ViewBag.FY</td> 
    </tr> 
</table> 

<label>Date : @(ViewBag.Date.ToString("dd/MM/yyyy") != "01/01/0001" ? ViewBag.Date.ToString("dd/MM/yyyy") : "")</label> 

_Layout.cshtml:

.... 
      <div class="navbar-collapse collapse"> 
       <ul class="nav navbar-nav"> 
        <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li> 
        <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li> 
        <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li> 
        <li><a asp-area="" asp-controller="Another" asp-action="Test">Test View</a></li> 
       </ul> 
      </div> 
.... 

Startup.cs: [Assurez-vous d'avoir s Certaines entrées liées à la session sont incluses. Très probablement lorsque vous avez créé une application ASP.NET Core MVC dans VS2017, ces entrées seront déjà présentes. Mais assurez-vous juste.]

.... 
// This method gets called by the runtime. Use this method to add services to the container. 
public void ConfigureServices(IServiceCollection services) 
{ 
    //In-Memory 
    services.AddDistributedMemoryCache(); 
    services.AddSession(options => { 
     options.IdleTimeout = TimeSpan.FromMinutes(1);//Session Timeout. 
    });    
    // Add framework services. 
    services.AddMvc(); 
} 

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseBrowserLink(); 
    } 
    else 
    { 
     app.UseExceptionHandler("/Home/Error"); 
    } 

    app.UseStaticFiles(); 

    app.UseSession(); 

    app.UseMvc(routes => 
    { 
     routes.MapRoute(
      name: "default", 
      template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 
....