เปิด IncludeExceptionDetailInFaults (จาก ServiceBehaviorAttribute หรือจากพฤติกรรมการกำหนดค่า <serviceDebug>) บนเซิร์ฟเวอร์


157

ฉันมีบริการ WCF ที่ทำงานได้อย่างสมบูรณ์และมีบางอย่างเปลี่ยนไปและฉันไม่รู้ว่าอะไร

ฉันได้รับข้อยกเว้นนี้:

System.ServiceModel.FaultException: เซิร์ฟเวอร์ไม่สามารถดำเนินการตามคำขอเนื่องจากข้อผิดพลาดภายใน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดเปิดใช้งาน IncludeExceptionDetailInFaults (จาก ServiceBehaviorAttribute หรือจากพฤติกรรมการกำหนดค่า) บนเซิร์ฟเวอร์เพื่อส่งข้อมูลข้อยกเว้นกลับไปยังไคลเอนต์หรือเปิดการสืบค้นกลับตามเอกสารประกอบของ Microsoft .NET Framework 3.0 SDK และตรวจสอบบันทึกการติดตามเซิร์ฟเวอร์

สิ่งนี้สับสนเพราะฉันใช้. NET 4.0

ฉันจะเปิดIncludeExceptionDetailInFaultsที่ไหน ฉันต่อสู้เพื่อค้นหามัน

คำตอบ:


265

กำหนดพฤติกรรมใน.configไฟล์ของคุณ:

<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="debug">
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    ...
  </system.serviceModel>
</configuration>

จากนั้นนำพฤติกรรมไปใช้กับบริการของคุณตามบรรทัดเหล่านี้:

<configuration>
  <system.serviceModel>
    ...
    <services>
      <service name="MyServiceName" behaviorConfiguration="debug" />
    </services>
  </system.serviceModel>
</configuration>

นอกจากนี้คุณยังสามารถตั้งค่าโดยทางโปรแกรม ดูคำถามนี้


1
สวัสดี Otivel ฉันเป็นกรณีของฉันมีโฟลเดอร์ซ้อนกันที่มีเว็บไซต์และบริการที่แตกต่างกัน โฟลเดอร์ที่บริการของฉันอยู่และฉันได้รับข้อผิดพลาดอยู่ในระดับที่สามของการซ้อนที่สัมพันธ์กับเว็บแอปพลิเคชันหลักและฉันมี web.config เฉพาะสำหรับแต่ละบริการ ฉันเปลี่ยน web.config ที่สอดคล้องกันของฉันเพื่อเพิ่ม <serviceDebug includeExceptionDetailInFaults = "true" /> แต่ฉันยังคงได้รับข้อผิดพลาด ฉันจำเป็นต้องเปลี่ยน web.config ทั้งหมดในแอปพลิเคชันเว็บที่สมบูรณ์หรือไม่
MaxRecursion

2
@AkshayKulkarni: ไม่แน่ใจว่าฉันไม่มีประสบการณ์กับเคสของคุณ ตรวจสอบให้แน่ใจว่าบริการของคุณมีการอ้างอิงถึง serviceBehavior (ตรวจสอบคำตอบgagogra ) ก่อน หากยังไม่สามารถแก้ปัญหาได้โปรดถามคำถามเกี่ยวกับ SO
Otiel

1
@ MatthewLock: คำตอบที่ปรับปรุงแล้ว นอกจากนี้ให้ตรวจสอบ<behavior>และ<service>หากคุณต้องการรายละเอียดเพิ่มเติม
Otiel

1
Visual Studio บอกฉันว่าบริการพฤติกรรมไม่สามารถเป็นลูกโดยตรงของ system.serviceModel ลงเอยด้วยคำตอบของ rich.okelly
andrewb

3
หมายเหตุ: VS2013 วางแท็ก <serviceDebug> ใน Web.config เริ่มต้นโดยตั้งเป็น false หากคุณไม่ได้สังเกตเห็นว่าฉันไม่ได้และเพิ่ม XML ข้างต้นเห็นได้ชัดว่าสิ่งที่อยู่ในที่สุดในไฟล์ชนะ หวังว่านี่จะเป็นประโยชน์กับใครบางคนที่นั่น
Jeff

63

มันอยู่ในไฟล์ app.config

<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceDebug includeExceptionDetailInFaults="true"/>

9
อย่าตั้งชื่อแอตทริบิวต์ของ <behavior> (ใน @Otiel answer) หากคุณต้องการให้มันใช้กับบริการทั้งหมดของคุณ
Pashec

47

หากคุณต้องการทำสิ่งนี้ด้วยรหัสคุณสามารถเพิ่มพฤติกรรมเช่นนี้:

serviceHost.Description.Behaviors.Remove(
    typeof(ServiceDebugBehavior));
serviceHost.Description.Behaviors.Add(
    new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });

เพิ่มลงในServiceHostอินสแตนซ์วัตถุของคุณ: ตัวอย่าง:ServiceHost serviceHost = new ServiceHost(Program.serviceInstance);
Daniel Bonetti

28

นอกจากนี้คุณยังสามารถตั้งค่าในแท็ก [ServiceBehavior] เหนือประกาศคลาสของคุณที่สืบทอดอินเทอร์เฟซ

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class MyClass:IMyService
{
...
}

Immortal Blue นั้นถูกต้องในการไม่เปิดเผยรายละเอียดที่ถูกต้องของรุ่นที่เผยแพร่สู่สาธารณะ แต่สำหรับวัตถุประสงค์ในการทดสอบนี่เป็นเครื่องมือที่มีประโยชน์ ปิดสวิตช์ทุกครั้งเมื่อปล่อย


ฉันใช้สิ่งนี้ในแอปพลิเคชันที่ทำงานบนแบ็กเอนด์และจะไม่สามารถดูได้แบบสาธารณะดังนั้นจึงใช้งานได้อย่างสมบูรณ์แบบ
AlbatrossCafe

4

ฉันยังได้รับข้อผิดพลาดเดียวกัน WCF ทำงานอย่างถูกต้องสำหรับฉันเมื่อฉันใช้ใน Dev Environment ด้วยข้อมูลประจำตัวของฉัน แต่เมื่อมีคนอื่นใช้ใน TEST มันก็โยนข้อผิดพลาดเดียวกัน ฉันทำการวิจัยจำนวนมากและจากนั้นแทนที่จะทำการอัปเดตการตั้งค่าจัดการข้อยกเว้นในวิธีการ WCF ด้วยความช่วยเหลือของการยกเว้นข้อผิดพลาด นอกจากนี้ข้อมูลประจำตัวสำหรับ WCF จะต้องตั้งค่าด้วยข้อมูลประจำตัวเดียวกันซึ่งมีการเข้าถึงในฐานข้อมูลบางคนอาจมีการเปลี่ยนแปลงสิทธิ์ของคุณ กรุณาค้นหารหัสด้านล่างสำหรับเดียวกัน:

 [ServiceContract]
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(ServiceData))]
    ForDataset GetCCDBdata();

    [OperationContract]
    [FaultContract(typeof(ServiceData))]
    string GetCCDBdataasXMLstring();


    //[OperationContract]
    //string GetData(int value);

    //[OperationContract]
    //CompositeType GetDataUsingDataContract(CompositeType composite);

    // TODO: Add your service operations here
}

  [DataContract]
public class ServiceData
{
    [DataMember]
    public bool Result { get; set; }
    [DataMember]
    public string ErrorMessage { get; set; }
    [DataMember]
    public string ErrorDetails { get; set; }
}

ใน service1.svc.cs ของคุณคุณสามารถใช้สิ่งนี้ใน catch block:

 catch (Exception ex)
        {
            myServiceData.Result = false;
            myServiceData.ErrorMessage = "unforeseen error occured. Please try later.";
            myServiceData.ErrorDetails = ex.ToString();
            throw new FaultException<ServiceData>(myServiceData, ex.ToString());
        }

และใช้สิ่งนี้ในแอปพลิเคชันไคลเอนต์เช่นรหัสด้านล่าง:

  ConsoleApplicationWCFClient.CCDB_HIG_service.ForDataset ds = obj.GetCCDBdata();

            string str = obj.GetCCDBdataasXMLstring();

        }

        catch (FaultException<ConsoleApplicationWCFClient.CCDB_HIG_service.ServiceData> Fex)
      {
          Console.WriteLine("ErrorMessage::" + Fex.Detail.ErrorMessage + Environment.NewLine);
          Console.WriteLine("ErrorDetails::" + Environment.NewLine + Fex.Detail.ErrorDetails);
          Console.ReadLine();
      }

ลองใช้วิธีนี้มันจะช่วยให้ได้รับปัญหาที่แน่นอน


4
คุณไม่ควรเปิดเผยรายละเอียดข้อยกเว้นพื้นฐาน วัตถุประสงค์ทั้งหมดสำหรับการแยกข้อยกเว้นระหว่างไคลเอนต์และเซิร์ฟเวอร์และความต้องการแฟล็กนี้เลยคือการป้องกันข้อมูลข้อยกเว้นที่มีให้กับลูกค้า ผู้ใช้ที่เป็นอันตรายสามารถใช้ข้อมูลนี้เพื่อจัดการบริการของคุณ! หากคุณกำลังพัฒนาให้ใช้พฤติกรรม IncludeExceptionDetailInFaults ตามที่อธิบายไว้เพื่อเผยแพร่ข้อยกเว้นทั้งหมดหรือในการปรับใช้ยกข้อผิดพลาดที่ให้ข้อผิดพลาดพื้นฐานมากเช่น "ไม่สามารถบันทึกไฟล์" แทนที่จะให้สแต็กติดตามและรายละเอียดทั้งหมดของ ข้อยกเว้น
Immortal Blue

สวัสดี .. ในกรณีของฉันฟังก์ชั่นบริการอื่น ๆ ทั้งหมดจะถูกเรียกใช้โดยฟังก์ชั่นที่ฉันใช้เพื่อบันทึกไฟล์กำลังโยนข้อยกเว้นนั้น ... เพื่อทราบปัญหาที่แน่นอนฉันใช้ระบบการบันทึก แต่ไม่มีการสร้างบันทึกสำหรับวิธีการนั้น ... ฉันกำลังสร้าง 3 บันทึก 1) เมื่อบริการกด 2) ก่อนบันทึกไฟล์ใด ๆ และ 3) บันทึกข้อยกเว้น
user3217843

0

ตามข้อมูลข้อผิดพลาดที่กล่าวก่อนโปรดลองเพิ่มค่าการหมดเวลาในทั้งฝั่งไคลเอ็นต์และฝั่งบริการดังต่อไปนี้:

<basicHttpBinding>
    <binding name="basicHttpBinding_ACRMS" maxBufferSize="2147483647"
      maxReceivedMessageSize="2147483647"
      openTimeout="00:20:00" 
      receiveTimeout="00:20:00" closeTimeout="00:20:00"
      sendTimeout="00:20:00">
      <readerQuotas maxDepth="32" maxStringContentLength="2097152"
        maxArrayLength="2097152" maxBytesPerRead="4006" maxNameTableCharCount="16384" />
    </binding>

จากนั้นโปรดอย่าลืมใช้การกำหนดค่าการเชื่อมโยงนี้กับจุดปลายโดยทำสิ่งต่อไปนี้:

<endpoint address="" binding="basicHttpBinding" 
      bindingConfiguration="basicHttpBinding_ACRMS"
      contract="MonitorRAM.IService1" />

ถ้าข้างต้นไม่สามารถช่วยได้มันจะดีกว่าถ้าคุณสามารถลองอัปโหลดโครงการหลักของคุณที่นี่จากนั้นฉันต้องการทดสอบด้านข้างของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.