Access Session in WCF service from WebHttpBinding - asp.net

I'm using WCF service (via WebGet attribute).
I'm trying to access Session from WCF service, but HttpContext.Current is null
I added AspNetCompatibilityRequirements and edited web.config but I still cannot access session.
Is it possible to use WebGet and Session together?
Thank you!

Yes, it is possible. If you edit the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
and add the AspNetCompatiblityRequirements, the HttpContext.Current should be available.
Check everything once again, maybe you've put the attribute in the wrong place (the interface instead of the class?).

A RESTfull service with a session?
See excellent discussion here: Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"
http://javadialog.blogspot.co.uk/2009/06/common-rest-mistakes.html (point 6)
and
http://www.peej.co.uk/articles/no-sessions.html
Quote from Paul Prescod:
Sessions are irrelevant.
There should be no need for a client to "login" or "start a connection." HTTP authentication is done
automatically on every message. Client applications are consumers of
resources, not services. Therefore there is nothing to log in to!
Let's say that you are booking a flight on a REST web service. You
don't create a new "session" connection to the service. Rather you ask
the "itinerary creator object" to create you a new itinerary. You can
start filling in the blanks but then get some totally different
component elsewhere on the web to fill in some other blanks. There is
no session so there is no problem of migrating session state between
clients. There is also no issue of "session affinity" in the server
(though there are still load balancing issues to continue).

Related

WCF request doesn't flow via asp.net pipeline

I have a WCF service hosted in an asp.net application.
Here's the service (shortened):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceContract(Name = Name, Namespace = Namespace)]
[ServiceBehavior(Name = Name, Namespace = Namespace)]
public class WcfMaintenanceFacade {...}
Here's hosting:
RouteTable.Routes.Add(new ServiceRoute("entity/maintenance/5.20", new ServiceHostFactory(), typeof(WcfMaintenanceFacade)));
And here's relevant config section:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
My service instantiates, the requests are coming in, and event HttpContext.Current is not empty.
There are two (major, for me) issues that I can't solve:
HttpContext.Current.Session is empty
Global.asax's Application_BeginRequest is never called
And yes, from the call stack it seems like the request is going through WCF activation pipeline, not ASP.net pipeline. So what am I doing wrong?
About the session, you handle it with OperationContext.Current.RequestContext instead of HttpContext.Current.Session.
HttpContext: Current is always null when accessed from within a WCF
service. Use
T:System.ServiceModel.OperationContext.Current.RequestContext instead.
Read more here: https://msdn.microsoft.com/en-us/library/aa702682.aspx
Application_BeginRequest are used by ASP.Net applications, but WCF works different from common web applications, thus BeginRequest could not be hit on each request.
The ASP.NET HTTP runtime handles ASP.NET requests but does not
participate in the processing of requests destined for WCF services
.... he WCF Service Model intercepts messages addressed to WCF
services and routes them through the WCF transport/channel stack
So, your problem can be related to this issue. This information is also available at the same link.
Hope it helps with your questions.
And the answer is simple (and, well, obvious):
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
Yes. RAMMFAR.
For me it is clear that these two technologies are not supposed to be working in the same application, and that's why they have two different pipelines. Service by the nature is an isolated thing. Now you just try to find a workaround, relying on the fact they both work on same IIS.
I would recommend you rather start from the goals, from what you want to achieve. If you need new service-like functionality integrated into native ASP.NET application you can
1) use ASMX services (will give you SAOP if you need it) and/or page methods
2) try to integrate WEB API in case you need JSON service.

In asp.net, Web Service endpoint is incorrect when client connects to production server

I've been scouring the net for almost two days and must be missing something (possibly basic).
On the test (local) web server I have set up a simple service, and using a client, I discover the service and run it without problems.
Using the same client, I discover the same service, but on the production server using https://MyNewStuff.com/WebServices/MyService.asmx (the real internet address of the service) without problems, but when I try to run it it fails with an EndPointNotFound exception. Upon investigating I find that the client's app.config is incorrect as follows;
<endpoint address="https://ProductionWeb.Ourdomain.com/WebServices/MyService.asmx"
binding="basicHttpBinding" bindingConfiguration="MyServiceSoap"
contract="MOX24.MyServiceSoap" name="MyServiceSoap" />
i.e., not set up correctly as it reflects https://ProductionWeb.Ourdomain.com ... and not https://MyNewStuff.com/WebServices, indicating that the service (discovery) is sending the wrong information to the clients (it is sending the server's name and domain and not the 'web' name).
Any help on this would be greatly appreciated!!
If your client is a web application, put https://MyNewStuff.com/WebServices/MyService.asmx in the Web.Release.config.

Forms Authentication Cookie and WCF

I have an asp.net 4.0 application (client) that makes ajax/json calls to a http facade that then passes on the calls to our wcf service layer.
Users must authenticate on the client using forms authentication. The idea then being that the authentication cookie will be passed to and be accessible at the http facade. [Design based on Dino Esposito's book - Microsoft ASP.NET and AJAX: Architecting Web Applications]
The problem is, that at the facade, HttpContext.Current.User.Identity.Name is an empty string and IsAuthenticated is false.
I have enabled compatibility by adding the following to my system.ServiceModel section in my web.config (http facade level):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
I have decorated my service with the following:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
When I am debugging in the ajax/facade app I can see that cookies exist at HttpContext.Current.Request.Cookies. It appears that Anonymous is being used and not my authenticated user.
Both applications are running on the same IIS server.
Calls to the AJAX enabled wcf service are made via serviceProxy.js. Perhaps this method is not passing the necessary cookie?
WCF tracing is currently showing '..ASPXANONYMOUS=.....; ASP.NET_SessionId=....; .ASPXAUTH=.....' in the message log.
I get the feeling I am missing something simple but am too close to the problem.
Any suggestions welcomed.
I am not sure I completely understand the context of what you are trying to accomplish, but if these are two separate applications you are going to need to share machine keys in order to decrypt/encrypt the auth cookies in both.
in your web.config, make sure you have the following set:
<machineKey
validationKey="[generated key]"
validation="HMACSHA512"
decryptionKey="[generated key]"
decryption="AES"
/>
see how to generate these keys (and more info about them) on this codeproject article:
ASP.Net machineKey Generator - CodeProject
Let me know if this helps...

Identifying the name of the application pool from a request

In .net, in a webservice (or website) is there an easy way of getting the name of the application pool that the service is running in, from a HttpRequest or the HttpContext?
I think its:
HttpRequest.ServerVariables["APP_POOL_ID"]
See ServerVariables on MSDN: http://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx

How to expose a wcf service to different clients

I am creating a wcf service. When i add the service as a "Web reference" to my web site (I do this by using the url: http://localhost/myservice.svc?wsdl ) and then call the web methods exposed by the service, I get a "Operation has timed out" exception. However when i add the service as a "Service Reference" to the site, the calls work fine.
The reason iam adding it as a web reference is, i want to expose the wcf service to all clients like java, php .....
I have looked at the article in "http://blogs.msdn.com/juveriak/archive/2008/03/18/wcf-proxy-that-works-with-different-clients.aspx", but i have not tried converting the wsdl to a typed proxy as suggested by this article.
Any ideas on why i get a time out error when using it as a web reference?
Likely you're using WsHttpBinding rather than BasicHttpBinding. .NET 2.0 web services cannot consume a WsHttpBinding service.
The problem is one of protocol. Web service protocols are constantly changing, adding security, federated identity, and so forth. As they change, older technologies can't communicate using the newer protocols.
Thankfully, WCF will allow you to use multiple protocols in a single service -- just set up separate endpoints for each protocol you want to use. Be wary, however, as some are more secure than others.
Regarding versioning, the MessageVersion class is a good starting point.
Edit: I should have mentioned that you need to use MessageVersion as part of a custom TextMessageEncodingBindingElement binding, like so:
<bindings>
<customBinding>
<binding name="MyBinding">
<textMessageEncoding messageVersion="Soap11WSAddressing10"/>
<httpTransport/>
</binding>
</customBinding>
</bindings>

Resources