Return large data from WCF Service to ASP.NET Web Service - asp.net

So we have console-hosted WCF Service and ASP.NET WEB Service (on IIS).
After some tough operation WCF Service must return some (large) data to ASP.NET Web Service for next processing. I tested on small results and everything is ok.
But after testing on real data that is a serialized result object that is near 4.5 MB, an error occurs on ASP.NET Web Service, which is the client in wcf-client-server communication.
This is the error I got:
The socket connection was aborted. This could be caused by an error
processing your message or a receive timeout being exceeded by the
remote host, or an underlying network resource issue. Local socket
timeout was '04:00:00'. Inner Exception: SocketException:"An existing
connection was forcibly closed by the remote host" ErrorCode = 10054
Messages size are configured by next binding (on server and client):
NetTcpBinding netTcpBinding = new NetTcpBinding();
netTcpBinding.TransactionFlow = true;
netTcpBinding.SendTimeout = new TimeSpan(0, 4,0, 0);
netTcpBinding.Security.Mode = SecurityMode.None;
netTcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
netTcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
netTcpBinding.Security.Transport.ProtectionLevel = ProtectionLevel.None;
netTcpBinding.MaxReceivedMessageSize = 2147483647;
netTcpBinding.MaxBufferSize = 2147483647;
netTcpBinding.MaxBufferPoolSize = 0;
netTcpBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
netTcpBinding.ReaderQuotas.MaxArrayLength = int.MaxValue;
netTcpBinding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
netTcpBinding.ReaderQuotas.MaxDepth = 32;
netTcpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;
MaxObjectsInGraph property is configured in a config file.
What can you advise me? And also I need example how programmatically set MaxObjectsInGraph property on client and server.
Thanks for answers.

Problem is fixed by setting programmatically MaxObjectsInGraph(for serializer) as a service attribute.

Related

SQL Server Report Server (SSRS) via WCF: HTTP request is unauthorized with client authentication scheme 'Ntlm'

I have a .Net Core 3.1 application which is trying to connect to a SQL Server Report Server via WCF, in order to programmatically generate reports on demand.
But the program is not able to authenticate against the Report Server.
Here is the relevant program code:
var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
binding.MaxReceivedMessageSize = 10485760; //10MB limit
// Create the execution service SOAP Client
var rsExec = new ReportExecutionServiceSoapClient(
binding,
new EndpointAddress("http://my-ssrs/ReportServer")
);
// Setup access credentials.
var clientCredentials = new NetworkCredential(
"MyReportServerUserName",
"MyReportServerPassword",
"."
);
if (rsExec.ClientCredentials != null)
{
rsExec.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
rsExec.ClientCredentials.Windows.ClientCredential = clientCredentials;
}
// ************************************************
// Get following Exception when next line executes.
// ************************************************
await rsExec.LoadReportAsync(null, "/path-to/my-report", null);
When the last line ("rsExec.LoadReportAsync") is executed, I get the following exception:
The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM'.
The Report Server is on the same Windows Domain.
After some research, I've tried changing the ClientCredentialType = HttpClientCredentialType.Windows but this generated a different exception, as follows:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'.
Does anyone have any suggestions about what I might try?
Had the same problem. Solved it by additionally setting the proxy credential type:
binding.Security.Transport.ProxyCredentialType = System.ServiceModel.HttpProxyCredentialType.Ntlm;

Getting 400 Bad Request erro calling java web service

I am connecting to a java web service from my asp.net app ,but I am getting a 400 Bad request exception.
I have added a web reference in my project and using that to connect in the code as follows :
client is the web service reference object.
NetworkCredential credentials = new NetworkCredential("", "");
client.Credentials = credentials;
client.PreAuthenticate = true;
client.RequestEncoding = Encoding.UTF8;
object response = client.getmethod(req);
I also tried putting in
client.UnsafeAuthenticatedConnectionSharing = true;
client.AllowAutoRedirect = true;
but it still does not work and gives me the same error. The request is working if i try from Soap-UI from my machine.
To Add, I am getting a ClientProtocol error in SoapUI also if i don't select authentication type as "PreEmptive". Is there a way to set this in asp.net.
Any thoughts would be appreciated.

How to host duplex wcf service on a VPS

i am trying to host a wcf service which has a following attribute;
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
and i am creating host class like this;
var uri = new Uri("net.tcp://localhost:7951");
var binding = new NetTcpBinding();
host = new ServiceHost(typeof(ChatService), uri);
ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null) host.Description.Behaviors.Add(new ServiceMetadataBehavior());
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
host.AddServiceEndpoint(typeof(IChat), new NetTcpBinding(), "");
host.Open();
So, on developer computer and dedicated server this is working. However, what i need to do is, host this on a VPS (vitual private server).
I thought making a web project and adding this code block to global.asax application start method. but this failed. I suspect problem that the port is closed from firewall maybe.
What solution should I follow?

Policy File Check closes socket

I have created a flex app that uses sockets. I published the flex app in a web application that runs on glassfish server.
Now from that flex app i create a socket connection to a C# server and start sending/receiving data.
The problem is that after i create the socket connection to C# server the flex app first checks the policy file, and after it get's it, it closes the socket, without keep the connection alive.
This is my C# server:
TcpListener tcpListener = new TcpListener(IPAddress.Parse("172.17.41.211"), 12345);
TcpClient tcpclient = tcpListener.AcceptTcpClient();
Socket client = tcpclient.Client;
while (client.Available > 0)
{
int bytes = 0;
byte[] m_aBuffer = new byte[1024];
bytes = client.Receive(m_aBuffer, m_aBuffer.Length, SocketFlags.None);
String str = Encoding.ASCII.GetString(m_aBuffer, 0, bytes);
if (str.StartsWith("<policy-file-request/>"))
{
sendBytes = Encoding.ASCII.GetBytes("<cross-domain-policy><allow-access-from domain=\"172.17.41.211\" to-ports=\"12345\"/></cross-domain-policy>\0");
client.Send(sendBytes);
}
}
while (client.Connected)
{
Thread.Sleep(200);
sendBytes = Encoding.ASCII.GetBytes("message to client");
client.Send(sendBytes, sendBytes.Length, SocketFlags.None);
}
Now the flex client looks like:
private var socket:Socket = new Socket();
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onData);
socket.addEventListener(ErrorEvent.ERROR, errorHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
...
socket.connect("172.17.41.211", 12345);
...
Now after i create the connection and it gets the policy from server it closes this socket, so to be able to use this connection i have to call again
socket.connect("172.17.41.211", 12345));
After i do this, i can use normally the connection.
Can someone suggest why this happens and maybe is possible to not have closed the connection ?
You don't send the policy file through the socket itself. It needs to be on a different channel. For instance, if you connect to some ip/port, by default flash will try to connect to the same ip but on port 843 and look for the master policy file.
You can also set it manually using Security.loadPolicyFile(someURL). More information can be found here.

HTTP Connection Parameters

I am using the HTTP Connection in the following way:
HttpConnection _httpConnection = null;
try {
_httpConnection = (HttpConnection)Connector.open(_url);
} catch(Exception e) { }
byte [] postDataBytes = _postData.getBytes();
_httpConnection.setRequestMethod(HttpConnection.POST);
_httpConnection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
_httpConnection.setRequestProperty("Content-Language", "en-US");
_httpConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
_httpConnection.setRequestProperty("Connection", "close");
_httpConnection.setRequestProperty("Content-Length", Integer.toString(_postData.getBytes().length));
os = _httpConnection.openOutputStream();
os.write(postDataBytes);
os.flush();
This HTTP Connection requires parameters to successfully open. For example on a WIFI network, it requires the ";deviceside=true;interface=wifi" to be added to the URL.
The problem is for the EDGE connection. Each country requires different parameters to be added. For example in lebanon it requires ";deviceside=false" but in KSA if i add this parameter the connection will not open. In USA it needs different types of parametes. The question is how to establish an HTTP connection for all the countries with the same parameters. So that the application will successfully have an internet connection no matter where it is downloaded.
Welcome to the confusing world of network transports on BlackBerry! You will want to start with the article Connecting your BlackBerry - http and socket connections to the world.
Here is a simple example for "just give me a connection" (note, you will need to add appropriate error handling; also, myURL in the code below should have no connection descriptor info appended to it):
ConnectionFactory factory = new ConnectionFactory();
ConnectionDescriptor descriptor = factory.getConnection(myURL);
if (descriptor != null) {
_httpConnection = (HttpConnection) descriptor.getConnection();
...
}
Try using to use the method reffered in this link melick-rajee.blogspot.com and use it like
_url = "http://www.example.com";
_httpConnection = (HttpConnection)Connector.open(_url + getConnectionString());
You will have to sign the application to use this else the application will show exception.
To sign your application just go here Code Signing Keys
To use the connectionFactory, seems you need to set BisBOptions.
Try this:
connFact = new ConnectionFactory();
connFact.setTransportTypeOptions(TransportInfo.TRANSPORT_BIS_B,
new BisBOptions("mds-public"));

Resources