I've setup a site with forms authentication and AspNetCompatibility enabled. The actual client is a silverlight application, and works fine, however I want to unit test the application separately using normal .net to exercise the service (live system for methods without side-effects). However, when I stop using Silverlight and start using full .net it doesn't remain authenticated
In a web service I have:
[OperationContract]
public bool Login(string Username, string Password, bool isPersistent)
{
if (Membership.ValidateUser(Username, Password))
{
FormsAuthentication.SetAuthCookie(Username, isPersistent);
return true;
}
else
{
return false;
}
}
[OperationContract]
public bool IsLoggedIn()
{
return HttpContext.Current.User.Identity.IsAuthenticated;
}
Then in a test method on the client I call it like so:
Assert.IsTrue(Client.Login("MyUsername","MyPassword", true));
Assert.IsTrue(Client.IsLoggedIn());
The client is an instance of the automatically generated ServiceReference client for .net. The first assertion passes but the second one fails, i.e. from one method call to the next it stops being logged in. A similar method in the silverlight application would pass.
How can I make normal .net behave correctly as silverlight would? Is there just a better way of configuring client/service for full .net?
Aditional Info Requested
Service Config:
<services>
<service behaviorConfiguration="MyBehaviour" name="SSCCMembership.Web.Services.LoginService">
<endpoint address="" binding="customBinding" bindingConfiguration="customBindingBinary"
contract="SSCCMembership.Web.Services.LoginService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<customBinding>
<binding name="customBindingBinary">
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
Authentication Config:
<authentication mode="Forms" />
<membership defaultProvider="OdbcProvider">
<providers>
<clear />
<add name="OdbcProvider" type="SSCCMembership.Web.SimpleMembershipProvider" applicationName="/SSCCMembership" requiresUniqueEmail="false" connectionStringName="mainConn" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" writeExceptionsToEventLog="true" />
</providers>
</membership>
I then use the following to construct the client in WPF
public static T LoadService<T>(string URI, Func<CustomBinding, EndpointAddress, T> F)
{
try
{
Uri U = new Uri(new Uri(Root), URI);
BinaryMessageEncodingBindingElement binary = new BinaryMessageEncodingBindingElement();
HttpTransportBindingElement transport;
if (U.Scheme == "http")
transport = new HttpTransportBindingElement();
else if (U.Scheme == "https")
transport = new HttpsTransportBindingElement();
else
throw new Exception(U.Scheme + " is not a recognised URI scheme");
transport.MaxBufferSize = int.MaxValue;
transport.MaxReceivedMessageSize = transport.MaxBufferSize;
transport.AllowCookies = true;
CustomBinding binding;
binding = new CustomBinding(binary, transport);
EndpointAddress address = new EndpointAddress(U);
return F(binding, address);
}
catch (Exception)
{
return default(T);
}
}
Which I call like:
var Client = LoadService(ServiceLocation, (b,e)=>new LoginServiceClient(b,e));