مسافات اسم متعددة في رسالة خطأ الصابون تسبب FaultException إلغاء التسلسل الفشل

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

سؤال

ونحن ربط لخدمة الويب ورسالة خطأ يمكننا العودة لا deserializing (على الإطلاق)، وليس نسخة من الطبقة أستطيع أن تجعل سوف إلغاء تسلسل بشكل صحيح. ليست لدينا سيطرة على الخادم الجانب من الأمور. الملقم لا تسمح للاكتشاف، مضيفا بذلك؟ WSDL إلى نهاية URL من نتائج نقطة النهاية في خطأ، وليس WSDL.

[عازف الكمان] [1] يظهر رسالة خطأ يعود تبدو مثل:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:eGov="http://eGov.gov" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <soapenv:Fault>
    <faultcode>Client</faultcode>
    <faultstring/>
      <detail>
        <eGov:eGov2Exception>
          <eGov:ErrorClassification>SOME_ERROR</eGov:ErrorClassification>
          <eGov:ErrorCode>SOME_ERROR_CODE</eGov:ErrorCode>
          <eGov:ErrorMessage>Your request was unsuccessful. blah blah blah.</eGov:ErrorMessage>
        </eGov:eGov2Exception>
      </detail>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>

ولكن لا فئة التي قمنا بها (تحاول xsd.exe، svcutil وغيرها بما في ذلك رمز لدينا كتب من الصفر) يمكن إلغاء تسلسل عندما نحاول أن قبض عليه مع:

catch (FaultException<eGov2ExceptionType> exp)
  {
     // Never stops here. 
  }
catch (FaultException<AllOtherAttemptedClasses> exp)
  {
     // Never stops here. 
  }
catch (SoapException se)
  {
     // Never stops here. 
  }
catch (FaultException exp)
  {
     //Always gets caught here. 
  }

وفقط الصيد قاعدة FaultException سوف الحصول على استدعاء، وهذا يعني أننا تفقد محتويات FaultMessage إرسالها. بعض الطبقات لقد كتبت وتسلسل حقا ارتباطا وثيقا العينة أعلاه، لكنه يفشل في إلغاء تسلسل، لذلك لدينا الشك هو أن هناك قضية مساحة الاسم.

والأسئلة:

1 - كيف تكتب هذه

2 - هل هذا خطأ / قضية مشتركة مع WCF

[1]: http://www.fiddler2.com/fiddler2/ عازف الكمان

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

المحلول

وماذا نحن انتهى به هو التخلي عن محاولة للقبض على خطأ وتمريرها مرة أخرى في قناة SOAP. بدلا من ذلك، أنشأنا استثناء مخصصة، والسلكية حتى MessageInspector لمراقبة الأخطاء ورميها على سبيل الاستثناء.

والجزء ذي الصلة من رمز (مطهرة):

   public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        if (reply.IsFault)
        {
            XmlDictionaryReader xdr = reply.GetReaderAtBodyContents();
            XNode xn = XDocument.ReadFrom(xdr);
            string s = xn.ToString();
            XDocument xd = XDocument.Parse(s);
            XNamespace nsSoap = "http://schemas.xmlsoap.org/soap/envelope/";
            XNamespace ns = "http://eGov.gov";
            XElement xErrorClass = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorClassification");
            XElement xErrorCode = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorCode");
            XElement xErrorMessage = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorMessage");

            throw new eGovException(xErrorClass.Value, xErrorCode.Value, xErrorMessage.Value);
        }
    }

وبعد ذلك يستخدم التطبيق الرئيسي:

والصيد (على سبيل المثال eGovException)
  {
    // مقابض استثناء هنا.
  }

وكان يضيع الكثير الكثير من الوقت في محاولة لتصحيح مسافات اسم. شكرا لإجابة هذا السؤال.

نصائح أخرى

وطريقة واحدة للتعامل مع هذا إذا التسلسل فشل تماما هو استخدام OoperationContract استخدام في نوع الرسالة كما المدخلات والمخرجات. وبهذه الطريقة يمكنك تحليل يدويا XML عندما == Iffault صحيح أو استخدام GetBody () للحصول على محتويات العادية إذا حدث أي خطأ.

وأولا وقبل كل شيء، إذا لم تتمكن من الحصول على WSDL من الناس الذين أنتجوا هذه الخدمة على شبكة الإنترنت، ثم ليس لديهم رجال الأعمال لديهم خدمة ويب تستند إلى SOAP. ومن شأن WSDL السليم حل مشكلتك، أم لا "WSDL؟" يستخدم.

وثانيا، يرجى الرد على رمز الطبقة eGov2ExceptionType. وأظن أنه ليس لديه مساحة الاسم http://eGov.gov تعيين على ذلك.

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