MetadataExchangeClient using Web Proxy - c#

I am trying to connect to a URI pointing to a WSDL file which describes a WCF service by using the MetadataExchangeClient class.
var mexClient = new MetadataExchangeClient(uri, MetadataExchangeClientMode.HttpGet);
var metaDocs = mexClient.GetMetadata();
The problem is that I cannot access this uri directly and need to go through a HTTP proxy server.
The proxy server URL can change at runtime so I cannot simply configure it through the app.config file.
Where can I specify the proxy server information in the MetadataExchangeClient class?
Anyone got an idea? WCF experts?

You need to specify the proxy in the app.config like this:
<system.net>
<defaultProxy enabled="true">
<proxy bypassonlocal="true"
proxyaddress="http://proxy.domain.org:8888/" />
</defaultProxy>
</system.net>

You can override the GetChannelFactory and provide an implementation that can create a suitable endpoint i.e. a BasicHtppBinding with the proxy details added.
See here for a clue to how programmatically set Binding.
How can I set an HTTP Proxy (WebProxy) on a WCF client-side Service proxy?
See here for starting point on creating the Channel Factory (see the 3 comments at the end of the post)
http://msdn.itags.org/visual-studio/83755/
This shows how to use MetadataExchangeClient with a Custom Binding:
http://wikiencyclopedia.net/WCF/3.5.30729.1/untmp/Orcas/SP/ndp/cdf/src/WCF/infocard/Service/managed/Microsoft/InfoCards/InfoCardMetadataExchangeClient.cs/2/InfoCardMetadataExchangeClient.cs
Here's the .NET Framework Source to MetadataExchangeClient so you can get a better understanding of what it is doing.
http://reflector.webtropy.com/default.aspx/WCF/WCF/3#5#30729#1/untmp/Orcas/SP/ndp/cdf/src/WCF/ServiceModel/System/ServiceModel/Description/MetadataExchangeClient#cs/1/MetadataExchangeClient#cs

Related

Programmatically changing defaultproxy instead of using app.config

I'm creating a desktop application in WPF. This application uses webclient instances to communicate with an API to collect data from.
In this desktop application I want to create a checkbox which should allow the user to ignore the internet options proxy or to use the default auto detect options.
At this moment I added this defaultproxy setting to my app.config to stop my application from trying to communicate through the proxy and instead ignore it.
<system.net>
<defaultProxy enabled="false" useDefaultCredentials="false">
<proxy/>
<bypasslist/>
<module/>
</defaultProxy>
</system.net>
When I don't have this code in my app.config, my application will try to use the default internet options proxy.
So in order to have this switchable by a checkbox in a settings menu I will have to change these settings programatically.
I am aware of the fact that when I set the default proxy to a new webproxy that the application will ignore the internetoptions proxy.
WebRequest.DefaultWebProxy = new WebProxy();
But I can't for the life of me figure out how I can set this back to the automatically detecting of proxy use, like before I inserted above defaultproxy settings in the app.config.
I am testing this by using a faulty proxy. This means that if I send an api request, the proxy can't be found and I receive a webexception. When I ignore the proxy with the app.config code, the request uses my normal internet connection, and returns API data.
It would really help me out if anyone could tell me how I can programatically set my application to ignore the proxy or, most importantly, to use the default auto detection settings.
If you want to set the proxy back to the default proxy, you can use this static method
WebRequest.GetSystemWebProxy();
see here https://msdn.microsoft.com/de-de/library/system.net.webrequest.getsystemwebproxy(v=vs.110).aspx

How to disable Expect:100-Continue when using WCF in Windows Store App

I need to get rid of the Expect: 100-Continue header in HTTP message, when communicating with WebService using WCF in Windows Store App.
I have found a lot of solutions, but none of them is possible in Windows 8:
ServicePoint.Expect100Continue = false; doesn't exist in Store App any more (No SericePoint or ServicePointManager class),
I cannot change configuration in web.config file, because it doesn't exist in Store App,
It is possible to change the flag in HttpClient, but I cannot access it, when using WCF,
I tried to manipulate with message headers using IClientMessageInspector, but the default HTTP headers are being added later, in higher layers, so my changes will be ovverriden.
Does anyone have any other ideas?
There are 2 ways to deal with this.
You can turn set expect100Continue="false" in you app.config or web.config, but this will be global. This could be an issue if some external services prefer to use the header expect100Continue. Here's how:
<system.net>
<settings>
<servicePointManager expect100Continue="false"/>
</settings>
</system.net>
Or you can do it in code for a specific endpoint as follows:
System.Net.ServicePoint servicePoint =
System.Net.ServicePointManager.FindServicePoint(myWcfService.Endpoint.Address.Uri);
servicePoint.Expect100Continue = false;
// now execute some service operation

Getting Error "This collection already contains an address with scheme http" with WCF on local machine

I'm trying out WCF for the first time and getting the following error when I try to instantiate the host:
This collection already contains an address with scheme http...
I have found a lot of other references to this and tried some of the solution to no avail. One fairly common thread that does not apply to me is that the problem is on a web server of some sort. I'm just running everything from my local machine.
One interesting symptom I found is that I'm developing a c# Forms app. Originally my top level form object inherited my service interface instead of a separate Service class. When I implement this way, there is no error on the host side but I have been having trouble on the client side.
Based on this solution:
How to solve "The ChannelDispatcher is unable to open its IChannelListener" error?
...I decided to separate the service host into a separate object. That's when I start seeing the problem.
The ServiceContract is simple enough:
[ServiceContract]
public interface ISSAService
{
[OperationContract]
void CreateSpaMonitor();
}
I instantiate the service like this:
Uri baseAddr = new Uri("http://localhost:8000/SSAService");
ServiceHost localHost = new ServiceHost(typeof(SSAService), baseAddr);
Where SSAService is the implementation of the Service interface.
If I change the second line to the following (and implement the interface...) the error goes away:
Uri baseAddr = new Uri("http://localhost:8000/SSAService");
ServiceHost localHost = new ServiceHost(typeof(SSAManager), baseAddr);
Where SSAManager is my top level Forms class...
Then I run into a client side problem which is where I started....
I have tried changing the port number and that doesn't seem to affect anything.
I'm new to WCF so maybe I'm missing something obvious.
Thanks.
I was getting this error:
This collection already contains an address with scheme https. There can be at most one address per scheme in this collection. If your service is being hosted in IIS you can fix the problem by setting 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' to true or specifying 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'.
Parameter name: item
I resolved it by doing the following to my web.config. Perhaps something changed in the .NET Framework 4 which is requiring this line, since I didn't need it before:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<!-- Rest of the system.serviceModel content omitted for brevity--->
<system.serviceModel>
This can also occur if you have multiple bindings on the same IIS site with different domain names/ports. I resolved the issue by removing the extra named binding.
One of the solution I found previously was to add something like this:
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://localhost:8000"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
And then specifying the endpoint address absolutely. This didn't seem to have an effect but I was still using baseAddr in the constructor as shown above.
The solution for me was to remove baseAddr from the constructor.

Programmatically add decompression in WCF Requests

I would like to turn on compression in my SOAP WCF requests. The solution described here works perfectly. It involves 2 parts:
The implementation of a IWebRequestCreate inherited class which turns on compression. This is not a problem.
Specifying in the app.config file that the above mentioned class should be used. This is done with this XML in the app.config file:
:
<configuration>
<system.net>
<webRequestModules>
<remove prefix="http:"/>
<add prefix="http:"
type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
</webRequestModules>
</system.net>
</configuration>
However, this is a problem, as this C# project is a DLL (an SSIS data flow component), and it cannot 'see' the app.config file (nor do we want to modify the calling .exe's config file).
The question here describes a workaround for this problem (in short, creating BasicHttpBinding and EndpointAddress objects and sending them to the client's c'tor). I have successfully used this to some extent to allow for proxy's, alter timeouts, change the service's URL, etc.
However, I cannot figure out the mechanism to replace the above XML in a similar manner.

IMetadataExchange endpoint purpose

What is the purpose of IMetadataExchange endpoint. Some places i found that if i dont define this endpoint, adding service reference will not work OR creating proxy using svcutil wont work. But both of this working without having IMetadataExchange defined.
If we have other endpoint with httpGetEnabled = true, we are able to create proxy from client.
Also, some article says that we should delete IMetadataExchange before moving code to production and it should development period only so that other client cant see metadata. Doesnt this stop the behaviour of service having self describing itself?
And if I have defined this IMetadataExchange endpoint, how can i see that on browser. Address whoch i have provided for this endpoint is not pulling any metadata in browser.
Service metadata can be served two ways:
Regular WSDL served over HTTP/HTTPS, which is what that http[s]GetEnabled=true enables.
WS-MetadataExchange (MEX) which uses SOAP (and not just a plain GET request over HTTP) and supports a few more advanced scenarios (in theory, at least). That's what the IMetadataExchange endpoint enables.

Categories

Resources