WCF 4.5 - multiple web services - c#

I would like to consume 2 WCF web services located on 2 different hosts (the first accessible in HTTPS and the second one in HTTP). Both present the same methods, but the first one is on the production server, while the second one is on a test server.
When I add the references in my Visual Studio 2012 (express), I get 2 namespaces ; for now, the only way I found to consume these services is to use the interfaces and classes generated in these namespaces.
I would like to use only one web service, depending of a configuration item, indicating if I'm in debug or release mode.
How can I do that by code ?
Here is my config file :
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ILotWebContract">
<security mode="Transport" />
</binding>
<binding name="BasicHttpBinding_ILotWebContract1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://xxx/Services/WebService/LotWebService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ILotWebContract"
contract="eMol.ILotWebContract" name="BasicHttpBinding_ILotWebContract" />
<endpoint address="http://yyy/Services/WebService/LotWebService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ILotWebContract1"
contract="eMolTest.ILotWebContract" name="BasicHttpBinding_ILotWebContract1" />
</client>
</system.serviceModel>
I tried to change the endpoint's address :
eMolTest.LotWebContractClient client = new eMolTest.LotWebContractClient();
client.Endpoint.Address = new System.ServiceModel.EndpointAddress("https://xxx/Services/WebService/LotWebService.svc");
client.Endpoint.Binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.Transport);
but the exception generated while running the client indicate that the links between client and service probably do not correspond.
I also tried to indicate the name of the endpoint when I call the proxy's contructor :
eMolTest.LotWebContractClient client = new eMolTest.LotWebContractClient("BasicHttpBinding_ILotWebContract");
but again it does not work because of the namespaces which are different (the contract's name contains the namespace's name, and can therefore not be found in the endpoint as defined in the config file).
So, if someone has a good idea ...
Thanks !
Chris

If you have two services with the exact same contract, you should share it's contract as a contract assembly between all three parties and use a ChannelFactory class to create the proxy yourself. That way you don't have two service references that although they represent the same contract are incompatible from a compiler perspective.

Related

Hosting WCFService Library on IIS 10 with SSL encryption

I am trying to host a WCF Service Library on IIS 10, with a self signed SSL.
To Obtain Minimum Complete Verifiable Example, Open Visual studio 2017
New>Project>C#>Web>WCFLibrary With this you will get a simple code that has one operation contract which takes an integer and returns a string.
Now I am trying to host this on IIS with Self Signed SSL (Mine has more operation contract but this will do).
What I have tried so far.
Now the next part is hosting it on IIS, so I created the SVC file
My SVC file contains ->
<%# ServiceHost Language = "C#" Debug = "true" Service = "WcfServiceLibrary2.Service1" %>
Then all the tutorials that I can find edit Web.Config, which is unavailable in Visual Studio 2017, so I tried two things
1. Created a Web.Config file and added the configurations
2. Published the website and then obtained Web.Config which did not require any changes
Then I went on to IIS (as administrator) and added a new website
Then while trying to browse, to see the message that IIS service is hosted I got this error "Cannot read configuration file" To Solve this I followed success.trendmicro.com/…
Now that error is gone but now I am getting
To solve this I Followed
IIS - 401.3 - Unauthorized But this lead to the browser letting me browse the directories rather than giving the message that a Service has been created.
Any Idea what I am missing here?
Definitely I am missing something major here as I have failed to host it on HTTP itself, All the tutorials I find online have a file Web.Config and not App.config, I am looking for an example (preferably with Images) that demonstrate it just with this small example.
I know this doesn't follow all SO guidelines on asking questions, but I have failed to articulate it into a question that does.
Edit
As per LexLi's advice that it may already be hosted, I went and tried to consume it using svcutil which gave me the error
WS-Metadata Exchange Error
URI: http://localhost/Service1.svc
Metadata contains a reference that cannot be resolved: 'http://localhost/Service1.svc'.
The remote server returned an unexpected response: (405) Method Not Allowed.
The remote server returned an error: (405) Method Not Allowed.
HTTP GET Error
URI: http://localhost/Service1.svc
There was an error downloading 'http://localhost/Service1.svc'.
The request failed with HTTP status 404: Not Found.
The Url is correct because I obtained it by using the browse functionality from IIS.
First, please don’t set the IIS physic path to desktop, which will cause the permission problem. we could set the IIS site physical path to the folder under C partition.
Second, please read the following link, which mainly indicates that WCF service library project could not published directly to IIS since its Appconfig could not be recognized by IIS unless additional Webconfig is added manually in the root directory of the web site.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/deploying-a-wcf-library-project
Generally speaking, we use the WCF service project template which contains an auto-generated Webconfig file instead of WCF service library project template, since it is generally used as a class library.
By default, the service is hosted with BasicHttpBinding, it depends on the following tag.
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
</protocolMapping>
The service could also be configured manually by the following ways. These two ways configuration file is equivalent.
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="mybehavior">
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="mybinding">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
It is unnecessary to assign the service endpoing address in the webconfig. It should be completed in the IIS site binding module.
WCF System.ServiceModel.EndpointNotFoundException
At last, we could host the service over https by adding an additional service endpoint, refer to the following configuration(simplified configuration).
<protocolMapping>
<add binding="basicHttpBinding" scheme="http"/>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
then add the https protocol in IIS site binding module.
Configuring Web.config to publish WCF Service
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl
Feel free to let me know if there is anything I can help with.
First Credit where credit is due, many of the issues I was pointed in the right direction by multiple SO users to name a few would be: Mikael bolinder, Abraham Qian, Lex Li, the wonderful people in the C# chat room and a co-worker of mine(Doesn't have an account on SO as of writing this answer), In this answer I plan to cover everything you might need to host a WCF Library in IIS Server using HTTPS security.
Tools I used:
Visual Studio 2017 professional
IIS 10 (Comes with windows 10 but has to be activated in windows features ) (See below)
First:
Make sure you have all the components you will need from visual studio installed.
Windows -> .Net Desktop Development
Windows -> Universal Windows platfor development
Web & Cloud -> ASP.NET and web development
In this list and among other list that will come, some extra components may be included, the reason for that is I installed them and couldn't verify one way or the another if they are absolutely necessary.
Now, let's add the windows features necessary. Control Panel -> Programs -> Turn Windows features on or off
Make sure to go into WCF Services and check HTTP Activation, don't be fooled by the square block (One of my mistakes)
Now let's get to creating the Service. Open Visual Studio File -> New -> Project -> Visual C# -> Web -> WCF -> WCF Service Library This generates the MCVE that you are trying to host
Now you have to link it with a website in order to generate the Web.Config file along with the SVC file, to do that, On Solutions Explorer, right click on your solution, Add-> New Website.
Now in the web.config file add
<system.serviceModel>
<services>
<service name="WcfServiceLibrary4.Service1"> <!-- Change the library name as per your need -->
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="WcfServiceLibrary4.IService1"/> <!-- Change the library name as per your need -->
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Next add reference to service on the website
Discover services and add the service you have created. Now Build your solution and publish it. **Careful Don't publish the solution in a user Directory like Desktop or documents or else ACL permissions will give you a headache, rather publish it directly in a directory in Drive.
Now Hosting time
First lets open IIS (Always as admin) and create a new certificate.
On the server go to the IIS part and Select Server Certificates, then click create new certificate on the right end.
Now create a new website from the left menu
Make sure to switch to https and select your certificate here, Now to verify that your service is created you will need to browse your websites svc file created, sadly at this point you will get an error saying Server Error in '/' Application.
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https]. I was unable to find the cause of the error, but I was able to find a bypass of it,
Steps to bypass this error -> Select you website from the menu on the left, on the menu at the right click bindings and also add an HTTP binding, with a different port.
After this you will be able to browse the HTTPS version of your svc file.
Now if you browse the HTTPS link you get the message that the service is created
Now you can go Ahead and create an application that consumes this service.
What lies ahead
I will try to find a way to do this without adding an additional binding
The Second goal would be to achieve this without adding the extra website.
If and when I achieve these I will update, however these are not my priority right now and may not be added for quite a while, if anything didn't make sense, or you have any ideas of improvement comment below.
In short here are the steps :
Create Self-Signed Certificate
Add SSL Binding
Configure Virtual Directory for SSL
Configure WCF Service for HTTP Transport Security
This link is more in depth : https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl

How to connect to WSDL service using Binding Url in .Net

I have been provided a Web Service which i need to consume in my MVC application .
The user has provided
WSDL URL :
http://abc.xyz.nirp.com:50000/dir/wsdl?p=ic/310c503c873138a884ddd3ee4a5738e6
Binding Url:
http://abc123.ad.xyx.com:50000/XISOAPAdapter/MessageServlet?senderParty=&senderService=BS_HARMONY_D&receiverParty=&receiverService=&interface=ABC_OS&interfaceNamespace=http%3A%2F%2Fabc.com%2Fhcm%2Fabc
I am able to add a service reference using the WSDL URL using SOAP credential but i also need to add these in the web configs and app configs which i am not able to understand where to put .
Pointers on how to use this Binding Url and put it in Web Config and App Config which be really helpful for me.
Check your web.config. After adding a service reference visual studio adds the endpoint in your web.config. You probably have a section like that:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="DefaultServiceEndpoint">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="ADDRESS_HERE"
binding="wsHttpBinding" bindingConfiguration="DefaultServiceEndpoint"
contract="ServiceReference1.SOME_CLASS" name="DefaultServiceEndpoint" />
</client>
</system.serviceModel>
You can change the address here.

Creating and Consuming a Webservice entirely within a DLL

Hope someone here can help me solve this !
I'm writing a custom plugin for Microsoft CRM, which on the creation or update of certain entities, carries out some tasks in the background on our Sharepoint instance, which can't be completed via CRM workflows as they don't have the functionality.
The problem is, that when creating the Service Reference, the defintion for the webservice, with the endpoint address, etc is stored in the DLL's .config file. When deploying the CRM Plugin, the .config file isn't available either when deploying it to disk, or to the database, and the plugin fails as soon as the I try to use the Webservice.
I've had a look at some documentation for BasicHttpBinding, but I'm not entirely sure how I would go about creating the Webservice programmatically, so that it is entirely contained within the DLL.
I'm not bothered about being able to amend the details without recompiling, as the code will be pretty much static anyway.
I've tried defining the Service Reference in the project, as "TestDws"
BasicHttpBinding SharepointWS = new BasicHttpBinding();
SharepointWS.Name = "SharepointWebservice";
EndpointAddress EndPoint = new EndpointAddress("http://hostname/_vti_bin/dws.asmx");
TestDws.DwsSoapClient temp = new TestDws.DwsSoapClient(SharepointWS, EndPoint);
However, the plugin just craps out at this point.
The original .config doesnt have much more in the way of configuration
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="DwsSoap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://hostname/_vti_bin/dws.asmx"
binding="basicHttpBinding" bindingConfiguration="DwsSoap"
contract="TempDws.DwsSoap" name="DwsSoap" />
</client>
</system.serviceModel>
</configuration>
I recreated the Service Reference from scratch, and used the same BasicHttpBinding method as above and it worked second time round... albeit now with a HTTP401 on the Sharepoint Webservice !

WCF: Cannot find endpoint reference

I am working on a SharePoint 2013 webpart and a label on the webpart needs to communicate with a SQL Server data table using WCF. I have created the WCF interface and main class, and have also invoked the service in my Visual webpart like this:
protected void Page_Load(object sender, EventArgs e)
{
WcfServiceReference1.Service1Client client = new WcfServiceReference1.Service1Client();
CustomerNameLbl.Text = client.GetCustomerName(ProjectIDDescLbl.Text);
}
Where WcfServiceReference1 is the added WCF service reference and a customer label text is being changed depending on the project number label. The project builds and deploys fine but when I add the webpart, I get this error: Could not find default endpoint element that references contract 'WcfServiceReference1.IService1' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
My app.config file is this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://as-sv-dev02:2345/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="WcfServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
And web.config file (for SharePoint) is this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://as-sv-dev02:2345/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="WcfServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
Can anyone guide me on how to resolve this? Am I going wrong somewhere?
After a lot of research, I found out that there was some problem with SharePoint which I don't really understand. Thankfully, in time, I chose not to go the SharePoint way and instead work with a simple .aspx page and that would resolve the issue. Just unhappy with Microsoft not offering as much support on such common issues.
I had the same problem and I found this link.
http://social.technet.microsoft.com/Forums/en-US/dea0763d-d6ea-4659-8ef0-8275514d066a/sp2010-consuming-web-service-in-visual-web-part?forum=sharepointdevelopmentprevious
I did it and worked fine. The problem is the deploy does not copy the service model configuration from the Visual Studio' app.config to the IIS's web.config.
I hope helps.
Best Regards.
Your client endpoint does not seem to have a default configuration (name="" or nameless). Try using:
WcfServiceReference1.Service1Client client = new WcfServiceReference1.Service1Client("BasicHttpBinding_IService1");

WCF Error - Could not find default endpoint element that references contract 'UserService.UserService'

Any ideas how to fix this?
UserService.UserServiceClient userServiceClient = new UserServiceClient();
userServiceClient.GetUsersCompleted += new EventHandler<GetUsersCompletedEventArgs>(userServiceClient_GetUsersCompleted);
userServiceClient.GetUsersAsync(searchString);
.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_UserService"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:52185/UserService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_UserService"
contract="UserService.UserService"
name="BasicHttpBinding_UserService" />
</client>
<behaviors>
<serviceBehaviors>
<behavior name="Shell.Silverlight.Web.Service3Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="Shell.Silverlight.Web.Service3Behavior"
name="Shell.Silverlight.Web.Service3">
<endpoint address=""
binding="basicHttpBinding"
contract="Shell.Silverlight.Web.Service3" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Could not find default endpoint element that references contract 'UserService.UserService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Resolved!
I didn't mention that this was a Silverlight application. I had the wcf reference in a DLL which had it's own "ServiceReferences.ClientConfig" file. I moved the contents of the DLL's ServiceReferences.ClientConfig to the main silverlight project and it worked.
I had a run in with the same problem. My application was also a Silverlight application and the service was being called from a class library with a custom UserControl that was being used in it.
The solution is simple. Copy the endpoint definitions from the config file (e.g. ServiceReferences.ClientConfig) of the class library to the config file of the silverlight application. I know you'd expect it to work without having to do this, but apparently someone in Redmond had a vacation that day.
You can also set these values programatically in the class library, this will avoid unnecessary movement of the config files across the library.
The example code for simple BasciHttpBinding is -
BasicHttpBinding basicHttpbinding = new BasicHttpBinding(BasicHttpSecurityMode.None);
basicHttpbinding.Name = "BasicHttpBinding_YourName";
basicHttpbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
basicHttpbinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endpointAddress = new EndpointAddress("http://<Your machine>/Service1/Service1.svc");
Service1Client proxyClient = new Service1Client(basicHttpbinding,endpointAddress);
Just in case anyone hits the same problem whilst using WPF (rather than WCF or Silverlight):
I had this error, when connecting to a Web Service. When my code was in the "main" WPF Application solution, no problem, it worked perfectly. But when I moved the code to the more sensible DAL-layer solution, it would throw the exception.
Could not find default endpoint element that references contract 'MyWebService.MyServiceSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
As has been stated by "Sprite" in this thread, you need to manually copy the tag.
For WPF apps, this means copying the tag from the app.config in my DAL solution to the app.config in the main WPF Application solution.
I ran into the same issue, for whatever reason Visual Studio did not update the web config when I first added the service. I found that updating the Service Reference also fixed this issue.
Steps:
Navigate to the Service Reference Folder
Expand it
Right Click and Select update Service Reference
Observe web Config be updated
Change the web.config of WCF service as "endpoint address="" binding="basicHttpBinding"..." (previously binding="wsHttpBinding")After build the app, in "ServiceReferences.ClientConfig" ""configuration> has the value. Then it will work fine.
Rename the output.config produced by svcutil.exe to app.config.
it worked for me.
Do you have an Interface that your "UserService" class implements.
Your endpoints should specify an interface for the contract attribute:
contract="UserService.IUserService"
Not sure if this is an issue.
Endpoint and binding both have the same name
Not sure if it's really a problem, but I see you have the same name for your binding configuration ().
I usually try to call my endpoints something like "UserServiceBasicHttp" or something similar (the "Binding" really doesn't have anything to do here), and I try to call my binding configurations something with "....Configuration", e.g. "UserServiceDefaultBinding", to avoid any potential name clashes.
Marc
Had to add the service in the calling App.config file to have it work. Make sure that you but it after all . This seemed to work for me.
This problem occures when you use your service via other application.If application has config file just add your service config information to this file.
In my situation there wasn't any config file so I use this technique and it worked fine.Just store url address in application,read it and using BasicHttpBinding() method send it to service application as parameter.This is simple demonstration how I did it:
Configuration config = new Configuration(dataRowSet[0]["ServiceUrl"].ToString());
var remoteAddress = new System.ServiceModel.EndpointAddress(config.Url);
SimpleService.PayPointSoapClient client =
new SimpleService.PayPointSoapClient(new System.ServiceModel.BasicHttpBinding(),
remoteAddress);
SimpleService.AccountcredResponse response = client.AccountCred(request);
For those who work with AX 2012 AIF services and try to call there C# or VB project inside AX (x++) and suffer from such errors of "could not find default endpoint"... or "no contract found" ...
go back to your visual studio (c#) project and add these lines before defining your service client, then deploy the project and restart AX client and retry:
Note, the example is for NetTcp adapter, you could easily use any other adapter instead according to your need.
Uri Address = new Uri("net.tcp://your-server:Port>/DynamicsAx/Services/your-port-name");
NetTcpBinding Binding = new NetTcpBinding();
EndpointAddress EndPointAddr = new EndpointAddress(Address);
SalesOrderServiceClient Client = new SalesOrderServiceClient(Binding, EndPointAddr);
In case if you are using WPF application using PRISM framework then configuration should exist in your start up project (i.e. in the project where your bootstrapper resides.)
In short just remove it from the class library and put into a start up project.

Categories

Resources