WCF Service Endpoints not reachable from local - c#

I am new to WCF development and I am trying to create a WCF service hosted in a console app.
I have already created the WCF service and tested it by running it on IIS Express. Doing so, the WCF service will be accessible from http://localhost:5576/MyFirstService.svc. Within the service, I have defined a GET endpoint /test/<param> just to test if it works. Upon visiting the url with Postman http://localhost:5576/MyFirstService.svc/test/123, it will echo back 123.
My console app that hosts the WCF on the other hand is super simple. I followed the tutorial (http://www.topwcftutorials.net/2014/05/wcf-self-hosting-console-application.html). The relevant code is below:
Uri httpBaseAddress = new Uri("http://localhost:4321/StudentService");
//Instantiate ServiceHost
studentServiceHost = new ServiceHost(typeof(StudentService.StudentService), httpBaseAddress);
//Add Endpoint to Host
studentServiceHost.AddServiceEndpoint(typeof(StudentService.IStudentService), new WSHttpBinding(), "");
//Metadata Exchange
ServiceMetadataBehavior serviceBehavior = new ServiceMetadataBehavior();
serviceBehavior.HttpGetEnabled = true;
studentServiceHost.Description.Behaviors.Add(serviceBehavior);
//Open
studentServiceHost.Open();
Console.WriteLine("Service is live now at : {0}", httpBaseAddress);
Console.ReadKey();
As I launched the console app and visited http://localhost:4321/StudentService, I am greeted with the standard page talking about wsdl. However, if I tried to visit http://localhost:4321/StudentService/test/123, I get a 400 bad request error.
Am I doing things right? What is the path that I should be using to get to my endpoints? I tried many variations of the URL and it just does not seem to work.

Your first service, http://localhost:5576/MyFirstService.svc, was running within the context of IIS (yes even though it's express) so that is what allows for the URL (REST style) routing like you were seeing in your "test/123" example.
But the code example, and posted reference link, is actually a self-hosted service from a console application which doesn't utilize IIS or WAS (Windows Activation Service) so routing won't be available.
Don't get me wrong, your StudentService will still work just fine if called via SOAP, just not from a REST perspective which is what Postman is used for.
There are free tools out there like SoapUI that work just like Postman to test your WCF services.

Related

How do I configure a single ASP .NET application to be hosted on multiple domains?

I have a single website that makes calls to multiple web-services, and the website is hosted in different environments, e.g:
https://production.domain.com
https://uat.domain.com
https://dev.domain.com
Each website calls out to webservices hosted in the same environment:
https://production.domain.com/rest/
https://uat.domain.com/rest/
https://dev.domain.com/rest/
How do I define my webservice URLs to be relative in the context of where the application is hosted? Do I require any IIS configuration to achieve this?
The result would be:
https://production.domain.com => https://production.domain.com/rest
Having multiple combinations of URLs in my web.config and IF statements in my code is last thing I want to consider doing.
If there's always a 1-to-1 relationship between the URL of the web service being called, and the URL of the request to the web application that's calling the web service then you should be able to compose the URL for the web service with relative ease. If you want a fully qualified URL, then you can start with the Request.Url for the incoming request to the website and for example:
var uriBuilder = new UriBuilder(Request.Url);
uriBuilder.Path = "/rest";
var uriForRestService = uriBuilder.ToString();
Using an instance of UriBuilder allows you to preserve the protocol, host and also any custom port (e.g. if you're working with Visual Studio/IIS Express and thus have a test.domain.local:4321 flavour of URL) although you could go down the route of just grabbing Request.Url.Authority and constructing the rest of the URL yourself if you have a need to.

How do I add WorkflowControllEndpoint with HttpBinding to all Workflow services hosted on IIS with Appfabric

By default AppFabric adds WorkflowControllEndpoit with NetNamedPipeBinding.
In my environment I need to manage workflows from another server which means that I cannot use net.pipe.
How do I add a WorkflowControllEndpoint on HttpBinding?
Please note that I allow users to dynamicly add workflows so I'm looking for a way to add endpoint to all workflows hosted by AppFabric. tag in web.config is not good for me.
Attempt 1:
Using behaviour to add endpoint. I've had problems adding WorkflowControllEndpoint. I've add following to behavior
var host = (WorkflowServiceHost)serviceHostBase;
host.AddServiceEndpoint(new WorkflowControlEndpoint(new
WSHttpBinding(), new EndpointAddress(host.BaseAddresses[0] +
"/Control")));
that compiles and runs but when I make request to this endpoint I'm getting
Content Type application/soap+xml; charset=utf-8 was not supported by service http://localhost/WorkflowServices/xx.xamlx/Control. The client and service bindings may be mismatched.
I guess that's because endpoint wasn't added and it goes to a default endpoint which doesn't accept Soap
Attempt 2
Disabling net.pipe - That forces AppFabric to bind to WSHttpBinding for WorkflowControllEndpoint but then I get wornings in Persistence window like
workflow persistence is not fully functional because the net.pipe
What functionality do I loose ?

Allow user to specify endpoint

I have created a desktop application in WPF that I wish to supply to clients as a .exe file.
Currently the application has a web service referenced to it where the web service would be sitting on the clients web server.
There is a high possibility that the URL of the web service could change depending on the clients therefore is it possible to add an option for the user to add the service reference themselves once they know the web service URL?
In the app.config is where the endpoint address is set, so if when the application fired up, it presented the user with a text box to enter the url, then on button click the application updates the service reference. Is this possible?
I have come across lots of different articles however was not sure if it was possible without have to recompile the code?
Assuming it's a WCF service, if it's called Service1 you can set its address like this:
Service1Client wcfServiceClient = new Service1Client();
wcfServiceClient.Endpoint.Address = new System.ServiceModel.EndpointAddress("your uri here");
//now you will invoke the service in the address you defined
an ASMX service (still called Service1 in this example for consistency) can be setup like this:
Service1 asmxService = new Service1();
asmxService.Url = "your uri here";

Programmatically connect Silverlight to WCF

I have inherited a Silverlight application that consumes a WCF service, and is hosted in an ASP.NET web form. The application needs to run over HTTP and HTTPS, and will be installed on a customer's own server. The client code was originally generated using the Add Service Reference pointing to the locally-hosted service, so my ServicesReferences.ClientConfig obviously contains hard-coded references to localhost - not much use when deploying to another server, so obviously I need to be able to programmatically set the endpoint address that the client uses.
My code is currently:
var binding = new BasicHttpBinding
{
MaxBufferSize = 2147483647,
MaxReceivedMessageSize = 2147483647,
};
binding.Security.Mode = HtmlPage.Document.DocumentUri.Scheme.StartsWith("https")
? BasicHttpSecurityMode.Transport
: BasicHttpSecurityMode.None;
var documentUri = HtmlPage.Document.DocumentUri;
var builder = new UriBuilder(
documentUri.Scheme,
documentUri.Host,
documentUri.Port,
documentUri.LocalPath.Replace("hostpage.aspx", "MyService.svc"));
var client = new CustomerDetailServicesClient(binding, new EndpointAddress(builder.Uri));
client.ChannelFactory.Faulted += OnChannelFactoryFaulted;
client.DoSomething();
and while this works OK when I use HTTP, attempts to access via HTTPS fail with 404s for each call to the WCF service. Using Fiddler, I can see that it is only the URI scheme that is changing, and if I enter the HTTPS address of the service, I get the expected metadata page.
Is there something obvious that I am missing?
sigh slap me with a wet herring. The HTTPS bindings for the web service had been commented out in web.config (since not all our customers can/want to run HTTPS on their servers, and having WCF bindings for HTTPS when IIS is not configured for HTTPS breaks WCF in lots of noisy ways).
It's amazing what fresh perspective and clarity a good night's sleep can bring to a problem.

I am trying to consume a PHP SOAP service from C# and create a class wrapper in VS 2010

I've been tasked with creating a class wrapper for a SOAP service, the idea is that you'll be able to treat it as a regular class. The main reason for this is that the WDSL for the SOAP service contains only one method and it's got 5 parameters and it's only kind of OO so you'd have to know all the method calls really well and it's a bit hard to remember them all.
OK, so I've tried adding a web reference, now web references can now be added as service references in VS 2010. You click add service reference advanced etc and it puts in a service reference. Great. Unfortunately if I try and access this from a class I can't.
I can build a console app and put code in the main procedure and access the method of the SOAP service fine but when I add a reference to a class library the intellisense won't allow me to select anything. I'd instantiate an instance like so:
SOAPService.webServiceService ws = new SOAPService.webserviceService();
ws.
and then the intellisense refuses to kick in. If I do the same in a web project or a console app then I can access it fine. I've added the namespace I've done all kinds of things. Also, I can add a web reference and get a DISCO file whenever I create a web project.
OK, also while I'm on the subject I also need to pass credentials to the web service in PHP.
The problem is that in the past I'd create some .net system credentials and add these and it would usually pass through if I was connecting to another .net service.
How should I be sending them to a PHP web service? I always get either invalid username/password combo errors or envelope malformatted error types
Thanks
Mr. B
So the intellisense is not working, but if you add the method in and try to use it does it work, or produce an error?
With regard to diagnosing authentication issues try using fiddler to view the SOAP messages that are being sent, and to view the reply. Do you have some other software that connects and authenticates to that service? Use fiddler to look at the SOAP messages and compare them to see if the header is different etc.
I'd normally do it like this,
using (Service service = new Service())
{
service.ClientCredentials.Windows.ClientCredential.Domain = "domain";
service.ClientCredentials.Windows.ClientCredential.Password = "password";
service.ClientCredentials.Windows.ClientCredential.UserName = "username";
}
Also with regard to the service working or not in general use fiddler if you have any problems, you can see the SOAP messages and it often gives you a clearer message.
I know in IIS you can turn on failed request handling that also gives you an insight from what is going on at the server end, perhaps you have some form of logging too for your php service?

Categories

Resources