problem when sending images through wcf from silverlight - wcf

Silverlight uses WCF with basicHttpBinding
<basicHttpBinding>
<binding name="BasicHttpBinding_BugsService"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None"/>
</binding>
</basicHttpBinding>
I send the image as an byte[], and it's working as long as the image has less than 20KB
but when it's bigger i get the error:
The remote server returned an error: NotFound
in the Reference.cs
public bool EndSave(System.IAsyncResult result)
{
object[] _args = new object[0];
bool _result = ((bool)(base.EndInvoke("Save", _args, result))); // error
return _result;
}

Please catch the exception on the wcf side in the interface implementation and post that.
The error may be related to this problem:
"WCF Message Size Issue"

Check the "maxReceivedMessageSize" property (representing the size in bytes) on the binding configuration. If your data exceeds that size, the message is discarded.

Related

How to change default message size using ClearUserNameBinding?

We are using ClearUserNameBindig in our WCF service.
When we tried to return a message with more than 3k records, we received this error:
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.
We tried to modify web.config like that:
<bindings>
<clearUsernameBinding>
<binding name="myClearUsernameBinding"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000" />
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
</clearUsernameBinding>
</bindings>
But we received this error:
Unrecognized attribute 'maxReceivedMessageSize'.
How to change default message size using ClearUserNameBinding?
We found the solution following this steps:
http://sureshjakka.blogspot.com.ar/2010/03/changing-message-sizes-in.html
We modify the code of ClearUserNameBinding like this:
In AutoSecuredHttpTransportElement() constructor, initialize the values to maximum possible
public AutoSecuredHttpTransportElement()
{
MaxReceivedMessageSize = int.MaxValue;
MaxBufferSize = int.MaxValue;
MaxBufferPoolSize = long.MaxValue;
}
In CreateBindingElements() method create XMLDictionaryReaderQutotas object and set the same on TextMessageEncodingBindingElement. Here is the modified version of this method.
public override BindingElementCollection CreateBindingElements()
{
XmlDictionaryReaderQuotas rqMax = XmlDictionaryReaderQuotas.Max;
TextMessageEncodingBindingElement textBE = new TextMessageEncodingBindingElement();
textBE.MessageVersion = this.messageVersion;
rqMax.CopyTo(textBE.ReaderQuotas);
var res = new BindingElementCollection();
res.Add(textBE);
res.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
res.Add(new AutoSecuredHttpTransportElement());
return res;
}
Note: Make sure that you have "System.Runtime.Serialization" version 3.0.0.0 and above in your references. Because if you have version 2.0.0.0, you will get compile error as this version does not allow setting properties on ReaderQuotas.
Web.config:
<bindings>
<clearUsernameBinding>
<binding name="myClearUsernameBinding" />
</clearUsernameBinding>
</bindings>
Finally We update the references in server and client.

WCF tcp binding messages sizes

This subject is discussed a lot around here but no answer is really accurate.
i have a wcf service that i've created with nettcpbinding.
i wanted to examine the messages sizes/sent data rate/received data rate that are being transferred between the server and client.
The service is a duplex channel and the client code is auto-generated by adding a service reference.
Both applications (client/server) are written in C# .Net 4.0.
The nettcp binding that is using the default binary encoder and the configuration settings on the server side is as follows:
<bindings>
<netTcpBinding>
<binding name="largeMessage"
receiveTimeout="infinite"
sendTimeout="24:00:00"
openTimeout="00:00:10"
closeTimeout="00:00:10"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxConnections="2000"
transactionFlow="false"
listenBacklog="2147483647"
maxBufferPoolSize="2147483647">
<readerQuotas maxDepth="128"
maxArrayLength="200000000"
maxStringContentLength="2147483647"/>
<security mode="None" />
<reliableSession enabled="false" ordered="true" inactivityTimeout="infinite" />
</binding>
</netTcpBinding>
</bindings>
The service is self hosted and is started as a console application by creating:
ServiceHost host = new ServiceHost(serviceObject, addresses);
i used wireshark to get a general statistics and the tcp packets that are transferred and i saw that i have a very high data rate.
So i wanted to examine each message size that is transferred between client and server.
For this i used several techniques for measuring messages sizes that are suggested in this forum but none of them give the exact same size as the wireshark does.
i already tested the following:
WCF - Measuring approximate message sizes programmatically
this links:
http://winterdom.com/2009/07/comparing-text-and-binary-serialization-in-wcf/
and did this in my code:
static byte[] SerializeToBin<T>(T obj)
{
Message msg = ObjectToMessage(obj);
MessageEncodingBindingElement mebe = new BinaryMessageEncodingBindingElement();
mebe.MessageVersion = MessageVersion.Soap12;
return Serialize(msg, mebe.CreateMessageEncoderFactory());
}
static byte[] Serialize(Message msg, MessageEncoderFactory factory)
{
MessageEncoder enc = factory.Encoder;
MemoryStream stream = new MemoryStream();
enc.WriteMessage(msg, stream);
return stream.ToArray();
}
static Message ObjectToMessage<T>(T obj)
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
return Message.CreateMessage(MessageVersion.Soap12, "", obj, ser);
}
it doesn't give accurate results.
Then i tried to add a message inspector and to listen to the Before/After - Send/Receive messages as suggested in this article
http://devlicio.us/blogs/derik_whittaker/archive/2011/02/03/how-to-intercept-a-wcf-message-to-track-message-size.aspx
and called this function:
private void DetermineAndLogMessageDiagnostics(ref Message message, eMessageDirection messageDirection)
{
long sizeInBytes = 0;
var mb = message.CreateBufferedCopy(int.MaxValue);
message = mb.CreateMessage();
var ms = new MemoryStream();
using (var memWriter = XmlDictionaryWriter.CreateBinaryWriter(ms))
{
mb.CreateMessage().WriteMessage(memWriter);
memWriter.Flush();
sizeInBytes = ms.Position;
}
//Recalculates the updated average and updates the variables
//sentBytes, averageSentbps, receivedBytes, averageReceivedbps
RecalculateAverage(bodySizeInBytes, messageDirection);
Logger.Info("Message '{0}' size: {1} bits / {2} bytes. ({3} KBits). Sent (Total: {4} Bytes, {5:0.00} bps). Received (Total: {6} Bytes, {7:0.00} bps)",
action,
sizeInBytes * 8,
sizeInBytes,
((double)sizeInBytes * 8) / 1024,
sentBytes,
averageSentbps,
receivedBytes,
averageReceivedbps
);
}
This also doesn't give accurate results.
When i say not accurate - i mean around 300 - 500 bytes differences. But the gap is not constant.
i didn't want to create a custom binding because i wanted to examine the netTcpBinding and didn't want to change any configuration.
Does anyone have an accurate solution for this matter?
Thank you for reading this long question description.
And thanks in advance for any suggested solution.
The only way where you'll get an accurate measurement of the message size is to use a custom message encoder. It can wrap the original encoder, and at that point (on the calls to WriteMessage and ReadMessage you can look at the message sizes.
You don't get accurate results by writing the message to a stream using the binary writer because the binary encoder used by the NetTcpBinding uses some dictionaries to further compress the message during transmission.

How to use ServiceRoutes while defining maxReceivedMessageSize for non-custom bindings in WCF

Editing this to refocus on the actual issue. I've preserved the origional question at the bottom of the message but changing the title and content to reflect what was really happening.
I need to override the maxReceivedMessageSize for a WCF service added to an MVC3 project via the ServiceRoute mechanism. Specifing the binding in the web.config doesn't work. How does one do this.
Initial question is below this line but is misleading based on lots of false positives I was seeing.
Hi I have used some examples to add a file streaming upload service to my MVC3 project. If I use the default bindings (i.e., not defined in web.config) the service works as long as I don't exceed the 64k default size. When I try and define my own binding to increase the size I get a content-type mismatch in my trace and a HTTP415 Unsupported Media Type in the response. I'm trying to call this via fiddler via HTTP and am not using a WCF client.
Here is the error in the trace:
Content Type image/jpeg was sent to a service expecting multipart/related;type="application/xop+xml". The client and service bindings may be mismatched.
Here is the web.config service model section
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior0" />
</endpointBehaviors>
</behaviors>
<services>
<service name="AvyProViewer.FileService">
<endpoint address="UploadFile" binding="basicHttpBinding" bindingConfiguration=""
contract="AvyProViewer.FileService" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Mtom" transferMode="StreamedRequest">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
Here is the service:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class FileService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UploadFile")]
public string UploadFile(Stream fileStream)
{
string path = HostingEnvironment.MapPath("~");
string fileName = Guid.NewGuid().ToString() + ".jpg";
FileStream fileToupload = new FileStream(path + "\\FileUpload\\" + fileName, FileMode.Create);
byte[] bytearray = new byte[10000];
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = fileStream.Read(bytearray, 0, bytearray.Length);
totalBytesRead += bytesRead;
} while (bytesRead > 0);
fileToupload.Write(bytearray, 0, bytearray.Length);
fileToupload.Close();
fileToupload.Dispose();
return fileName;
}
}
And here is where I expose it in my MVC3 routes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new ServiceRoute("FileService", new WebServiceHostFactory(), typeof(FileService)));
. . .
}
I think the issue is with the mtom declaration for messageEncoding in your binding. Try changing messageEncoding to Text.
Answer ended up being a combination of three different stack overflow posts. None by themselves solved the question but each provided crucial clues as to what was happing.
It seems that if you add a ServiceRoute the web.config binding information is ignored. This SO post clued me in to what seems to be undocumented behavior of this function: Unable to set maxReceivedMessageSize through web.config
I then used this post to determine how to programatically override the maxreceivedmesssagesize for the binding: Specifying a WCF binding when using ServiceRoute.
Unfortunately the code form #2 didn't work out of the box (not sure if the binding behavior for ServiceRoute has changed or what makes the difference). Turns out that if you specify a ServiceRoute its automatically created as a CustomBinding which can't be cast to the WebHTTPBinding type used in #2. So this post: How to set the MaxReceivedMessageSize programatically when using a WCF Client? helped me determine how to change the code in #2 to add this capability to a custom binding.

unable to load wcf restful help page after changing transferMode to "Streamed"

In my project, a wcf restful service, which allow users to upload photos to the web service.
After changing config settings to allow large file upload. (add binding configuration, i.e. "TransferMode", "BufferSize", etc.)
All Operation contracts are all working as expected.
However, the service help page for the endpoint stopped working.
The help page comes back, once I remove the binding config setting on my endpoint
How can I fixed this?? where did i missed
thank you all
<bindings>
<webHttpBinding>
<!-- buffer: 64KB; max size: 64MB -->
<binding name="StreamedBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transferMode="Streamed"
maxBufferPoolSize="67108864" maxBufferSize="65536" maxReceivedMessageSize="67108864">
</binding>
</webHttpBinding>
</bindings>
<service name="WCFRestFul.ApiRestful">
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="StreamedBinding" bindingName="StreamedBinding"
contract="WCFRestFul.IApiRestful" behaviorConfiguration="web" />
</service>
Update:
I think it is not just because of the transfer mode, but maybe some other setting as well.
The service help page comes back once I remove the "bindingConfiguration" in the code above.
I have 2 endpoints. The other endpoint don't have the "bindingConfiguration", and the service help page works fine on that.
I definitely missed some thing here, maybe some thing simple.
any help will be greatly appreciated
I took carlosfigueira advice, painfully removed my config setting one at a time.
I changed my config settings from
OLD Code
<bindings>
<webHttpBinding>
<!-- buffer: 64KB; max size: 64MB -->
<binding name="StreamedBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transferMode="Streamed"
maxBufferPoolSize="67108864" maxBufferSize="65536" maxReceivedMessageSize="67108864">
</binding>
</webHttpBinding>
</bindings>
To Final working version (transferMode="Streamed" is removed)
<bindings>
<webHttpBinding>
<binding name="StreamedBinding" maxReceivedMessageSize="67108864" />
</webHttpBinding>
</bindings>
finally the service help page is back.
However I can't understand why it is back same as why it was turned off.
anyway, this is the working solution for my case.
hope someone would find it helpful.
What do you mean by saying that it stops working? In the example below the help page is still returned by the service (and I tried using both IE and Chrome, and they were able to see the page).
public class StackOverflow_5937029
{
[ServiceContract]
public interface ITest
{
[WebGet]
int Add(int x, int y);
}
public class Service : ITest
{
public int Add(int x, int y)
{
return x + y;
}
}
static void SendRequest(string address)
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
req.Method = "GET";
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException e)
{
resp = (HttpWebResponse)e.Response;
}
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Stream respStream = resp.GetResponseStream();
Console.WriteLine(new StreamReader(respStream).ReadToEnd());
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
WebHttpBehavior behavior = new WebHttpBehavior
{
HelpEnabled = true
};
WebHttpBinding binding = new WebHttpBinding
{
TransferMode = TransferMode.Streamed
};
host.AddServiceEndpoint(typeof(ITest), binding, "").Behaviors.Add(behavior);
host.Open();
Console.WriteLine("Host opened");
SendRequest(baseAddress + "/Add?x=4&y=8");
SendRequest(baseAddress + "/help");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}

Error calling a WCF REST service using JSON. length quota (8192) exceeded

I’m having a WCF REST service hosted in IIS using .NET 4 RC. The POST calls to the service are serialized using JSON. Everything works fine until the size of one of the DataMember (string) is longer than 8K. In this case I receive the error described below indicating the MaxStringContentLength has been exceeded. The maxStringContentLength attribute for the endPoint has been increased and it is correctly read from the config file.
Web config is:
<services>
<service name="MyServiceServer" >
<endpoint address="http://localhost/MyService" kind="webHttpEndpoint" endpointConfiguration="serviceEndPoint" contract="IMyService">
</endpoint>
</service>
</services>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="serviceEndPoint" maxReceivedMessageSize="2048000" maxBufferSize="2048000" maxBufferPoolSize="0">
<readerQuotas maxStringContentLength="2048000" maxArrayLength="2048000" maxDepth ="65000"/>
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
IMyService interface is defined as:
public interface IMyService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/request", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void MyMehod(<Class Type> obj);
}
Complete Error Message is:
“The server encountered an error processing the request. The exception message is 'There was an error deserializing the object of type . The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.'. See server logs for more details. The exception stack trace is: at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName) at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)”
This works, just make sure to have a full absolute URL as your endpoint address. If you get crafty and try to use a relative path, or if you omit .svc it will bomb with the strange reader quota error once the request gets too large --
I would file this under a Bug for WCF because either:
relative URLs should be disallowed (and an appropriate exception thrown)
or
the reader quota should work with relative paths as well
Insert into your web.config:
<configuration>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingConfig">
<readerQuotas maxStringContentLength="2048000" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
and insert attribute bindingConfiguration="webHttpBindingConfig" into your endpoint
I had similar problems but with .NET 3.5
I had no problems on the server log, so the problem was on the client.
Seems that the configuration with the max values increased was not read and used...
So I solved passing the name of the endpoint EXPLICITLY in the constructor of the WebChannelFactory, using another overload.
WAS:
WebChannelFactory<IWKRestTest> factory = new WebChannelFactory<IWKRestTest>(new Uri(XXX));
factory.Credentials.UserName.UserName = K_USERNAME;
factory.Credentials.UserName.Password = K_PASSWORD;
IWKRestTest proxy = factory.CreateChannel();
IS:
WebChannelFactory<IWKRestTest> factory = new WebChannelFactory<IWKRestTest>("IWKRestTestService");
and in the app.config there's:
The Uri is indicated in the endpoint node but there you find also the bindingConfiguration and so on, so all the new increased limits now works.