كيف يمكنني استخراج الاستثناء الداخلي من استثناء الصابون في ASP.NET؟

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

سؤال

لدي عملية خدمة ويب بسيطة مثل هذه:

    [WebMethod]
    public string HelloWorld()
    {
        throw new Exception("HelloWorldException");
        return "Hello World";
    }

وبعد ذلك لدي تطبيق عميل يستهلك خدمة الويب ثم يستدعي العملية.من الواضح أنه سوف يطرح استثناء :-)

    try
    {
        hwservicens.Service1 service1 = new hwservicens.Service1();
        service1.HelloWorld();
    }
    catch(Exception e)
    {
        Console.WriteLine(e.ToString());
    }

في كتلة الالتقاط الخاصة بي، ما أود القيام به هو استخراج رسالة الاستثناء الفعلي لاستخدامها في الكود الخاص بي.الاستثناء الذي تم اكتشافه هو أ SoapException, ، وهو أمر جيد، لكنه كذلك Message الملكية هكذا...

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: HelloWorldException
   at WebService1.Service1.HelloWorld() in C:\svnroot\Vordur\WebService1\Service1.asmx.cs:line 27
   --- End of inner exception stack trace ---

...و ال InnerException يكون null.

ما أود القيام به هو استخراج Message ملكية InnerException (ال HelloWorldException النص في العينة الخاصة بي)، هل يمكن لأي شخص المساعدة في ذلك؟إذا كنت تستطيع تجنب ذلك، من فضلك لا تقترح تحليل Message ملكية SoapException.

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

المحلول

لسوء الحظ لا أعتقد أن هذا ممكن.

يتم تشفير الاستثناء الذي ترفعه في كود خدمة الويب الخاص بك إلى Soap Fault، والذي يتم بعد ذلك تمريره كسلسلة مرة أخرى إلى كود العميل الخاص بك.

ما تراه في رسالة SoapException هو ببساطة النص من خطأ Soap، والذي لم يتم تحويله مرة أخرى إلى استثناء، ولكن تم تخزينه كنص فقط.

إذا كنت تريد إرجاع معلومات مفيدة في حالات الخطأ، فإنني أوصي بإرجاع فئة مخصصة من خدمة الويب الخاصة بك والتي يمكن أن تحتوي على خاصية "خطأ" والتي تحتوي على معلوماتك.

[WebMethod]
public ResponseClass HelloWorld()
{
  ResponseClass c = new ResponseClass();
  try 
  {
    throw new Exception("Exception Text");
    // The following would be returned on a success
    c.WasError = false;
    c.ReturnValue = "Hello World";
  }
  catch(Exception e)
  {
    c.WasError = true;
    c.ErrorMessage = e.Message;
    return c;
  }
}

نصائح أخرى

هو - هي يكون ممكن!

مثال تشغيل الخدمة:

try
{
   // do something good for humanity
}
catch (Exception e)
{
   throw new SoapException(e.InnerException.Message,
                           SoapException.ServerFaultCode);
}

العميل المستهلك للخدمة:

try
{
   // save humanity
}
catch (Exception e)
{
   Console.WriteLine(e.Message);    
}

شيء واحد فقط - تحتاج إلى تعيين وضع customErrors='RemoteOnly' أو 'On' في ملف web.config الخاص بك (مشروع الخدمة).

الاعتمادات حول اكتشاف customErrors - http://forums.asp.net/t/236665.aspx/1

لقد واجهت شيئًا مشابهًا منذ قليل و تدوين حول هذا الموضوع.لست متأكدًا مما إذا كان ذلك قابلاً للتطبيق على وجه التحديد، ولكن قد يكون كذلك.يكون الرمز بسيطًا بدرجة كافية بمجرد أن تدرك أنه يتعين عليك المرور عبر كائن messageFault.في حالتي، كنت أعرف أن التفاصيل تحتوي على GUID يمكنني استخدامه لإعادة الاستعلام عن خدمة SOAP للحصول على التفاصيل.يبدو الرمز كما يلي:

catch (FaultException soapEx)
{
    MessageFault mf = soapEx.CreateMessageFault();
    if (mf.HasDetail)
    {
        XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
        Guid g = reader.ReadContentAsGuid();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top