WCF - تم تجاوز حصة عدد الأحرف القصوى (16384) أثناء قراءة بيانات XML

StackOverflow https://stackoverflow.com/questions/2765598

سؤال

لدي خدمة WCF التي تستخدم WSHTTPBINDING. تكوين الخادم كما يلي:

<bindings>
      <wsHttpBinding>
        <binding name="wsHttpBinding" maxBufferPoolSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="None">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

على جانب العميل ، أقوم بتضمين مرجع الخدمة لخدمة WCF. إنه يعمل بشكل رائع إذا كان لدي وظائف محدودة أن 90 عملية تشغيل في iservice الخاص بي ولكن إذا أضف عملية أخرى أكثر مما لا يمكنني تحديث مرجع الخدمة ولا يمكنني إضافة مرجع الخدمة هذا. في هذه تم الإشارة إلى أنه من خلال تغيير ملفات التكوين هذه (أي devenv.exe.config و wcftestclient.exe.config و svcutil.exe.config) ، ستعمل ولكن حتى بما في ذلك الروابط في ملفات التكوين هذه لا تزال هذه الخطأ تنبثق على قولها قائلاً

كان هناك خطأ تنزيلhttp://10.0.3.112/myservice/service1.svc/mex'. فشل الطلب مع حالة HTTP 400: طلب سيء. تحتوي البيانات الوصفية على مرجع لا يمكن حله: 'http://10.0.3.112/myservice/service1.svc/mex'. هناك خطأ في مستند XML (1 ، 89549). تم تجاوز أقصى حصة عدد الأحرف Nametable (16384) أثناء قراءة بيانات XML. Nametable هو بنية بيانات تستخدم لتخزين الأوتار التي تمت مواجهتها أثناء معالجة XML - مستندات XML الطويلة مع أسماء العناصر غير المتكررة ، وأسماء السمات وقيم السمات قد تؤدي إلى هذه الحصة. يمكن زيادة هذه الحصة عن طريق تغيير خاصية maxnametablecharcount على كائن xmldictionareReaderQuotas المستخدم عند إنشاء قارئ XML. السطر 1 ، الموضع 89549. إذا تم تعريف الخدمة في الحل الحالي ، فحاول إنشاء الحل وإضافة مرجع الخدمة مرة أخرى.

أي فكرة عن كيفية حل هذا ؟؟؟؟

هل كانت مفيدة؟

المحلول

حاول القيام بما يلي:

في دليل التثبيت الخاص بـ Visual Studio حيث يوجد Devenv.exe (على سبيل المثال C: Program Files Microsoft Visual Studio 9.0 Common7 IDE) أضف هذا القسم إلى devenv.exe.cofig

<system.serviceModel>
<client>
  <endpoint binding="customBinding" bindingConfiguration="largeServiceBinding" contract="IMetadataExchange" name="http" />
</client>

<bindings>
  <customBinding>
    <!-- NOTE: The binding name must be the same as specified in the config file of the wcf service -->
    <binding name="largeServiceBinding" >
      <textMessageEncoding>
        <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      </textMessageEncoding>

      <httpTransport transferMode="Buffered" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
    </binding>

  </customBinding>
</bindings>
</system.serviceModel>

في App.config من خدمة WCF الخاصة بك ، أضف نفس الربط:

<bindings>
  <customBinding >
    <!-- NOTE: The binding name must be the same as specified in the devenv.exe.config file located ..\Common7\IDE folder of the VS installation directory -->
    <binding name="largeServiceBinding" >
      <textMessageEncoding>
        <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647"
          maxNameTableCharCount="2147483647" />
      </textMessageEncoding>
      <httpTransport transferMode="Buffered" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
    </binding>
  </customBinding>
</bindings>

لاحظ أن سمة الاسم لعلامات الربط من الملفين يجب أن تتطابق (مثل largeserviceBinding)

أخيرًا ، أضف نقطة نهاية MEX التالية إلى علامة الخدمة الخاصة بك:

 <endpoint address="mex" binding="customBinding" contract="IMetadataExchange" bindingName="testBinding" bindingConfiguration="largeServiceBinding" name="http"/>

قد يبدو هذا هكذا:

 <services>
  <service behaviorConfiguration="MyServiceBehavior"
    name="MyService.MyService">
    <endpoint address="" binding="wsHttpBinding" contract="MyService.IMyService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="customBinding" contract="IMetadataExchange" bindingName="testBinding" bindingConfiguration="largeServiceBinding" name="http"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/Design_Time_Addresses/MyService/MyService/" />
      </baseAddresses>
    </host>
  </service>
</services>

نصائح أخرى

أعلم أن الأمر مرت فترة ، لكنني حصلت على نفس المشكلة ووجدت حلًا آخر (أبسط) في codeproject

في الحل المعطى هناك ، يتم تعيين القيم في الكود بدلاً من ملف .config.

        BasicHttpBinding binding = new BasicHttpBinding();
        binding.Security.Mode = BasicHttpSecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
        binding.MaxReceivedMessageSize = 50000000;
        binding.ReaderQuotas.MaxArrayLength = 50000000;
        binding.ReaderQuotas.MaxStringContentLength = 50000000;
        binding.ReaderQuotas.MaxNameTableCharCount = 50000000;
        EndpointAddress endpoint = new EndpointAddress(new Uri("https://server/EWS/Exchange.asmx"));
        ExchangeServicePortTypeClient ews = new ExchangeServicePortTypeClient(binding, endpoint);

ومع ذلك ، قمت بتغيير القيم في القيم ذات الصلة في ملف .config (في كل من <binding> و ال <readerQuotas> الأقسام) وحل المشكلة (بدلاً من إضافة روابط مخصصة):

                <binding name="ITransactionProcessor" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="50000000" maxBufferPoolSize="524288" maxReceivedMessageSize="50000000"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="50000000" maxArrayLength="50000000"
                        maxBytesPerRead="4096" maxNameTableCharCount="50000000" />
                    <security mode="TransportWithMessageCredential">
                        <transport clientCredentialType="None" proxyCredentialType="None" 
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>

آمل أن يساعد هذا شخص ما :)

شيء واحد يجب إدراكه هو أن الرسالة تشير إلى حصص قارئ SVCUTIL وليس تلك الخدمة! لدى Svcutil حدود على مقدار البيانات الوصفية التي يمكن أن تقرأها. يمكن تغيير هذا الحد باستخدام ملف التكوين. يتمثل الحل في إنشاء ملف تكوين لـ SVCUTIL ووضعه في نفس المجلد مثل الأداة. في المرة القادمة التي تقوم فيها بتشغيل SVCUTIL ، سيتم أخذ قيم ملفات التكوين في الاعتبار.

http://geekswithblogs.net/claraoscura/archive/2007/08/20/114806.aspx

في app.config أو dll.config على إضافة العميل:

<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="myMex" maxReceivedMessageSize="1024000"> <!-- modify this to avoid stupid error -->
<readerQuotas maxNameTableCharCount="163840" /> <!-- DO NOT touch this one -->
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>

...

<client>
<endpoint binding="netTcpBinding" bindingConfiguration="myMex"
contract="IMetadataExchange" name="net.tcp" />

...

        </client>
    </system.serviceModel>
</configuration>

وهناك تذهب! هذه واحدة من الأشياء المزعجة حقًا مع WCF ، وغالبًا ما تعطيك Google الكثير من BS. يضيع الكثير من الوقت مع هذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top