F# WsdlTypeProvider MaxReceivedMessageSize - web-services

I am using F# and the WsdlTypeProvider with this code:
type svc = FSharp.Data.TypeProviders.WsdlService<"http://my.service.url?wsdl">
let svcClient = svc.GetServicePort()
It works quite well in most cases calling some method on the client. But in some cases I get this message:
The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
Except there is no such property on the binding. The binding may be accessed using:
let binding = svcClient.DataContext.Endpoint.Binding
Casting the binding to BasicHttpBinding, which has the property, does not work either, because apparently the bindings are not related inheritance wise:
let binding = svcClient.DataContext.Endpoint.Binding :?> System.ServiceModel.BasicHttpBinding
And it results in this error:
Unable to cast object of type
'System.ServiceModel.Channels.CustomBinding' to type
'System.ServiceModel.BasicHttpBinding'.
So the question is:
How can I increase the MaxReceivedMessageSize while using the WsdlTypeProvider?
There doesn't seem to be any settings in my App.Config, like there would be if I was attaching to a service in the regular way, by generating proxy etc.

If you are writing this code for testing purpose than it is ok to use BasicHttp binding but to support sessions and for security reasons you should not use BasicHttp for commercial use of application . Go for netTcp or WsHttp bindings. The following code works for netTcp binding.
<bindings>
<customBinding>
<binding name="CustomBinding_MyService">
<binaryMessageEncoding>
<readerQuotas maxDepth="32" maxStringContentLength="200000000" maxArrayLength="200000000"/>
</binaryMessageEncoding>
<tcpTransport maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000" maxBufferSize="200000000">
<extendedProtectionPolicy policyEnforcement="Never"/>
</tcpTransport>
</binding>
</customBinding>
</bindings>
Hope this helps!

Related

Web Service Error 400 - Bad Request

I have a perplexing issue. I have Web Service A (henceforth WSA), a 3.5 .Net WCF, which I have added a call to Web Service B (henceforth WSB) which is a 3.5 .Net ASMX. When running WSA in the client (SOAPUI or WCFStorm), the WSB call times out per the client timeout setting.
In the VS event viewer I can see that the call to WSB immediately throws two error 400s:
Exception thrown: 'System.Net.WebException' in System.dll ("The remote
server returned an error: (400) Bad Request."). Exception thrown:
'System.Net.WebException' in System.dll ("The remote server returned
an error: (400) Bad Request.")
No reason is given. What is just as puzzling to me is the error doesn't go to my catch. When I debug and I hit the line of code that calls WSB, it's like a reset. No further code gets executed and no error is thrown by my WSA.
If I call WSB directly, it works. So nothing is wrong with WSB. At suggestion of a coworker, I took the code specific to my change and put it in a stand-alone service. I literally C&P the code and configs setting specific to me and adjust namespaces and class names. Lo and behold it works. My stand-alone web service called WSB just fine and get the data I expect.
A coworker and I checked the logs (IIS log for the service and the HTTPERR log) on the IIS server that WSB resides on to see if there was any mention of the 400 error. We found none.
So we are kind of perplexed at this point. The only thing we can think of is perhaps something in the web config might be interfering but have no idea what it could be.
If you have any suggestions of where else to look that would be helpful.
And it would be nice to know why it isn't falling into my error handler.
Thanks.
Update: It was requested I add config and code. I don't think it will help honestly and it is pretty straightforward. I can't put the real code due to company reasons but it is basically this:
In web config:
<configuration>
<appSettings>
<add key="endpointUrl" value = "someurl" />
</appSettings>
.
.
.
<applicationSettings>
<MyService.Properties.Settings>
<setting name="MyService_TheirService"
serializeAs="String">
<value>someurl</value>
</setting>
</MyService.Properties.Settings>
</applicationSettings>
Even though the data is super small I did try making large reader settings and such:
<binding name="CustomHtttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="01:50:00" openTimeout="01:50:00" sendTimeout="01:50:00" receiveTimeout="01:50:00" >
<readerQuotas maxDepth="128"
maxStringContentLength="8388608"
maxArrayLength="2147483646"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
</binding>
Code:
using MyService.TheirService
.
.
.
var theirURL = ConfigurationManager.AppSettings["endpointUrl"];
var oSvc = new TheirServiceObject
{
Url = theirURL
};
int numberIneed = oSvc.SomeMethod();
That last line is where it throws the 400.
UPDATE 2:
A colleague show me how to use Fiddler. And I can now see that the request to WSB is absolute garbage.
xڭ s 6 mr!!u \ .3 5'3 G QOH>Iп kX M3 ~vY ) X e Z
w ~ :jv -ݴwڽHb Yqv A :(Q Z; >9W O0g 6 .ɖVlU Ţ 8Z
< ( t eSv U]r R $N \
Some odd encoding? At least it's another clue.
Wanted to let you know this problem was solved. Another Dev that had worked on this service before but no longer just happened to walk by and I said "Hey! Look at this!"
They saw the garbage request data and said "That looks like compression. Look up compression in the project."
Turn out there was a custom compression component that was compressing the outgoing data of the service and you needed to add 2 lines of code to decompress. After adding those lines to the top of my method everything immediately worked.
The lesson here is if your project is doing some weird stuff that defies reason, try and find as many people as you can that worked on it before even if they aren't working on it anymore.

Elixir Detergentex Soap Call Always Returns {:ok, :undefined, :undefined}

I've implemented a simple SOAP webservice client to test the functionality but whether my client or in iex, and regardless of the target service I always get {:ok, :undefined, :undefined}
Here is my code:
wsdl_url = "http://www.webservicex.net/convertVolume.asmx?WSDL"
action = "ChangeVolumeUnit"
parameters = ["100", "dry", "centiliter"]
Detergentex.call(wsdl_url, action, parameters)
I'm using Versions:
Elixir: 1.2.0
Detergentex: 0.0.7
My mix.exs deps:
[{:erlsom, github: "willemdj/erlsom"},{:detergentex, "0.0.7"}]
Any suggestions on what I'm missing would be greatly appreciated.
1.) It's got a dependency on the detergent package.
Have you added the dependency for detergent? If not modify your mix.exs to this:
[{:erlsom, github: "willemdj/erlsom"},{:detergentex, "0.0.7"}, {:detergent, "~> 0.3.0"}]
2.) You also need to add detergentex to the list of applications as well:
def application do
[applications: [:logger, :detergentex]]
end
3.) The fact that it's returning {:ok, :undefined, :undefined} may simply indicate an issue with the endpoint or the message you're passing. Therefore I'd try it against an endpoint you're sure is good with a message you're sure will work. Perhaps the valid parameters to the endpoint they mention in their docs have changed since the docs were prepared.
By the way, I did see that you mentioned "regardless of the target service" but given it seems that you failed to add that detergent dependency and the fact that it looks like you forgot to add detergent to the application list, I'd still try some of those other SOAP endpoints again since you've changed things.

Getting a Windows Client to Change its Web Service Endpoint Dynamically – Problems with a WSDL

This describes a problem I had and the solution found, which I did not see discussed elsewhere (except the Background material).
Background – What Should Work (but May Not)
Let’s assume a web service defined by “https://mysite.com/?wsdl”, whose functions are to be called by a Windows client “myclient.exe”. In Visual Studio, you provide a “Service Reference” (The problem described here also manifests with the older-style “Web Reference”.)
Suppose you have more than 1 machine (mysite and mysite2) exposing the same web services. It is desirable to just change the client’s choice of endpoint at runtime to point to the correct machine, without having to update the Service Reference. This could be done in 3 ways:
Edit the deployed myclient.exe.config (or its source at compile time in VS, app.config), in particular:
<system.serviceModel>
...
<client>
<endpoint address="https://mysite2.com/?wsdl" …/>
</client>
</system.serviceModel>
Arrange your client code so that it reads in or selects the endpoint address, and sets it in the constructor (where “MyWebService” is the name of the Service Reference, and MyWebServiceBinding is defined in app.config), e.g. in C#:
public static EndpointAddress remoteAddress =
new EndpointAddress("https://mysite2.com/?wsdl");
public static BasicHttpBinding basicBinding =
new BasicHttpBinding("MyWebServiceBinding"); //Your binding type may differ
public MyWebService.myWebServicePortTypeClient mws =
new MyWebService.myWebServicePortTypeClient(basicBinding, remoteAddress);
Do like (2), but instead of in the constructor, set the endpoint later, say, during the first call to the service:
private void SetMyEndpointAddress(MyWebService.myWebServicePortTypeClient mws)
{
mws.Endpoint.Address = new
System.ServiceModel.EndpointAddress("https://mysite2.com/?wsdl");
}
All of these can still quietly fail if the specifics of the service WSDL are problematic (probably not generated in a routine manner by a MS server; PHP NuSoap in my case). Assuming you have control over the server WSDL, the next section explains what to look for.
Removing Unnecessary URLs from the WSDL
The WSDL is a long document with overall structure shown next. If any of the phrases pointed to here by "<===" contains a URL (e.g., https://mysite.com/...), change its generation process so that this is no longer true.
<definitions ...
xmlns:tns="soap/MyWebServices" <===
...
targetNamespace="soap/MyWebServices"> <===
<types>
<xsd:schema elementFormDefault="qualified"
targetNamespace="soap/MyWebServices"> <===
...
</xsd:schema>
</types>
[multiple <message>...</message> sections, ones for each defined function.]
<portType name="myWebServicesPortType">...</portType>
<binding name="MyWebServicesBinding" type="tns:myWebServicesPortType">...</binding>
<service name="MyWebServices">...</service>
</definitions>
In addition, within the <binding>…</binding> section, the “soapAction” for each function should be only the function name. It should not include a URL prefix (followed by “#” and the function). Typical function:
<operation name="getMyData">
<soap:operation
soapAction="getMyData" <===
style="document"/>
<input><soap:body use="literal" namespace=""/></input>
<output><soap:body use="literal" namespace=""/></output>
</operation>
The ONLY place where a URL to the particular machine should appear is in the <service> section:
<service name="MyWebServices">
<port name="MyWebServicesPort" binding="tns:MyWebServicesBinding">
<soap:address location="https://mysite.com/?wsdl"/>
</port>
</service>

How to use Remember me in spring security for custom authentication

Can any one give me idea how to use Remember me check box in spring security for custom authentication,
this is my remember me field in login page
and this is the configuration in secuirty.xml
thanks
As defined in Spring Docs, when one declares a "remember-me", the "user-service-ref" should be:
"The remember-me services implementations require access to a
UserDetailsService, so there has to be one defined in the application
context."
However, in your case, your user-service-ref is a ref to a bean of type MyCustomAuthentication. This is why you get the ClassCastException "MyCustomAuthentication cannot be cast to UserDetailsService".
You should define something like:
<security:user-service id="userDetailsService">
<security:user name="username" password="pass" authorities="ROLE_USER" />
</security:user-service>
and use this id in the "user-service-ref"
P.S. IMHO you will have to fix your authentication-provider as well
HTH
For your request, to be more precise:
<http auto-config="true" use-expressions="true">
...
<remember-me user-service-ref="customUserDetailsManager"/>
</http>
<b:bean id="customUserDetailsManager"
class="com.something.something.MyCustomUserDetailsManager" />
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsManager">
</authentication-provider>
</authentication-manager>
</b:beans>
Note that MyCustomUserDetailsManager should implement UserDetailsManager
Another important note (from the docs):
Note that both (Spring's) implemementations require a
UserDetailsService. If you are using an authentication provider which
doesn't use a UserDetailsService (for example, the LDAP provider) then
it won't work unless you also have a UserDetailsService bean in your
application context.

Complex Object in JAX-WS is created empty

I'm testing JAX-WS to access the Oracle IRM web serviecs. I can get it to work just fine with AXIS so this isn't an Oracle problem.
What's happening is that I'm getting the following error when making the call:
Expected xsd:anyType - unknown type provided
If I look at the SOAP packet is sent I see that the owner tag is blank under JAX-WS:
<ns1:browseAccounts>
<owner/>
<accountType>All</accountType>
</ns1:browseAccounts>
The same piece under AXIS is this:
<owner xsi:type="ns1:LicenseServer"
xmlns=""
xmlns:ns1="http://www.sealedmedia.com/ls/server/schema">
<serverKey>#############</serverKey>
</owner>
Obviously the owner tag is not getting properly created, this is what I'm using to create that:
AccountServicesPort AA = ORI.getAccountServices();
LicenseServer LicSer = new LicenseServer();
LicSer.setServerKey("#######################");
List<Account> Acts = AA.browseAccounts(LicSer,AccountAccountType.ALL);
Is there some other process that I need to go through to create the object properly?
EDIT
I thought maybe running the LicenseServer creation through ObjectFactory would help. Unfortunately, it doesn't.
Despite the Oracle IRM documentation stating that BrowseAccounts accepts either a LicenseServer object or a Context object for the owner parameter it actually accepts an LicenseServer_ref.
EDIT
Further, I was running JAX-WS under JDK 1.6.0 which is a lower version than JDK 1.6.0_14. The new version supports XMLSeeAlso annotation which allowed JAX-WS to use the proper class for serialization.