WCF WebGet Capture HTTP Referrer? - wcf

I have a self-hosted WCF app using Basic HTTP Binding, no SSL, running in a console app on .NET Framework 4.0.
I have a WebGet Attribute on a method to which returns a human-readable string as a "smoke test".
If I had an ASP.NET webforms page, I would use Request.UrlReferrer or ServerVariables("HTTP_REFERER") to see if the client volunteers their redirect information.
How can I do that with WCF?
Thanks.

If you're using BasicHttpBinding, the WebGet attribute is probably being ignored (it's used for endpoints which use the webHttpBinding and the WebHttpBehavior).
If you're using a "web" endpoint (WebHttpBinding / WebHttpBehavior), you can use the WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Referer]. If you don't have a reference to System.ServiceModel.Web.dll, you can also use the HttpRequestMessageProperty from the OperationContext:
HttpRequestMessageProperty prop;
prop = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
var referer = prop.Headers[HttpRequestHeader.Referer]

Related

Create WCF Service to be hosted differently

I have a WCF service which programmatically creates its endpoints rather than using a config file - I'm looking into this as our field engineers are prone to break XML easily and we may use different types of binding in different scenarios.
This works well in self-hosted environments (console app, windows app) and as a Windows Service.
Can I do this with a service in IIS or do I have to provide a .SVC file for each endpoint ?
Also will the endpoint address from the client end have to include the .SVC extension ?
This is not a service intended to be used by third parties, only by our client components. We may expose parts of our API later but not initially.
If you're using .NET Framework 4.0 (and later), you can use the ASP.NET routing integration to define a service using a custom ServiceHostFactory implementation. A few things you'll need:
In web.config, set the attribute aspNetCompatibilityEnabled on the <system.serviceModel / serviceHostingEnvironment> element to true
Add a global.asax / global.asax.cs file, and in the Application_Start add a new ServiceRoute to the ASP.NET RouteTable.Routes collection. The service route requres you to define a new service host factory, where you can define your endpoints programmatically.
With that you'll be able to have endpoints without the ".svc" in their addresses. You can also use the service host factory without using routes, by creating a .svc file for each service (not endpoint), and using the Factory attribute in the <%# ServiceHost directive.
For more information about service host factories, check the post at http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/14/wcf-extensibility-servicehostfactory.aspx.

wsHttpBinding on the wcf service and web reference on the client don't work

I am using wsHttpBinding with a WCF service.
I've added a web reference and I've got the web proxy (it is based on SoapHttpClientProtocol).
Also I've tried to build a proxy using wsdl.exe and the actual wsdl generated by the wcf service (http://zzzz/zz.svc?wsdl).
When the client calls the service, I get the following error:
The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://tempuri.org/Service1/Operation1'.
Why doesn't the client (the web proxy) work with my WCF service?
What steps should I take to make them work?
I am running .NET FW 3.5 and ASP.NET 2.0.
You cannot consume service exposed on wsHttpBinding with default configuration by old ASMX proxy. You must either use add service reference / svcutil or change your binding to basicHttpBinding. Default configuration of wsHttpBinding uses advanced security and ASMX doesn't support it.

WCF service with HttpContext

I had a web service which I converted to wcf service with the same asmx extension. I have basicHttpbinding since my service talks to various clients like java, perl etc.
I had a validation which had HttpContext.Current in it. But I know this will not work in wcf service. I am trying to use RequestContext or OperationContext but am not able to do so. I tried to use
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
but did not help. I am calling my service from soapUI for testing.
Ok, So I found the solution. There are quite some ways to get the HttpContext.Current context. Either we can use OperationContext or we can use the AspNetCompatibilityRequirements mode set to Allowed and aspNetCompatibilityEnabled set to true in web.config.
For my case where I had converted the asmx service to wcf service, I also had to modify the HttpHandler handler to remove and add asmx path to System.ServiceModel.Activation.HttpHandler.
You would better to use the OperationContext while using WCF services.
As you will always get the HttpContext.Current.Items is always Null which runs only while ASP.NET.
So add the following code:-
OperationContext.Current.Extensions.Add(extension);

Reading a cookie from a WCF RESTful webservice

Writing a suite of IIS hosted WCF webservices (both GET and POST), and I need to be able to read a cookie for an authentication token so I know the user has been auth'd previously.
Will HttpContext.Current.Cookies give me what I need or is there something cleaner and more appropriate for a WCF web service with WebGet and WebInvoke attributes?
string cookieHeader = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie];
works for me

Invoking WCF service method through a browser

I've a WCF service which uses basic http binding.
How do I invoke its operations/methods through a browser?
You would need to add WebGetAttribute to your method like following sample
[OperationContract]
[WebGet(UriTemplate = "/placesList/{userId}",
ResponseFormat = WebMessageFormat.Xml)]
List<Places> GetAllPlacesForUser(String userId)
{
string xml = "";
// build xml here
return xml;
}
Now in the browser, you could invoke the method like this
http://localhost:8085/GeoPlacesDataService/placesList/10
where 10 is the userId parameter.
Note: In order to add WebGetAttribute you have to reference System.ServiceModel.Web namespace which is found in a separate assembly
I would recommend setting up multiple endpoints for the Service. Add an endpoint using webHttpBinding to get an XML version of the service. If this is done correctly the response you will get from the service is identical to the basicHttpBinding endpoint, but without the SOAP overhead.
Other than that, you can't call a SOAP web service directly from the browser because it requires a form post. You could use a tool to test it using SOAP though, I recommend Soap UI. Its written in Java but I try not to hold that against it. :)
After adding the above code, the endpoint property has to be modified in web.config, binding="webHttpBinding" and behaviorConfiguration="webHttp".