dcsimg
Results 1 to 9 of 9

Thread: Webservice needs to return a large string

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Webservice needs to return a large string

    Hi,

    I am building a webservice that reads some HTML source code from a website and sends it back to the client. The service however is failing to send the data because it is too large. I keep getting this error:
    The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://nickthissen.nl/iracingforum/:...umListResponse. The InnerException message was 'There was an error deserializing the object of type iRacingForumServiceTest.ForumService.GetForumListResponseBody. 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. Line 153, position 247.'. Please see InnerException for more details.
    I have been googling this problem for ages and I cannot figure out how to apply the answers I keep finding.

    The problem is simple: the default configuration doesn't allow such large strings. I just don't know how to change this. All I keep finding is things related to WCF, I'm not sure if that applies for me.

    What I keep finding is that I need to change the web.config file in various ways. However I cannot figure out where I need to put the config sections. I've tried everything but without a complete web.config file example I can't get it to work


    Here is my current web.config of the server:
    Code:
    <?xml version="1.0"?>
    <configuration>
      
        <configSections>
        </configSections>
        <connectionStrings/>
        <system.web>
          
            <compilation debug="true" >
              <assemblies>
                <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
                <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
                <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
              </assemblies>
            </compilation>
        <!--
          The <authentication> section enables configuration 
          of the security authentication mode used by 
          ASP.NET to identify an incoming user. 
        -->
        <authentication mode="Windows" />
        <!--
           The <customErrors> section enables configuration 
           of what to do if/when an unhandled error occurs 
           during the execution of a request. Specifically, 
           it enables developers to configure html error pages 
           to be displayed in place of a error stack trace.
    
           <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
             <error statusCode="403" redirect="NoAccess.htm" />
             <error statusCode="404" redirect="FileNotFound.htm" />
           </customErrors>
        -->
          <pages>
            <controls>
              <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
              <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            </controls>
          </pages>
    
          <httpHandlers>
            
            <remove verb="*" path="*.asmx"/>
            <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
          </httpHandlers>
          <httpModules>
            <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          </httpModules>
        </system.web>
        <system.codedom>
          <compilers>
            <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
                      type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
              <providerOption name="CompilerVersion" value="v3.5"/>
              <providerOption name="WarnAsError" value="false"/>
            </compiler>
          </compilers>
        </system.codedom>
        <!-- 
            The system.webServer section is required for running ASP.NET AJAX under Internet
            Information Services 7.0.  It is not necessary for previous version of IIS.
        -->
    
    
      
        <system.webServer>
          
          <validation validateIntegratedModeConfiguration="false"/>
          <modules>
            <remove name="ScriptModule" />
            <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          </modules>
          <handlers>
            <remove name="WebServiceHandlerFactory-Integrated"/>
            <remove name="ScriptHandlerFactory" />
            <remove name="ScriptHandlerFactoryAppServices" />
            <remove name="ScriptResource" />
            <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
                 type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
                 type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </handlers>
        </system.webServer>
        <runtime>
          <assemblyBinding appliesTo="v2.0.50727" xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
              <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
              <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
            </dependentAssembly>
            <dependentAssembly>
              <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
              <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
            </dependentAssembly>
          </assemblyBinding>
          
          
        </runtime>
      
    
    </configuration>
    I found this piece to add to it:
    Code:
      <system.serviceModel>
        <services>
          <service name="ForumService">
            <endpoint address=""
                      binding="basicHttpBinding"
                      bindingConfiguration="basicHttpBinding_ISRV">
            </endpoint>
          </service>
        </services>
    
        <bindings>
          <basicHttpBinding>
            <binding name="basicHttpBinding_ISRV" maxReceivedMessageSize="2147483647">
              <readerQuotas maxStringContentLength="1310720"
                            maxArrayLength="16384"
                            maxBytesPerRead="24096"
                            maxDepth="10000"
                            maxNameTableCharCount="16384"/>
            </binding>
          </basicHttpBinding>
        </bindings>
      </system.serviceModel>
    I figured out where to put it without getting errors (just as a child of the <configuration> element), but it just doesn't work. I get the same error no matter what values I try here...



    This shouldn't be such a difficult issue, how can I solve it?

  2. #2
    Frenzied Member
    Join Date
    Jan 2006
    Posts
    1,875

    Re: Webservice needs to return a large string

    seems like you have have already tried all possible solution....just give one more shot by adding
    <httpRuntime maxRequestLength="9999999" /> attribute in <system.web> section

    reference
    __________________
    Rate the posts that helped you

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Webservice needs to return a large string

    Thanks, but I already tried that too.


    I just saw what I'm doing wrong... Seems stupid but it doesn't seem to be explained anywhere lol. I was trying to edit the web.config of the webservice. What I actually need to do is edit the app.config file in the client that has the service reference it seems. All the config sections are already there and I just need to edit the values...

    I got it working for now, I'm just wondering if it will also work for other (non .NET) clients later. The idea is that an Android app (java) is going to consume this service. Oh well, I'll see that once I get to it I guess...

  4. #4
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,966

    Re: Webservice needs to return a large string

    Hello,

    Yes, this is a well known "gotcha" with these things. The transit settings have to be the same in both the client and the server, in order for it to work.

    I can't tell you the number of times that this has caught me out.

    One application that is a must in these situations is the SvcConfigEditor.exe:

    http://msdn.microsoft.com/en-us/library/ms732009.aspx

    You can point it at either the server or the client, to get information on exactly what settings are being used.

    Gary

  5. #5

  6. #6
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,966

    Re: Webservice needs to return a large string

    Quote Originally Posted by NickThissen View Post
    That seems really useful, thanks.
    Not a problem. A colleague at work told me about it. Now, along with with the WcfTestClient:

    http://msdn.microsoft.com/en-us/library/bb552364.aspx

    They are permanently located on my desktop for when I need to use them

    Gary

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Webservice needs to return a large string

    Again, really useful... Thanks!! Is it just for WCF though or can I test the "regular" asmx file webservices too? I really don't have a clue what the difference is actually :/

  8. #8
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,966

    Re: Webservice needs to return a large string

    Hmm, good question

    Normally I have always used soapUI for testing straight up web services (asmx), but in theory, the TestClient is simply creating a proxy class based on the WSDL definition, so there is no reason it shouldn't work.

    I have just tested this by pointing the TestClient at:

    http://www.webservicex.com/globalweather.asmx?WSDL

    And it works! So the answer to your question is yes.

    As for the differences, that is a long one.

    WCF, or Windows Communication Foundation, which was created as a direct replacement for Web Services. From the ground up, it has things like security baked in, which is something that straight up web services didn't, and you needed things to WSE to add this. Depending on who you listen to WCF does a lot of stuff "wrong", but the same can be said for lots of things.

    Each to their own. I have always found it to do a decent job.

    Gary

  9. #9
    Learning .Net danasegarane's Avatar
    Join Date
    Aug 2004
    Location
    VBForums
    Posts
    5,834

    Re: Webservice needs to return a large string

    From here

    To compress the WCF data transfered over the wire, Microsoft Samples contains a GZipEncoder. This encoder wraps TextMessagingEncoder applying GZip Compression on top of it (N.B. you can even wrap a Binary Encoder to enable compression on Images for instance).

    But as you try to transfer a large object using GZipEncoder, you will run into the below error asking to increase maximum string length content:

    Unhandled Exception: System.ServiceModel.CommunicationException: Error in deserializing body of reply message for operation ‘GetData’. 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. Line 192, position 30. — System.Xml.XmlException: 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.

    This can look quite confusing if you are not familiar with how WCF Channel pipeline works. This error is encountered by many even if you are not using GZipEncoder outlined above. So let’s look at all solutions while using & not using GzipEncoder (below I set the limit to max allowed, though it’s not recommended) :

    1) Standard Binding (No GZipEncoder)
    <bindings>
    <basicHttpBinding>
    <binding>
    <readerQuotas maxStringContentLength=”2147483647″/>
    </binding>
    </basicHttpBinding>
    </bindings>
    //new BasicHttpBinding().ReaderQuotas.MaxStringContentLength = Int32.MaxValue
    N.B. Binding is a collection of channels providing an abstract way to add readerQuotas.

    2) Custom Binding (No GZipEncoder)
    <bindings>
    <customBinding>
    <binding>
    <textMessageEncoding>
    <readerQuotas maxStringContentLength=”2147483647″/>
    </textMessageEncoding>
    <httpTransport />
    </binding>
    </customBinding>
    </bindings>

    /*
    CustomBinding binding = new CustomBinding();
    TextMessageEncodingBindingElement element = new TextMessageEncodingBindingElement();
    element.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
    binding.Elements.Add(element);

    */
    N.B. For CustomBinding you need to select channels manually and for encoding channel you can specify the readerQuotas.

    3) Using GZipEncoder – in this case you need to add couple of lines in GZipMessageEncodingBindingElement class (GZipMessageEncodingBindingElement.cs file). The method which you would change is below:

    public override IChannelFactory BuildChannelFactory (BindingContext context)
    {
    if (context == null)
    throw new ArgumentNullException(“context”);
    context.BindingParameters.Add(this);

    var property = GetProperty<XmlDictionaryReaderQuotas>(context);
    property.MaxStringContentLength = 2147483647; //Int32.MaxValue
    property.MaxArrayLength = 2147483647;
    property.MaxBytesPerRead = 2147483647;

    return context.BuildInnerChannelFactory();
    }
    Please mark you thread resolved using the Thread Tools as shown



    www.techreceipe.tk


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width