Skip to content

Instantly share code, notes, and snippets.

@rogersillito
Created May 19, 2015 12:48
Show Gist options
  • Save rogersillito/e1b84bd325611c04200e to your computer and use it in GitHub Desktop.
Save rogersillito/e1b84bd325611c04200e to your computer and use it in GitHub Desktop.
A test web project to show unexpected behaviour in Nancy.FlashMessages when setting messages between http requests
using Nancy;
using Nancy.Bootstrapper;
using Nancy.Conventions;
using Nancy.FlashMessages;
using Nancy.Session;
using Nancy.TinyIoc;
namespace NancyFlashTestHarness
{
public class CustomBootstrapper: DefaultNancyBootstrapper
{
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
CookieBasedSessions.Enable(pipelines);
FlashMessages.Enable(pipelines);
}
protected override void ConfigureConventions(NancyConventions nancyConventions)
{
base.ConfigureConventions(nancyConventions);
nancyConventions.StaticContentsConventions.Add(StaticContentConventionBuilder.AddDirectory("/css"));
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Nancy" version="1.2.0" targetFramework="net45" />
<package id="Nancy.FlashMessages" version="1.0.4.0" targetFramework="net45" />
<package id="Nancy.FlashMessages.Razor" version="1.0.4.0" targetFramework="net45" />
<package id="Nancy.Hosting.Aspnet" version="1.2.0" targetFramework="net45" />
<package id="Nancy.Viewengines.Razor" version="0.23.0" targetFramework="net45" />
</packages>
@using Nancy.FlashMessages
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<style>body { padding: 10px; }</style>
<link href="/css/bootstrap.css" rel="stylesheet"/>
<title>title</title>
</head>
<body>
<div>
@Html.FlashMessages(FlashMessages.Success)
</div>
</body>
</html>
using System;
using Nancy;
using Nancy.FlashMessages;
using Nancy.FlashMessages.Extensions;
namespace NancyFlashTestHarness
{
public class TestModule : NancyModule
{
private const string SessionKey = "TestSessionKey";
public TestModule()
: base("/Test")
{
Get["/Menu"] = _ =>
{
Func<string, string> buttonPostToAction = action =>
string.Concat("<form action=\"", action, "\" method=\"post\"><input type=\"submit\" value=\"", action, "\"></form>");
var s = "<html><body>";
s += buttonPostToAction("SetSessionKey");
s += buttonPostToAction("SetSessionKeyAndFlashMessage");
s += buttonPostToAction("ReadSessionKey");
s += buttonPostToAction("ClearSessionKey");
s += buttonPostToAction("SetSessionKeyThenRedirectToView");
s += buttonPostToAction("SetBothSessionKeyAndFlashMessageThenRedirectToView");
s += "</body></html>";
this.FlashMessage(FlashMessages.Success, "This got set on Menu screen");
return s;
};
Post["/ClearSessionKey"] = _ =>
{
Session.Delete(SessionKey);
return SessionKey + " cleared";
};
Post["/ReadSessionKey"] = _ =>
Session[SessionKey] + " (ReadSessionKey)";
Post["/SetSessionKey"] = _ =>
{
SetSessionKey();
return Session[SessionKey] + " (SetSessionKey)";
};
Post["/SetSessionKeyAndFlashMessage"] = _ =>
{
this.FlashMessage(FlashMessages.Success, "This got set without doing a redirect");
SetSessionKey();
return Session[SessionKey] + " - Flash Message was also set. (SetSessionKeyAndFlashMessage)";
};
Get["/view"] = _ =>
{
// the following flash message is the only one that ever appears??
this.FlashMessage(FlashMessages.Success, "This got set AFTER redirect: App1 = " + Session[SessionKey]);
return View["Test"];
};
Post["/SetSessionKeyThenRedirectToView"] = _ =>
{
// redirecting from here works as expected: TestSessionKey is still present in Session when we hit Get["/view"]
SetSessionKey();
return Response.AsRedirect("view");
};
Post["/SetBothSessionKeyAndFlashMessageThenRedirectToView"] = _ =>
{
// redirecting from here demonstrates the issue:
// TestSessionKey is no longer present in Session when we hit Get["/view"]
// Also the __fm session key used by FlashMessages is missing
// note - if we had previously set TestSessionKey (by /SetSessionKey) we will see the PREVIOUS value of the key
// but not the one we set on the next line:
this.FlashMessage(FlashMessages.Success, "This got set BEFORE redirect: TestSessionKey = " + Session[SessionKey]);
SetSessionKey();
return Response.AsRedirect("view");
};
}
private void SetSessionKey()
{
Session[SessionKey] = DateTime.Now.ToLongTimeString();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<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="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5">
<buildProviders>
<add extension=".cshtml" type="Nancy.ViewEngines.Razor.BuildProviders.NancyCSharpRazorBuildProvider, Nancy.ViewEngines.Razor.BuildProviders" />
<add extension=".vbhtml" type="Nancy.ViewEngines.Razor.BuildProviders.NancyVisualBasicRazorBuildProvider, Nancy.ViewEngines.Razor.BuildProviders" />
</buildProviders>
</compilation>
<httpRuntime targetFramework="4.5" />
<httpHandlers>
<add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</httpHandlers>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors existingResponse="PassThrough" />
<handlers>
<add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*" />
</handlers>
</system.webServer>
<appSettings>
<add key="webPages:Enabled" value="false" />
</appSettings>
<system.web.webPages.razor>
<pages pageBaseType="Nancy.ViewEngines.Razor.NancyRazorViewBase">
<namespaces>
<add namespace="Nancy.ViewEngines.Razor" />
</namespaces>
</pages>
</system.web.webPages.razor>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment