Per-Session Services based on WSHttpBinding
-
Tuesday, January 26, 2010 9:17 AM
Hi Folks. I am writing a WCF services based on http, which can be consumed by web browsers. Because my web method might return a huge number of objects, so that a single Request-Reply method call doesn't meet my need.
Firstly, I chose to use WSDualHTTPBinding to leverage its "call back", but it seems not work if browser raises a Ajax invocation. So I switched to WSHttpBinding to make it as a Per-Session Service. Then my Browser and my client (yup, my service supports both web browsers and windows clients) can raise a "poll" to get those objects, 100 for each time.
I do read some docs, which said WSHttpBinding supports Per-Session services. But I cannot get it work. Here is just my client code sample, and the InvalidOperationException is thrown when creating a channel and says "Contract requires Session, but Binding 'WSHttpBinding' doesn't support it or isn't configured properly to support it."
So my question is that:
a.) what's the right way to get a huge number of objects thru web services?
b.) Is the WSHttpBinding right one for my scenario? Basically, I need any web browsers can consume my service, besides my current client;
c.) How to make WSHttpBinding support Per-Session call?
Thx!!!
[
ServiceContract(SessionMode = SessionMode.Required)]
public interface IDDIService
{
[
OperationContract()]void BeginGetList(string schemaName);
[
OperationContract()]
object[] GetList();
}
public
static void Main(string[] args)
{
EndpointAddress endPoint = new EndpointAddress(new Uri("https://myMachine/Service.svc"));
WSHttpBinding binding = new WSHttpBinding(SecurityMode.Transport, false);
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Certificate;
binding.SendTimeout =
new TimeSpan(0, 10, 0);
ChannelFactory<IDDIService> factory = new ChannelFactory<IDDIService>(binding, endPoint);
factory.Credentials.Windows.ClientCredential =
new NetworkCredential("administrator", "password");
IDDIService moacService = factory.CreateChannel();
All Replies
-
Tuesday, January 26, 2010 9:24 AMModeratorWSHttpBinding supports session but only if either security (SecureConversation) or reliable messaging are enabled. So with the standard defaults, if you then change the security mode to none for the binding then it can;t support session
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewett -
Tuesday, January 26, 2010 9:32 AM
"if you then change the security mode to none for the binding then it can;t support session"
But I didn't change security mode to none, the whole code is above. :-( -
Tuesday, January 26, 2010 9:38 AMModeratorAre you using a different proxy instance for the requests?
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewett -
Tuesday, January 26, 2010 9:47 AM
Absolutely not. The whole client code is listed below, I believe it's very simple and direct. But don't know what's wrong.
using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Security.Principal; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.Text; using System.Threading; using System.Xml; using System.Globalization; using System.IO; using System.Security; using System.Net; namespace TestMoac { /// <summary> /// Public interface for extensions web services /// </summary> [ServiceContract(SessionMode = SessionMode.Required)] public interface IDDIService { [OperationContract()] void BeginGetList(string schemaName); [OperationContract()] object[] GetList(); } class Program { public static void Main(string[] args) { // Turn off the server SSL cert check System.Net.ServicePointManager.ServerCertificateValidationCallback += CertificateValidationCallBack; try { EndpointAddress endPoint = new EndpointAddress(new Uri("https://bjexvm117/ecp/DDIService/DDIService.svc")); WSHttpBinding binding = new WSHttpBinding(SecurityMode.Transport, false); binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; binding.SendTimeout = new TimeSpan(0, 10, 0); ChannelFactory<IDDIService> factory = new ChannelFactory<IDDIService>(binding, endPoint); factory.Credentials.Windows.ClientCredential = new NetworkCredential("administrator", "J$p1ter"); IDDIService moacService = factory.CreateChannel(); moacService.BeginGetList("Test"); var list = moacService.GetList(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static bool CertificateValidationCallBack( object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; } } } -
Tuesday, January 26, 2010 9:52 AMModerator
oh - if you are using transport security then it is not using WS-SecureConversation and WS-ReliableMessaging is turned off by default. Therefore the two protocols that WSHttpBinding uses for session are not available. You either need to use message security or turn on reliable session
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewett- Marked As Answer by Mog LiangModerator Wednesday, February 03, 2010 1:40 AM
-
Tuesday, January 26, 2010 11:27 AMThank for the reply. So I added the following code to enable reliable session, but get another error message, "Binding validation failed because the WSHttpBinding does not support reliable sessions over transport security (HTTPS). The channel factory or service host could not be opened. Use message security for secure reliable messaging over HTTP."
Does that mean if I want to use per session call, I have to use Message mode? in which I have to pass my credential as a text?
binding.ReliableSession.Enabled =
true;
-
Tuesday, January 26, 2010 12:29 PMModerator
You can use certificate based authentication over message security
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewett

