セッションと REST は必ずしも連携して動作しないのは理解していますが、新しい Web API を使用してセッション状態にアクセスすることはできないのでしょうか?HttpContext.Current.Session
は常に null です。
ベストアンサー1
MVCC の
MVC プロジェクトの場合は、次の変更を加えます (WebForms と Dot Net Core の回答は下にあります)。
WebApiConfig.cs
public static class WebApiConfig
{
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 }
);
}
}
グローバル.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);
}
}
このソリューションには、AJAX 呼び出しを行うために JavaScript でベース URL を取得できるという追加の利点があります。
_レイアウト.cshtml
<body>
@RenderBody()
<script type="text/javascript">
var apiBaseUrl = '@Url.Content(ProjectNameSpace.WebApiConfig.UrlPrefixRelative)';
</script>
@RenderSection("scripts", required: false)
そして、Javascript ファイル/コード内で、セッションにアクセスできる WebAPI 呼び出しを行うことができます。
$.getJSON(apiBaseUrl + '/MyApi')
.done(function (data) {
alert('session data received: ' + data.whatever);
})
);
Webフォーム
上記を実行しますが、WebApiConfig.Register 関数を変更して、代わりに RouteCollection を取得します。
public static void Register(RouteCollection routes)
{
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: WebApiConfig.UrlPrefix + "/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
次に、Application_Start で以下を呼び出します。
WebApiConfig.Register(RouteTable.Routes);
ドットネットコア
Microsoft.AspNetCore.Session NuGet パッケージを追加し、次のコード変更を加えます。
スタートアップ.cs
ConfigureServices 関数内のサービス オブジェクトでAddDistributedMemoryCacheメソッドとAddSessionメソッドを呼び出します。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
...
services.AddDistributedMemoryCache();
services.AddSession();
そして、Configure 関数にUseSessionの呼び出しを追加します。
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
app.UseSession();
app.UseMvc();
セッションコントローラ.cs
コントローラー内で、先頭に using ステートメントを追加します。
using Microsoft.AspNetCore.Http;
そして、コード内で HttpContext.Session オブジェクトを次のように使用します。
[HttpGet("set/{data}")]
public IActionResult setsession(string data)
{
HttpContext.Session.SetString("keyname", data);
return Ok("session data set");
}
[HttpGet("get")]
public IActionResult getsessiondata()
{
var sessionData = HttpContext.Session.GetString("keyname");
return Ok(sessionData);
}
これで次の操作を実行できるはずです:
http://localhost:1234/api/session/set/thisissomedata
そして、この URL にアクセスすると、次の内容が取り出されます。
http://localhost:1234/api/session/get
dot net core 内でセッション データにアクセスする方法については、次のリンクでさらに詳しく説明されています。https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state
パフォーマンスに関する懸念
パフォーマンスに関しては、以下の Simon Weaver の回答をお読みください。WebApi プロジェクト内でセッション データにアクセスすると、パフォーマンスに非常に重大な影響が出る可能性があります。ASP.NET が同時要求に対して 200 ミリ秒の遅延を強制するのを見たことがあります。同時要求が多数ある場合、これが積み重なって悲惨な結果になる可能性があります。
セキュリティ上の懸念
ユーザーごとにリソースをロックダウンしていることを確認してください。認証されたユーザーは、アクセス権のないデータを WebApi から取得できないようにする必要があります。
ASP.NET Web API の認証と承認に関する Microsoft の記事を読む -https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
クロスサイト リクエスト フォージェリ ハッキング攻撃を回避するための Microsoft の記事をお読みください。(簡単に言うと、AntiForgery.Validate メソッドを確認してください) -https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks