1. ホーム
  2. asp.net

[解決済み】ASP.NET Web APIを使用したセッションへのアクセス

2022-04-15 04:12:41

質問

セッションとRESTは必ずしも相性が良いとは言えないと思いますが、新しいWeb APIを使ってセッションの状態にアクセスすることはできないのでしょうか? HttpContext.Current.Session は常に null です。

解決方法は?

<ブロッククオート

MVC

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 }
        );
    }
}

グローバル.アサックス.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を取得することができるという利点があります。

_Layout.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);
   })
);


<ブロッククオート

ウェブフォーム

上記を実行しますが、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

を呼び出す。 AddDistributedMemoryCache セッションの追加 メソッドを使用することで、ConfigureServices 関数内でサービスオブジェクトにアクセスできます。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    ...

    services.AddDistributedMemoryCache();
    services.AddSession();

という呼び出しを追加し、Configure 関数で セッションを使用する :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
ILoggerFactory loggerFactory)
{
    app.UseSession();
    app.UseMvc();

セッションコントローラ(SessionController.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

ドットネットコアのセッションデータへのアクセスについて、詳しくはこちらをご覧ください。 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state

<ブロッククオート

パフォーマンスに関する懸念

パフォーマンスについては、以下のSimon Weaver氏の回答をお読みください。WebApiプロジェクト内でセッションデータにアクセスしている場合、パフォーマンスに深刻な影響が出る可能性があります。ASP.NETが同時リクエストに対して200msの遅延を強制するのを見たことがあります。ASP.NETが同時リクエストに200msの遅延を強制するのを見たことがあります。これは、多くの同時リクエストがある場合、積み重なって悲惨なことになるかもしれません。


<ブロッククオート

セキュリティへの配慮

ユーザーごとにリソースをロックしていることを確認してください。認証されたユーザーは、アクセス権のないデータをWebApiから取得できないようにする必要があります。

ASP.NET Web APIにおける認証と認可に関するマイクロソフトの記事をお読みください。 https://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

クロスサイトリクエストフォージェリーのハッキング攻撃を回避するためのマイクロソフトの記事を読んでください。(要するに、AntiForgery.Validateメソッドをチェックアウトしてください) -。 https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks