All,
I have this SOAP web service, the way I do it is generated a WSDL proxy class based on the WSDL file (using the wsdl tool from Microsoft). Now, I want to also have the ability to log the ENTIRE XML packets, both outbound and inbound. I know that there's a class called SOAPExtension to overwrite. But for ppl like me using the WSDL proxy class, how to we even hook into the SOAPExtension class since that proxy class is supposed to be make the call...? Can anyone help?
Regards,
Kyle
If you use WSE2, you can put this in your web.config, in <microsoft.web.services2> section:
<diagnostics>
<trace enabled="true" input="InputTrace.log" output="OutputTrace.log" />
</diagnostics>
You will see the incoming xml in "InputTrace.log" and outcoming in "OutputTrace.log", both files in the root directory of your app.
EDIT: There must be a simple way like this if you're not using WSE, but I'm not aware of, so anyone feel free to add your two cents...
Related
first of all this is not duplicate. I have a little bit different question.
Is it good practice to get rid of WCF's config in App.config file in the client (or clients in case of cross-platform project) and replace it with injected Proxy class (from different dll, shared for all clients)?
I'm just starting so my config file is not big, but here is an example:
App.config (WCF part):
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:8002/MyService"
binding="netTcpBinding"
contract="CallbackExample.Client.IMyService" />
</client>
</system.serviceModel>
I must have this code copy and pasted into every client I made. Working with Xamarin I can have many clients written in C# in single VS solution. So I though, why not just get rid of system.serviceModel section and do that:
MyServiceProxy.cs:
public class MyServiceProxy : ClientBase<IMyService>, IMyService
{
public MyServiceProxy()
: base(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8002/MyService"))
{
}
public int JustAMethod()
{
return Channel.JustAMethod();
}
}
This way, I will have my configuration in single place.
So, my question is: Is it considered as a good practice? Is there a better way? I'm not sure, cause WCF is all about flexibility and easy config through App.config flie.
If there is no need for additional configuration, I always go for pure code solutions.
Back in the day WCF was slightly more complex to configure, via app.conf. With the ServiceHost you can even configure a WCF service in pure code.
The same applies to a WCF client imo; if you don't have the need to configure it via a config file for your users: I'd say go for the pure code solution.
Here another discussion of the same topic. (kind of the same reasoning, the question remains; do you need the configuration flexibility).
One potential downside to doing everything in code is that you lose the flexibility to configure not just the endpoint, but also the binding, without recompiling and redeploying. The binding includes some important network-related attributes (timeouts, transport protection levels, authorization schemes, etc) that you may want to tweak depending on the environment in which some of your client programs can run.
Note that you don't necessarily have to have a separate *.exe.config file for every client application. You can have a common .config file that each application can load explicitly. See ConfigurationManager.OpenMappedExeConfiguration
We've used the solution in this old topic ("WCF Service Reference generates its own contract interface, won't reuse mine"), but that only solves the problem of reusing interfaces. What we would like to do, if possible, is to also retain the use of config files to setup and configure various options on WCF client side using all the bells and whistles of <system.serviceModel> node.
The approach that was given forces us to do all that in code, and that already proved to be a problem at one point (we had to change a binding configuration parameter which forced us to go through an entire corporate change request approval process to alter two lines in the code base, which is a huge hassle compared to a request to change config file).
Is there a solution that combines these two worlds?
Lets say you have IService as your service contract and it is shared between the client and the server.
Then in client code you would have something like this:
ChannelFactory<IService> factory = new ChannelFactory<IService>("ServiceClient");
var channel = factory.CreateChannel();
var result = channel.GetData(1);
In Client app.cofnig you would have a section that looks like this:
<system.serviceModel>
<client>
<endpoint name="ServiceClient" address="http://localhost:51377/service.svc" binding="basicHttpBinding"
contract="Common.IService"/>
</client>
</system.serviceModel>
Briefly explained ChannelFactory creates Channel to access IService service using ServiceClient endpoint configuration in app.config.
You can expand serviceModel configuration as you wish. Just add additional code to properly close channel once operation is complete.
What exactly is it that you're trying to achieve? Seems like you're trying to reuse contracts, but have SVCUTIL/VS generate the ClientBase<T>-derived class and modify the .config file?
If so, I don't think that's a supported scenario, really. Honestly, if you need to reuse your service contract interfaces, you might as well implement the ClientBase<T>-based proxy class by hand. It's only a little bit of additional work, and will make your life easier in the long run.
There isn't a supported option in SVCUTIL/VS to only import the binding configuration rather than the entire thing, though, so you'd likely need to write your config file by hand as well (or copy it from a manual run of SVCUTIL).
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.
it looks like I am not able to succesfully move my WCF proxy code into a separate DLL (as opposed to an EXE as I can see in all the examples I have run into).
The reason I am trying to do this is that I would like my proxy code to be invoked by different clients (possibly unmanaged code), which might not know anything about WCF but just need to access to the services (through a Facade exposed by the proxy maybe?).
Whenever I move the following code that creates a new proxy to a different VS project within the same solution, I get the dreaded "Could not find default endpoint element that references contract 'localhost.IRemoteCommandService' in the ServiceModel client configuration section" exception.
localhost.RemoteCommandServiceClient proxy =
new localhost.RemoteCommandServiceClient();
The same code works smoothly whenever used within a Main method in the same project where the proxy code is (auto-generated from Visual Studio).
Any idea? I hope that the client code of my proxy does not need to have the service model XML configuration as the proxy, because that would defeat the purpose I am moving the WCF proxy code into a DLL in the first place.
Thanks,
Stefano
The endpoints are indeed normally specified in the configuration file. You must look at the serviceModel data in the config file, and copy it into your calling app.config - or you need to use the more verbose way of creating the proxies in your code (i.e. specifying the address, binding, configuration etc through code to the constructors).
If you don't want to have to endpoint configuration on the client, you'll have to embed it into your proxy dll by specifying everything in code.
Another option would be to use a dynamic proxy, like this one, which would allow you to not have the serviceModel in your client apps.
I have numerous Web Services in my project that share types.
For simplicity I will demonstrate with two Web Services.
WebService1 at http://MyServer/WebService.asmx
webService2 at http://MyServer/WebService.asmx
When I generate the proxy for these two services I use:
wsdl /sharetypes http://MyServer/WebService1.asmx http://MyServer/WebService2.asmx
/appsettingurlkey:WebServiceUrl /namespace:MyNamespace /out:MyProxy.cs
The problem is that the appsettingurlkey is the same for each Web Service
in the proxy file. I want to be able to specify multiple
appsettingurlkey parameters. How is this accomplished? I figure
since the /sharetypes parameter became available, there should be a
solution for specifying the appsettingurlkey specifically for each
Web Service identified.
If this is not possible with the wsdl.exe, what would you propose I do? I would rather not update the generated code that wsdl.exe outputs and I don't want to go through my whole application passing in the Url to each instance of the Web Services.
The proxy classes generated are partial classes, so my solution would be to add your own constructor in a different (non-generated) code file, which explicitly reads a different setting for each proxy.
To suplement Elijah's own answer, here's the email answer I gave him.
I had to blog it because the XML didn't paste well into this text box: http://www.rickdoes.net/blog/archive/2008/09/29/wsdl-shared-types-and-configuration.aspx
Ahh, instead of creating another partial class with an overloaded constructor passing in the Url, the following additional parameters to the wsdl.exe will solve my problem...
wsdl /sharetypes http://MyServer/WebService1.asmx http://MyServer/WebService2.asmx /appsettingurlkey:WebServiceUrl /namespace:MyNamespace /out:MyProxy.cs /appsettingurlkey:BaseSoapUrl /appsettingbaseurl:http://MyServer/
If the web.config has a BaseSoapUrl appSetting, then it will use that to replace the http://MyServer/ sub string from the MyProxy.cs. If the appSetting is not present, then it will just use the path provided in the wsdl.exe (example: {BaseSoapUrl}/WebService1.asmx when using the appSetting or http://MyServer/WebService1.asmx when not using the appSetting).
A thanks goes out to Rick Kierner for pointing me in the right direction.