Active IncludeExceptionDetailInFaults (ya sea desde ServiceBehaviorAttribute o desde el comportamiento de configuración <serviceDebug>) en el servidor

157

Tengo un servicio WCF que ha estado funcionando perfectamente, y algo ha cambiado y no sé qué.

Me sale esta excepción:

System.ServiceModel.FaultException: el servidor no pudo procesar la solicitud debido a un error interno. Para obtener más información sobre el error, active IncludeExceptionDetailInFaults (desde ServiceBehaviorAttribute o desde el comportamiento de configuración) en el servidor para enviar la información de excepción al cliente, o active el seguimiento según la documentación del SDK de Microsoft .NET Framework 3.0 e inspeccionar los registros de rastreo del servidor.

Esto es confuso porque estoy ejecutando .NET 4.0.

¿Dónde enciendo IncludeExceptionDetailInFaults? Estoy luchando por encontrarlo.

Trevor
fuente

Respuestas:

265

Defina un comportamiento en su .configarchivo:

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

Luego aplique el comportamiento a su servicio a lo largo de estas líneas:

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

También puede configurarlo mediante programación. Ver esta pregunta .

Otiel
fuente
1
Hola Otivel, en mi caso hay carpetas anidadas que contienen diferentes sitios y servicios. La carpeta donde reside mi servicio y obtengo un error está en el tercer grado de anidamiento en relación con la aplicación web principal y he dedicado web.config para cada servicio. Cambio mi correspondiente web.config en consecuencia para agregar <serviceDebug includeExceptionDetailInFaults = "true" />. Pero todavía recibo el error. ¿Necesito cambiar todo el web.config en la aplicación web completa?
MaxRecursion
2
@AkshayKulkarni: No estoy seguro, no tengo experiencia con su caso. Asegúrese de que sus servicios tengan una referencia al servicio Comportamiento (verifique la respuesta de gagogra ) primero. Si eso no resuelve el problema, haga una pregunta sobre SO.
Otiel
1
@MatthewLock: respuesta actualizada. Además, marque <comportamiento> y <servicio> si necesita más detalles.
Otiel
1
Visual Studio me dice que serviceBehaviors no puede ser un hijo directo de system.serviceModel. Terminé yendo con la respuesta de rich.okelly.
andrewb
3
Nota: VS2013 coloca la etiqueta <serviceDebug> en el Web.config predeterminado con el valor falso. Si no se da cuenta de que no lo hice y agrega el XML anterior, aparentemente lo que está en el último en el archivo gana. Espero que esto sea útil para alguien por ahí.
Jeff
63

Está en el archivo app.config.

<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceDebug includeExceptionDetailInFaults="true"/>
Rich O'Kelly
fuente
9
No establezca el atributo de nombre de <comportamiento> (como en @Otiel answer) si desea que se aplique a todos sus servicios.
Pashec
47

Si desea hacer esto por código, puede agregar el comportamiento de esta manera:

serviceHost.Description.Behaviors.Remove(
    typeof(ServiceDebugBehavior));
serviceHost.Description.Behaviors.Add(
    new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
Yang Zhang
fuente
Agregue esto a su ServiceHostinstancia de objeto: Ejemplo:ServiceHost serviceHost = new ServiceHost(Program.serviceInstance);
Daniel Bonetti
28

También puede configurarlo en la etiqueta [ServiceBehavior] sobre su declaración de clase que hereda la interfaz

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

Immortal Blue es correcto al no revelar los detalles de la excepción a una versión lanzada públicamente, pero para fines de prueba esta es una herramienta útil. Siempre apague al soltar.

LievenV
fuente
Utilicé esto en una aplicación que se ejecuta en el backend y nunca será visible públicamente, por lo que funciona perfectamente
AlbatrossCafe
4

También recibí el mismo error, el WCF funcionaba correctamente para mí cuando lo estaba usando en el entorno de desarrollo con mis credenciales, pero cuando alguien más lo estaba usando en TEST, arrojaba el mismo error. Investigué mucho y luego, en lugar de hacer actualizaciones de configuración, manejé una excepción en el método WCF con la ayuda de la excepción de falla. Además, la identidad para WCF debe establecerse con las mismas credenciales que tienen acceso a la base de datos, alguien podría haber cambiado su autoridad. A continuación encontrará el código para el mismo:

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

en su service1.svc.cs puede usar esto en el bloque 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());
        }

Y use esto en la aplicación Cliente como el siguiente código:

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

Simplemente intente esto, seguramente ayudará a obtener el problema exacto.

Aditya
fuente
44
NO debe exponer los detalles de excepción subyacentes. El propósito completo de la separación de excepciones entre el cliente y el servidor y la necesidad de este indicador es evitar que la información de excepción esté disponible para el cliente. ¡Un usuario malintencionado podría usar esta información para manipular su servicio! Si está desarrollando, utilice el comportamiento IncludeExceptionDetailInFaults como se describe para propagar toda la excepción, o en la implementación, genere una excepción de error que genere un error muy básico, como "No se puede guardar el archivo" en lugar de proporcionar un seguimiento de la pila y todos los detalles del excepción.
Immortal Blue
Hola ... en mi caso, todas las demás funciones de servicio están siendo llamadas por la función que estoy usando para guardar el archivo que está lanzando esa excepción ... para conocer el problema exacto que utilicé el sistema de registro pero no se crea ningún registro para ese método ... Estoy creando 3 registros 1) cuando el servicio golpeó 2) antes de guardar cualquier archivo y 3) registro de excepciones.
user3217843
0

Como la información del error dice primero, intente aumentar el valor del tiempo de espera tanto en el lado del cliente como en el del servicio de la siguiente manera:

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

Luego, no olvide aplicar esta configuración de enlace al punto final haciendo lo siguiente:

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

Si lo anterior no puede ayudar, será mejor si puede intentar cargar su proyecto principal aquí, entonces quiero tener una prueba a mi lado.

Muhammad Mohsin Muneer
fuente