The reason you should never set EnableSession to true in WebService
Today, I found one interesting mechanism of ASP.Net WebService (WebMethod) which is if you enable EnableSession in your WebMethod, all your WebMethods with EnableSession(true) will become synchronous operations.
This is what Microsoft tell us:
Note Enabling session state pins each session to one thread (to protect session data). Concurrent calls from the same session are serialized once they reach the server, so they have to wait for each other, regardless of the number of CPUs.
And
Maintaining session state has an impact on concurrency. If you keep data in session state, Web services calls made by one client are serialized by the ASP.NET runtime. Two concurrent requests from the same client are queued up on the same thread in the Web service the second request waits until the first request is processed.
Hope this help!
The BDD Way for ASP.Net MVC – Setting Up
In this series, I want to share my BDD way for ASP.Net MVC.
I’m a big fan of BDD development using Rails, Cucumber, Webrat and RSpec. As a .NET developer and BDD lover, I aslo want to use BDD development (outside-in development) for my ASP.Net MVC development. After spending a few days, I can make it almost the same BDD workflow as rails development.
To get the workflow, I used the following tools and frameworks.
Setting up the environment
- Download and install SpecFlow
- Download and install TestDriven.Net (as of writting this post, I used version 3.0.2749 )
- Download and extract xUnit (I used version 1.6.1) to your prefer place
- Download and extract WatiN (I used version 2.0.20.1089) to your prefer place
Create Project structure
- Create MVC 2 project with Solution (I chose not to create unit test project since I prefer to create from scratch)
- Create “lib” folder under solution folder
- Copy these files from your extracted xUnit folder to lib folder.
- xunit.dll,
- xunit.xml,
- xunit.dll.tdnet,
- xunit.runner.tdnet.dll,
- xunit.runner.utility.dll,
- xunit.runner.utility.xml
- Copy TechTalk.SpecFlow.dll from SpecFlow installed folder to lib folder. (My SpecFlow installed folder is “C:\Program Files\TechTalk\SpecFlow”)
- Copy these files from WatiN folder to lib folder
- WatiN.Core.dll
- WatiN.Core.xml
- Interop.SHDocVw.dll
- Microsoft.mshtml.dll
- After you copied, you should have 11 files inside your lib folder.
- Create Features project with Class Library type (I will use this project to test the features including UI to database. aka IntegrationTest)
- Delete Class1.cs file from the project. (I don’t know why Microsoft added that file by default since I have to delete everytime)
- Add Reference “TechTalk.SpecFlow.dll” and “xunit.dll” from lib folder.
- Add App.config file. (We need to hook SpecFlow with xUnit)
- I modify App.config with the following content.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow"/> </configSections> <specFlow> <unitTestProvider name="xUnit" /> </specFlow> </configuration> - Add User Login feature (Add > New Item > SpecFlowFeature (template) )
- Right click on the project node in the Solution Explorer and click “Run Test(s)” (if you cannot see the menu, you need to install TestDriven.Net)
- Now you should be able to run test and see it failed.
In the next post, I’ll show how to run UI automation test using WatiN, SpecFlow and xUnit. Stay tune.
Start Development WebServer from C#
I need to start the development webserver (if it was not started yet). Here is the code.
private const int PORT_NUMBER = 1852; // the port number to used for SpecFlow testing
[BeforeTestRun()]
public static void StartWebServer()
{
if (ExistsPort())
return;
// settings
string LocalHostUrl = string.Format("http://localhost:{0}", PORT_NUMBER);
string PhysicalPath = Path.GetFullPath(@"..\..\..\Web"); // the path of compiled web app
// create a new process to start the ASP.NET Development Server
Process process = new Process();
/// configure the web server
process.StartInfo.FileName = @"C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\WebDev.WebServer40.EXE";
process.StartInfo.Arguments = string.Format("/port:{0} /path:\"{1}\" /virtual:\"{2}\"", PORT_NUMBER, PhysicalPath, LocalHostUrl);
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
// start the web server
var started = process.Start();
}
private static bool ExistsPort()
{
var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
return ipGlobalProperties.GetActiveTcpConnections().Any(info => info.LocalEndPoint.Port == PORT_NUMBER);
}