Подтвердить что ты не робот

Ошибка пользовательского исключения веб-службы WCF для клиента

Я хотел бы добавить пользовательское исключение, например сообщение об ошибке, в качестве исключения из веб-службы WCF и попытаться получить это сообщение об ошибке в клиентском приложении при вызове метода веб-службы.

как отбросить пользовательское исключение из веб-службы WCF и получить ту же ошибку исключения на стороне клиента.

Метод веб-службы WCF:

    public bool Read()
    {
        if (IsUserValid() == false)
        {
            throw new Exception("Authorized user");
        }
    }

На стороне клиента

try
{
   _client.Read();
}
catch (Exception e)
{
   MessageBox.Show(e.Message);
   return;
}

Результат: всегда высылайте сообщение об ошибке как исключение ** i.e.

"System.ServiceModel.FaultException: Сервер не смог обработать запрос из-за внутренней ошибки. Для больше информации об ошибке, либо включить IncludeExceptionDetailInFaults (либо из ServiceBehaviorAttribute или из конфигурация поведение) на сервере, чтобы отправить информацию об исключении клиента или включить отслеживание в соответствии с Microsoft.NET Framework 3.0 SDK документацию и проверку сервера журналы трассировки.

Этот код генерирует исключение, но не возвращает такое же сообщение об ошибке, которое выбрано из веб-службы WCF как ошибка исключения

Пожалуйста, предложите

4b9b3361

Ответ 1

В WCF вы не должны бросать стандартные исключения .NET - это противоречит потенциально совместимой природе WCF. В конце концов, ваш клиент может быть Java или PHP-клиентом, который не имеет понятия об исключениях .NET.

Вместо этого вам нужно выкинуть FaultExceptions (что является стандартным поведением для WCF).

Если вы хотите передать больше информации о том, что пошло не так, посмотрите на общие типы FaultException<T>:

СЕРВЕР:

public bool Read()
{
    if (IsUserValid() == false)
    {
        throw new FaultException<InvalidUserFault>("User invalid");
    }
}

Или, альтернативно (как предложено @MortenNorgaard):

public bool Read()  
{ 
    if (!IsUserValid()) 
    { 
        InvalidUserFault fault = new InvalidUserFault(); 
        FaultReason faultReason = new FaultReason("Invalid user"); 

        throw new FaultException<InvalidUserFault>(fault, faultReason); 
    }   
}

КЛИЕНТ:

try
{
   _client.Read();
}
catch (FaultException<InvalidUserFault> e)
{
    MessageBox.Show(e.Message);
    return;
}

Вы должны объявить свои InvalidUserFault как контракты данных WCF и определить, какие члены могут вернуться с этим типом (например, код ошибки, сообщение об ошибке и т.д.).

 [DataContract]
 [Serializable()]
 public class BusinessFault
 {
   ... add your fault members here
 }

И тогда вы должны украсить свои методы обслуживания возможными ошибками, которые он может бросить:

[FaultContract(typeof(InvalidUserFault)]
[OperationContract]
public bool Read()
.....

Конечно, "quick'n'dirty" взлома - это просто определить, что сервер возвращает детали исключения в своих исключениях FaultExceptions:

<serviceBehaviors>
   <behavior name="EmployeeManager_Behavior">
      <serviceDebug includeExceptionDetailInFaults="true"/>
   </behavior>
</serviceBehaviors>

а затем вы можете проверить исключение FaultException .Detail для фактического исключения, которое произошло на сервере, но опять же: это скорее взлом, зависящий только от времени разработки, а не от реального решения.

Марк

Ответ 2

Чтобы это сработало, вам нужно сделать две вещи:

  • Определите контракт на отказ в интерфейсе (договор WCF)
  • Выбросить исключение в качестве исключения