2011-11-29 4 views
135

Tôi có dịch vụ WCF hoạt động hoàn hảo, và một cái gì đó đã thay đổi và tôi không biết gì.Bật IncludeExceptionDetailInFaults (hoặc từ ServiceBehaviorAttribute hoặc từ hành vi cấu hình <serviceDebug>) trên máy chủ

tôi nhận được ngoại lệ này:

System.ServiceModel.FaultException: Các máy chủ đã không thể xử lý yêu cầu do lỗi nội bộ. Để biết thêm thông tin về lỗi, hoặc bật IncludeExceptionDetailInFaults (hoặc từ ServiceBehaviorAttribute hoặc từ hành vi cấu hình) trên máy chủ để gửi thông tin ngoại lệ trở lại máy khách hoặc bật truy tìm theo tài liệu Microsoft .NET Framework 3.0 SDK và kiểm tra nhật ký theo dõi máy chủ.

Điều này gây nhầm lẫn vì tôi đang chạy .NET 4.0.

Tôi có thể bật số IncludeExceptionDetailInFaults ở đâu? Tôi đang chiến đấu để tìm nó.

Trả lời

226

Xác định một behavior trong tập tin .config của bạn:

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

Sau đó áp dụng hành vi sử dụng dịch vụ của bạn cùng những dòng này:

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

Bạn cũng có thể thiết lập nó lập trình. Xem this question.

+1

Hi Otivel, trường hợp của tôi có các thư mục lồng nhau chứa các trang web và dịch vụ khác nhau. Các thư mục mà dịch vụ của tôi cư trú và tôi nhận được lỗi là ở mức độ thứ ba làm tổ tương đối so với ứng dụng web chính và tôi đã dành riêng web.config cho mỗi dịch vụ. Tôi thay đổi web.config tương ứng của mình để thêm . Nhưng tôi vẫn nhận được lỗi. Tôi có cần thay đổi tất cả web.config trong ứng dụng web hoàn chỉnh không? – MaxRecursion

+2

@AkshayKulkarni: Không chắc chắn, tôi không có kinh nghiệm về trường hợp của bạn. Đảm bảo các dịch vụ của bạn có tham chiếu đến dịch vụBehavior (kiểm tra ** gagogra ** answer) trước tiên. Nếu điều đó không giải quyết được vấn đề, vui lòng đặt câu hỏi trên SO. – Otiel

+0

Xin chào, bạn có thể đặt toàn bộ cây để chúng tôi biết nơi đặt những đoạn XML này không? –

56

Nó nằm trong tệp app.config.

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

Không đặt thuộc tính tên là (như trong câu trả lời @Otiel) nếu bạn muốn áp dụng cho tất cả các dịch vụ của mình. – Pashec

4

Tôi cũng nhận được lỗi tương tự, WCF hoạt động bình thường cho tôi khi tôi đang sử dụng nó trong môi trường Dev với thông tin đăng nhập của tôi, nhưng khi ai đó đang sử dụng nó trong TEST, nó đã ném cùng một lỗi. Tôi đã làm rất nhiều nghiên cứu, và sau đó thay vì làm cập nhật cấu hình, xử lý một ngoại lệ trong phương pháp WCF với sự giúp đỡ của lỗi ngoại lệ. Ngoài ra, danh tính cho WCF cần phải được đặt cùng với thông tin xác thực có quyền truy cập trong cơ sở dữ liệu, ai đó có thể đã thay đổi thẩm quyền của bạn. Vui lòng xem dưới mã cho giống nhau:

[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; } 
} 

trong service1.svc.cs của bạn, bạn có thể sử dụng trong khối catch:

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()); 
     } 

Và sử dụng này trong ứng dụng khách hàng như mã dưới đây :

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(); 
     } 

Chỉ cần thử điều này, nó sẽ giúp đảm bảo để có được vấn đề chính xác.

+3

Bạn KHÔNG nên để lộ các chi tiết ngoại lệ cơ bản. Toàn bộ mục đích cho việc tách biệt các ngoại lệ giữa máy khách và máy chủ và sự cần thiết cho cờ này, là để ngăn chặn thông tin ngoại lệ được cung cấp cho khách hàng. Một người dùng độc hại có thể sử dụng thông tin này để thao tác dịch vụ của bạn! Nếu bạn đang phát triển, hãy sử dụng hành vi IncludeExceptionDetailInFaults như được mô tả để tuyên truyền toàn bộ ngoại lệ hoặc trong triển khai, tăng lỗi khi đưa ra một lỗi rất cơ bản, chẳng hạn như "Không thể lưu tệp" thay vì cung cấp dấu vết ngăn xếp và chi tiết đầy đủ của ngoại lệ. –

+0

Xin chào .. trong trường hợp của tôi, tất cả các chức năng dịch vụ khác được gọi bằng hàm mà im sử dụng để lưu tệp đang ném ngoại lệ đó ... để biết chính xác vấn đề tôi đã sử dụng hệ thống ghi nhật ký nhưng không có nhật ký nào được tạo cho phương thức đó. .im tạo 3 bản ghi 1) khi dịch vụ đạt 2) trước khi lưu bất kỳ tệp nào và 3) nhật ký ngoại lệ. – user3217843

35

Nếu bạn muốn làm điều này bằng mã, bạn có thể thêm các hành vi như thế này:

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

Tôi viết mã này ở đâu? –

+0

Thêm trường hợp này vào đối tượng 'ServiceHost' của bạn: Ví dụ:' ServiceHost serviceHost = new ServiceHost (Program.serviceInstance); ' –

17

Bạn cũng có thể thiết lập nó trong [ServiceBehavior] tag trên khai báo lớp của bạn mà được thừa hưởng giao diện

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

Bất tử xanh là chính xác khi không tiết lộ chi tiết ngoại lệ cho phiên bản được phát hành công khai, nhưng với mục đích thử nghiệm, đây là một công cụ hữu ích. Luôn tắt khi phát hành.

+0

Tôi đã sử dụng ứng dụng này chạy trên chương trình phụ trợ và sẽ không bao giờ được hiển thị công khai. – AlbatrossCafe

0

Như thông tin báo lỗi nói đầu tiên hãy cố gắng tăng giá trị timeout trong cả hai phía khách hàng và dịch vụ phụ như sau:

<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> 

Sau đó, hãy làm không quên áp dụng cấu hình ràng buộc này cho điểm cuối bằng cách thực hiện như sau:

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

Nếu ở trên không thể giúp đỡ, sẽ tốt hơn nếu bạn có thể thử tải lên dự án chính của mình tại đây, sau đó tôi muốn thử nghiệm bên cạnh.