Debugging some of these issues (and the AG_ stuff) is the biggest challenge with Silverlight right now...
You can look at the compression sample app in the Samples download. Even if you don't use compression, the technique allows you to easily get at the size of the byte stream that'll go on the wire (though you could also use fiddler or similar) to see if it is still blowing out some size limit.
Though honestly I think all Silverlight apps should just use compression and be done with it. If it didn't mean taking a dependency on another open source project I'd look at directly using compression in the WcfProxy out of the box...
httpRuntime maxRequestLength="8192" enable="true" executionTimeout="60"
Hi Rocky,
I am having the exact same issue. Only, I get this issue WHEN using compression. It's very strange.
Without compression, I can load and save a parent and its children. When I save the parent with one child/ 250 children, no issues.
However, using the compression host/proxy, I can save a parent with up to a few children. But in the scenario as above, using 250 children, I get the NotFound error.
I am using CSLA 4 and the CompressionHost/Proxy and SharpLibZip assemblies found in the CSLA SL 4.0 Samples (RemotePortalWithCompressedProxy example) as well as the exact same WCF configuration settings in the config files.
I have noticed that the zip assemblies target the 2.0 runtimes. Not sure if that is the issue. But again, the compression stuff works fine as long as the children count is within a lower range.
I'm finding this terribly difficult to debug as well. I can see the call being made to the service via Fidler, but a breakpoint is not being hit in CompressionHost.ConvertRequest in the 250 children scenario.
So again, loading and saving a parent with 250 children WITHOUT compression works just fine. But loading up and saving the same parent with its 250 children bombs when using compression. However, saving the parent with a few children with compression does work.
Any thoughts on how I can debug this, or is this a known issue?
Thanks much!
Are you sure the compression library is on both the client and server in the proper location? Can you build a test project to verify that the zip assemblies work under Net 4? I hit a problem where Sqlite .Net wasn't working under 4.
Hi Andy,
I'm not sure what you mean by the proper location? I know that the parent and its children are being compressed before sending out and decompressed when received on the server. I have breakpoints set which are hit successfully on the SL side and server side.
Of course, in the case where I have 250 children, it is compressed but never makes it to the server. But a parent with fewer children makes it to the server and is decompressed just fine.
Any other thoughts?
Have you tried a test project to verify that compression works as you expect under .Net 4?
Also, is this one of those weird cases when the compression doesn't compress much, and just ends up adding more overhead?
I'm just kinda throwing things out there. :-)
Oh, I appreciate that, that's what I'm looking for because I'm all out of ideas (short of not using compression :)
So I am using .NET 4. CSLA SL 4 and CSLA .NET 4.
Any other thoughts? This is one of those really frustrating issues where you feel completely helpless..
Andy, also, the compression does a great deal of good; from 1 mb down to 50k. So yeah, kind of a big deal ;)
Still unable to figure this one out. Anyone have any thoughts on this?
Have you followed Andy's suggestion and created a simple test app using compression?
I'm not sure what a test app would do for me. Perhaps I don't understand what you and Andy mean by that?
The compression does work, just not when the parent's child collection gets too big. Loading the same parent with all its children without compression works fine, so I'm sure it's not a payload size issue on the receiving end of the server, because the payload size is much larger without compression.
Do you have any thoughts on how I might better debug this? Again, using compression, I do see the request going out to the server, but then the breakpoint is not hit in the compressionHost. Reducing the size of the children (ex. 255 down to 150) works fine though...
Can you get a breakpoint in compressionhost when things work?
If so, then it seems likely that IIS or ASP.NET or WCF is failing before compression is invoked with the large data size.
If not, then not hitting a breakpoint provides no information.
But if you can hit the breakpoint otherwise, just not in this case, then we know that something is failing before your code gets to run since it is your class that does anything real on the server. WcfHost just creates an empty response object and then immediately calls the convert method, which you've overridden to do your decompression.
Yes, I do get the breakpoint when the parent.children count is lower.
So in the case that is failing (255 children) on the SL side, I literally watch the collection get compressed, and I can see the request and packet being shipped off (via Fidler). Then in this case, the breakpoint on the service side (within CompressionHost) is never hit.
I would like to point out, once again, that the Fetch() is also not the issue here. Fetch() works great with compression. It's when I update a child, and call parent.Save() is when I get the "NotFound" exception.
And again, the kicker to all of this is that if I don't use compression, the same parent with its 255 children works just fine when invoking parent.Save().
Any more thoughts?
So WcfHost (which you've subclassed right?) has this code in Update():
public WcfResponse Update(UpdateRequest request)
{
var result = new WcfResponse();
try
{
request = ConvertRequest(request);
You are putting your breakpoint at the very top of your ConvertRequest() override, and that isn't being hit.
So I think it is a fairly safe bet that we can eliminate the decompression code or any later processing (like your data access, MobileFormatter, etc) from scrutiny.
You see the request flow across the wire. So when it hits the server, IIS routes the request to ASP.NET, which routes the request to WCF. WCF (from a simplistic view) routes the call to a message processor which I assume you haven't implemented (so this is a non-issue), and then to a deserializer (the DataContractSerializer or DCS) which rehydrates the UpdateRequest object. That object is passed as a parameter to the Update() method.
The DCS is what was used to serialize the UpdateRequest object on the client. We basically feed the result of the MobileFormatter, along with some other data, to the DCS and let Microsoft serialize everything into BinaryXML. Your client-side compression occurs after MobileFormatter, and before the DCS runs, so the DCS is actually serializing your compressed data.
The server-side processing is the mirror of the client. The UpdateRequest comes in, and is deserialized by the DCS. You then get to decompress data in the request object, then the MobileFormatter is used to deserialize the data, then the data portal itself is invoked to process the objects.
I'm going through all this so we're clear on the flow - and to help myself think through where it could fail.
We have visibility as the data goes over the wire. We know the flow never hits the Update() method in WcfHost. Therefore we've narrowed the failure window to IIS, ASP.NET, the WCF binding, a WCF message processor or WCF deserializion (the DCS).
WCF has pretty extensive tracing and debugging capabilities. I think that both Juval and Michelle's books cover how to turn on WCF tracing and set it to verbose - and I'm sure MSDN has articles on this too. So I think your next step is to turn on WCF tracing and see what it can tell you.
I think the tracing is a great idea, I'll look into that.
By WcfHost, I'm assuming you mean WcfPortal? Here is the class I'm using, which I took straight from the RemotePortalWithCompressedProxy sample, found in the CSLA SL 4.0 samples. Is this the correct version that I should be using?
public class CompressedHost : Csla.Server.Hosts.Silverlight.WcfPortal
{
protected override Csla.Server.Hosts.Silverlight.CriteriaRequest ConvertRequest(Csla.Server.Hosts.Silverlight.CriteriaRequest request)
{
Csla.Server.Hosts.Silverlight.CriteriaRequest returnValue = new Csla.Server.Hosts.Silverlight.CriteriaRequest();
returnValue.ClientContext = CompressionUtility.Decompress(request.ClientContext);
returnValue.GlobalContext = CompressionUtility.Decompress(request.GlobalContext);
if (request.CriteriaData != null)
returnValue.CriteriaData = CompressionUtility.Decompress(request.CriteriaData);
returnValue.Principal = CompressionUtility.Decompress(request.Principal);
returnValue.TypeName = request.TypeName;
return returnValue;
}
protected override Csla.Server.Hosts.Silverlight.UpdateRequest ConvertRequest(Csla.Server.Hosts.Silverlight.UpdateRequest request)
{
Csla.Server.Hosts.Silverlight.UpdateRequest returnValue = new Csla.Server.Hosts.Silverlight.UpdateRequest();
returnValue.ClientContext = CompressionUtility.Decompress(request.ClientContext);
returnValue.GlobalContext = CompressionUtility.Decompress(request.GlobalContext);
returnValue.ObjectData = CompressionUtility.Decompress(request.ObjectData);
returnValue.Principal = CompressionUtility.Decompress(request.Principal);
return returnValue;
}
protected override Csla.Server.Hosts.Silverlight.WcfResponse ConvertResponse(Csla.Server.Hosts.Silverlight.WcfResponse response)
{
Csla.Server.Hosts.Silverlight.WcfResponse returnValue = new Csla.Server.Hosts.Silverlight.WcfResponse();
returnValue.GlobalContext = CompressionUtility.Compress(response.GlobalContext);
returnValue.ObjectData = CompressionUtility.Compress(response.ObjectData);
returnValue.ErrorData = response.ErrorData;
return returnValue;
}
}
Yes, I meant WcfPortal, sorry...
Ok, so admitedly, I'm one of those users that usually have 4 instances of VS open at once and put my computer in sleep mode, rarely rebooting. A reboot seemed to have made the issue go away. Still extremely strange that the one particular scenario was causing issue, but in any event, it is gone now. So if you are like me and rarely reboot and run into some strange issue that just doesn't make sense, I'd give it a reboot. Common sense, I realize...
Out of curiousity, did you find a solution to this issue. I'm having the same problem, when the parent object contains too many children.
sorry, I missed the last post. I've tried all that including rebooting, but still doesn't work. I've enbled tracing and it says that "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."
I've increased it to 2147483647 but still doesn't work.
Hi
I have the same issue. I have re-booted and set the MaxReceivedMessageSize.
My limit was 128 child objects. When I manually insert more data into the database, the data is fetched without issues, but the update throws a 'NotFound' error.
Message=The remote server returned an error: NotFound.
StackTrace:
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at Csla.WcfPortal.WcfPortalClient.WcfPortalClientChannel.EndUpdate(IAsyncResult result)
InnerException: System.Net.WebException
Message=The remote server returned an error: NotFound.
StackTrace:
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
InnerException: System.Net.WebException
Message=The remote server returned an error: NotFound.
StackTrace:
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass4.<BeginOnUI>b__1(Object sendState)
InnerException:
Copyright (c) Marimer LLC