asp.net-mvc - 为什么 Asp.net MVC4 不能使用 SQL Server Session 状态存储的 cookieless

标签 asp.net-mvc sql-server-2008 session-state session-cookies

所有,这是我在 Asp.net MVC4 应用程序中的 Web 配置。我发现如果我设置 cookieless false ,一切都会好起来的。但如果我不想使用 cookie 。那么应用程序就不能工作了。当我调试应用程序时,我发现 Controller 无法从 View 接收任何请求。我认为这是因为在 cookie-less 模式下,某些东西会被附加到 url 之前。比如 http://localhost:8119/(S(3cicpjpagvpunr5he5fnfrj1))/。

<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="webAssets" type="Telerik.Web.Mvc.Configuration.WebAssetConfigurationSection, Telerik.Web.Mvc" requirePermission="false" />
      <!-- 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=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <connectionStrings>
    <add name="..." connectionString="..." providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="true" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <customErrors mode="Off" />
    <httpRuntime executionTimeout="14400" maxRequestLength="716800" />
    <compilation debug="true" targetFramework="4.0" />
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" />
    </authentication>
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
        <add namespace="Telerik.Web.Mvc.UI" />
      </namespaces>
    </pages>
    <profile defaultProvider="DefaultProfileProvider">
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="DefaultMembershipProvider">
      <providers>
        <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <roleManager defaultProvider="DefaultRoleProvider">
      <providers>
        <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
    <!-- <sessionState mode="InProc" timeout="30" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </sessionState> -->
    <sessionState mode="SQLServer" cookieless="true" sqlConnectionString="data source=xxxx; User ID=xxxx; password=xxxx" timeout="300" sqlCommandTimeout="10" />
    <httpHandlers>
      <add verb="GET,HEAD" path="asset.axd" validate="false" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc" />
    </httpHandlers>
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="3000000000" />
      </requestFiltering>
    </security>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true" />
    <directoryBrowse enabled="true" />
    <handlers>
      <remove name="asset" />
      <add name="asset" preCondition="integratedMode" verb="GET,HEAD" path="asset.axd" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc" />
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.WindowsAzure.StorageClient" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.7.0.0" newVersion="1.7.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
 </configuration>

最佳答案

Html.BeginForm() 中存在一个错误与 cookieless="true" 一起使用时的助手(不带任何参数的) .它在生成 url 时不考虑 session id。所以而不是:

<form action="/(S(kkt0zgbnuaoxad23ew33iod4))/home/index" method="post">

它产生:
<form action="/home/index" method="post">

当您发帖到 /home/index自动重定向到 /(S(kkt0zgbnuaoxad23ew33iod4))通过 ASP.NET。重定向意味着 GET 请求 => 您的 POST 操作永远不会被命中。

作为解决方法,您可以编写自定义 Html.BeginForm修复错误的助手:
public static class FormExtensions
{
    public static IDisposable MyBeginForm(this HtmlHelper htmlHelper)
    {
        var rawUrl = htmlHelper.ViewContext.HttpContext.Request.RawUrl;
        var formAction = htmlHelper.ViewContext.HttpContext.Response.ApplyAppPathModifier("~/") + rawUrl;
        var builder = new TagBuilder("form");
        builder.MergeAttributes(new RouteValueDictionary());
        builder.MergeAttribute("action", formAction);
        builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(FormMethod.Post), true);
        htmlHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
        var form = new MvcForm(htmlHelper.ViewContext);
        return form;
    }
}

然后使用:
@using (Html.MyBeginForm())
{
    ...
}

就 BeginForm 助手的其他重载而言,它们应该可以正常工作并生成包含 session ID 的正确操作。

关于asp.net-mvc - 为什么 Asp.net MVC4 不能使用 SQL Server Session 状态存储的 cookieless,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12994772/

相关文章:

linq - 在 Linq 中旋转

mysql - SQL Server 2008 的 ADDTIME 和 SEC_TO_TIME

c# - FormsAuthentication.RedirectToLoginPage() 什么都不做

c# - Visual Studio 2013/打开特定扩展名的所有文件

c# - asp.net MVC 项目中的 OAuth

c# - 呈现包含存储在资源文件中的 HTML 的显示名称

jquery - MVC 帮助链接 Url.Action 不再解析

sql - 如何组合修剪和替换函数以删除字符串中任意位置的空格?

c# - 如何在负载平衡的 Azure 虚拟机上使用 SessionState

c# - IRequiresSessionState 与 IReadOnlySessionState