locked
Silverlight and WCF service data size RRS feed

  • Question

  • Hello,

    I have the following structure:

        /// <summary>
        /// Summary description for Evaluation
        /// </summary>
        [DataContract]
        public class Evaluation
        {
    
            [DataMember]
            public string EvalCode;
            [DataMember]
            public int SessionId;
            [DataMember]
            public int PenId;
    
            [DataMember]
            public List<BatchEvaluation> Batches = new List<BatchEvaluation>();
    
            [DataMember]
            public Guid BookId = Guid.Empty;
        }
    
        [DataContract]
        public class BatchEvaluation
        {
            [DataMember]
            public int BatchId;
    
            [DataMember]
            public List<DescriptorEvaluation> Descriptors = new List<DescriptorEvaluation>();
    
            [DataMember]
            public List<FreeDescriptorEvaluation> FreeDescriptors = new List<FreeDescriptorEvaluation>();
    
            [DataMember]
            public string Comment;
    
            [DataMember]
            public int Column;
        }
    
        [DataContract]
        public class DescriptorEvaluation
        {
            [DataMember]
            public int DescriptorId;
            [DataMember]
            public float Value;
        }
    
        [DataContract]
        public class FreeDescriptorEvaluation
        {
            [DataMember]
            public int DescriptorId;
        }

    and the following wcf service

        [ServiceContract(Namespace = "")]
        [SilverlightFaultBehavior]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class Service1
        {
            [OperationContract]
            public string DoWork(Evaluation evaluation)
            {           
                return evaluation.Batches.Count.ToString(CultureInfo.InvariantCulture);
            }
            
        }

    From my silverlight application I populate an Evaluation object and try to pass it to the DoWork method

            public MainPage()
            {
                InitializeComponent();
    
                Service1Client client = new Service1Client();
                client.DoWorkCompleted += ClientDoWorkCompleted;
    
                Evaluation evaluation = new Evaluation
                                            {
                                                BookId = Guid.NewGuid(),
                                                PenId = 1,
                                                SessionId = 2,
                                                EvalCode = "3",
                                                Batches = new ObservableCollection<BatchEvaluation>()
                                            };
    
                Random rnd = new Random(DateTime.UtcNow.Millisecond);
                for (int idx = 0; idx < 140;idx++ )
                {
                    BatchEvaluation batchEvaluation = new BatchEvaluation
                                                          {
                                                              Column = idx,
                                                              BatchId = idx,
                                                              Descriptors = new ObservableCollection<DescriptorEvaluation>()
                                                          };
    
                    for (int j = 0; j < 9;j++ )
                        batchEvaluation.Descriptors.Add(new DescriptorEvaluation{DescriptorId = j, Value = Convert.ToSingle(rnd.NextDouble() * 5.0) });
                    evaluation.Batches.Add(batchEvaluation);
                }
    
                client.DoWorkAsync(evaluation); 
            }
    
            static void ClientDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
            {
                MessageBox.Show(e.Result);
            }
    
    

    Unfortunatly, when I launch it, I get an exception:

    System.ServiceModel.CommunicationException was unhandled by user code
      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 SilverlightApplication2.ServiceReference1.Service1Client.Service1ClientChannel.EndDoWork(IAsyncResult result)
           at SilverlightApplication2.ServiceReference1.Service1Client.SilverlightApplication2.ServiceReference1.Service1.EndDoWork(IAsyncResult result)
           at SilverlightApplication2.ServiceReference1.Service1Client.OnEndDoWork(IAsyncResult result)
           at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(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__0(Object sendState)
                InnerException: 
    

    For the log, my web.config is

    <configuration>
        <system.web>
            <compilation debug="true" targetFramework="4.0" />
        </system.web>
    
        <system.serviceModel>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="false" />
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <bindings>
                <customBinding >
                    <binding name="customBinding0">
                        <binaryMessageEncoding />
                        <httpTransport />
                    </binding>
                </customBinding>
            </bindings>
            <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
            <services>
                <service name="SilverlightApplication2.Web.Service1">
                    <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1" />
                    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                </service>
            </services>
        </system.serviceModel>
    </configuration>

    If I populate Evaluation with only 118 batchEvaluations, I get no error.

    Any idea ?

    Thank you

    Wednesday, February 8, 2012 9:00 AM

Answers

  • I think the problem was I didn't update the service reference after changing my Web.config file.

    Moreover I noticed that I had to put the namespace in the service name and endpoint contract attributes.

    <services>
      <service behaviorConfiguration="WCFServiceBehavior" name="SilverlightApplication2.Web.Service1">
        <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1" />
      </service>
    </services>

    And now i can send huge data to my webservice.

    Thank you

    Friday, March 2, 2012 3:31 AM

All replies

  • See my post here for an example web.config for a WCF service with the limits maxed out and using binary transfer:

    http://social.msdn.microsoft.com/Forums/en-US/silverlightarchieve/thread/0a611684-d592-403b-bce6-0a6a605b1cee/

    If you are not interested in enabling SSL, remove the https entries.

     

    Wednesday, February 8, 2012 11:42 AM
  • According to the referenced post, I've changed my web.config file to the following:

    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
    
      <system.serviceModel>
        <diagnostics>
          <messageLogging logEntireMessage="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"/>
        </diagnostics>
        <behaviors>
          <serviceBehaviors>
            <behavior name="WCFServiceBehavior">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <customBinding >
            <binding name="customBinding0" closeTimeout="00:20:00" openTimeout="00:20:00" receiveTimeout="00:20:00" sendTimeout="00:20:00">
              <binaryMessageEncoding  maxReadPoolSize="2147483647" maxWritePoolSize="2147483647" maxSessionSize="2147483647">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
              </binaryMessageEncoding>
              <httpTransport maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" authenticationScheme="Negotiate" maxBufferSize="2147483647" transferMode="Buffered"/>
            </binding>
          </customBinding>
        </bindings>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
        <services>
          <service behaviorConfiguration="WCFServiceBehavior" name="SilverlightApplication2.Web.Service1">
            <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    

    ... and get the same exception :(

    Thursday, February 9, 2012 4:14 AM
  • IIS by default sets a limit on the max request size to 4096kb (4mb), see here:

    http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.maxrequestlength.aspx

    You can bump it up using the following in your web.config:

    <system.web>
       <httpRuntime maxRequestLength="40960" /> <!-- 40 mb -->
    </system.web>

     

    Thursday, February 9, 2012 8:22 AM
  • Same result, ... sorry :' (

    Thursday, February 9, 2012 8:36 AM
  • Try this after your binaryMessageEncoding:

    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />

    Thursday, February 9, 2012 9:55 AM
  • Try removing the mex end point:

    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

    Thursday, February 9, 2012 10:36 AM
  • I wouldn't think that would matter.  I think that is primarily used by the service to publish its interface.

    Thursday, February 9, 2012 11:17 AM
  • @mtiede : Already tried without success.

    @rjacobs : no change, still the same exception.

    Friday, February 10, 2012 6:12 AM
  • I don't think it will help, but, grasping at straws, I would move your logic OUT of the constructor.  Make a Loaded event handler and put all your code in there.  Maybe there is some sort of timing issues, because you certainly seem to have all the "size" parameters possible in the web.config.

    Friday, February 10, 2012 11:01 AM
  • I've created a Loaded event and place all the stuff in it, but I still have the same exception.

    no luck.

    Cry

    Tuesday, February 28, 2012 7:29 AM
  • I think the problem was I didn't update the service reference after changing my Web.config file.

    Moreover I noticed that I had to put the namespace in the service name and endpoint contract attributes.

    <services>
      <service behaviorConfiguration="WCFServiceBehavior" name="SilverlightApplication2.Web.Service1">
        <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1" />
      </service>
    </services>

    And now i can send huge data to my webservice.

    Thank you

    Friday, March 2, 2012 3:31 AM
  • How to know the data size that is being sent now? I have set the buffer sizes to maximum, but still I get timeout errors. I want to know how much is being sent. In terms of rows, I have 2700 rows with 10 columns - dates, small strings, integers.

    Monday, February 25, 2013 4:42 PM