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.
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
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
I created a web method but when i go to the site and type for example http://mysite.com/services/Amounts/GetAmount it returns an error Internal Server Error 500. After investigating the issue in event logs etc,, it says GetAmount invalid method name. but i know the mame is fine
[WebMethod(EnableSession=true)]
public string GetAmount(Amounts amts)
{
//some logic here to add to the database.
}
What are the possible issues that I have to look into when this type of error shows?, I checked all the references and everything is named properly "GetAmount".
What are you trying to do here? You need to post more code and web.config. Which version of .NET you are using here? All this information may get you the better answer.
Firstly, your URL http://example.org/services/Amounts/GetAmount does not seems to be correct - there has to be .asmx somewhere unless you are using ASP.NET routing or some url rewriting.
Assuming that your routing/re-writing is indeed working correctly:
in general, if its a normal SOAP Web Service then enable HTTP get -
<webServices>
<protocols>
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
If you are trying create a service callable from script (ScriptService) then for asmx service, you need to mark the method as ScriptService and you may need to adjust web.config based on your .NET version. Also you need to enable HTTP GET - for example,
[ScriptMethod(UseHttpGet = true)]
public string GetAmount(Amounts amts)
You may also need to adjust Response Format whether you want JSON or XML.
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...
Background
I am developing an ASP.Net server side control that needs to talk to an ASMX web service. The server side control uses a WebClient object to talk to the web service, since it needs to be reused often in various application, and to make it easier on the developers, they are not required to create a service reference to the web service.
Implementation
During the use of the control, it is requires the sending of a serialised object to the web service. The object is serialised using the XmlSerializer and the resulting XML string is then compressed using the chilkat compression library. The web service call for the control looks as follows:
webClient.UploadStringAsync(new Uri(serviceHost + serviceMethod), "POST", sendData)
The content of sendData (string) is compressedResponse={CompressedData}.
The web service has a method defined as follows to receive the data and then decompress the string value using the chilkat library before de-serialising the object using the XmlSerializer.
public void SaveResponse(string compressedResponse)
The communication between the control and the service is working. Initially there were no settings or binding defined in the web.config for any of the above. After initial searching I did add
<httpRuntime maxRequestLength="20480"/>
to both the client and server web.config files. This has made no difference.
Problem
Compressed or uncompressed the data being posted to the web service in the sendData variable is to big for a normal POST request, and is corrupted. This is confirmed when checking the last few characters of the string before and after it being posted to the server in compressed format, and uncompressed, the Xml document is missing the last root tag when checking in the debugger. The string can't be decompressed and therefore the service call fails every time.
How do I increase the POST size for the WebClient request to ensure that the full string is received by the server?
I have looked at the various option on Google, but none are giving me a good enough sample of where to make the changes, or samples of what the changes need to look like. I am completely lost as to whether the change needs to be made on the server or the consuming website, and since there are no binding defined for this, how to create a binding in the web.config for an ASMX HTTP service call.
I believe you must be hitting ASP.NET max request length limit. That you can modify via config file such as:
<system.web>
<httpRuntime executionTimeout="240" maxRequestLength="20480" />
</system.web>
maxRequestLength value is in KB, so above setting would allow 20 MB. You can also apply the setting only to selected URLs using location tag e.g.
<location path="yourservice.asmx">
<system.web>
<httpRuntime executionTimeout="240" maxRequestLength="20480" />
</system.web>
</location>
There seems to be no way to change the POST size for a ASMX Web Service when only HttpPost is enabled.
The solution in the end was to switch the service to running HttpSoap and create a service reference to the assembly containing the control. Once done the binding is created using code in the control once the endpoint is set via a property.