"Создатель этой ошибки не указал" Исключение причины "
У меня есть следующий код в службе WCF, чтобы вызвать пользовательскую ошибку, основанную на определенных ситуациях. Я получаю исключение "Создатель этой ошибки не определял причину". Что я делаю неправильно?
//source code
if(!DidItPass)
{
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault);
}
//operation contract
[OperationContract]
[FaultContract(typeof(InvalidRoutingCodeFault))]
bool MyMethod();
//data contract
[DataContract(Namespace="http://myuri.org/Simple")]
public class InvalidRoutingCodeFault
{
private string m_ErrorMessage = string.Empty;
public InvalidRoutingCodeFault(string message)
{
this.m_ErrorMessage = message;
}
[DataMember]
public string ErrorMessage
{
get { return this.m_ErrorMessage; }
set { this.m_ErrorMessage = value; }
}
}
Ответы
Ответ 1
После некоторых дополнительных исследований работал следующий модифицированный код:
if(!DidItPass)
{
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason("Invalid Routing Code - No Approval Started"));
}
Ответ 2
Короткий ответ: вы ничего не делаете неправильно, просто неправильно читаете результаты.
На стороне клиента, когда вы поймаете ошибку, то, что поймано, имеет тип System.ServiceModel.FaultException<InvalidRoutingCodeFault>
.
Ваш объект InvalidRoutingCodeFault
фактически находится в свойстве .detail
исключения FaultException. SO....
//код клиента
private static void InvokeMyMethod()
{
ServiceClient service = new MyService.ServiceClient();
try
{
service.MyMethod();
}
catch (System.ServiceModel.FaultException<InvalidRoutingCodeFault> ex)
{
// This will output the "Message" property of the System.ServiceModel.FaultException
// 'The creator of this fault did not specify a Reason' if not specified when thrown
Console.WriteLine("faultException Message: " + ex.Message);
// This will output the ErrorMessage property of your InvalidRoutingCodeFault type
Console.WriteLine("InvalidRoutingCodeFault Message: " + ex.Detail.ErrorMessage);
}
}
Свойство Message для FaultException - это то, что отображается на странице ошибки, поэтому, если оно не заполнено, как в столбце Джона Эгертона, вы увидите сообщение "Создатель этой ошибки не указал сообщение" Причина ". Чтобы легко заполнить его, используйте два конструктора параметров при вызове ошибки в службе следующим образом, передав сообщение об ошибке из вашего типа ошибки:
InvalidRoutingCodeFault fault = new InvalidRoutingCodeFault("Invalid Routing Code - No Approval Started");
throw new FaultException<InvalidRoutingCodeFault>(fault, new FaultReason(fault.ErrorMessage));
Ответ 3
serviceDebug includeExceptionDetailInFaults="true"
НЕ является решением
Следующий код работает даже с serviceDebug includeExceptionDetailInFaults="false"
// data contract
[DataContract]
public class FormatFault
{
private string additionalDetails;
[DataMember]
public string AdditionalDetails
{
get { return additionalDetails; }
set { additionalDetails = value; }
}
}
// interface method declaration
[OperationContract]
[FaultContract(typeof(FormatFault))]
void DoWork2();
// service method implementation
public void DoWork2()
{
try
{
int i = int.Parse("Abcd");
}
catch (FormatException ex)
{
FormatFault fault = new FormatFault();
fault.AdditionalDetails = ex.Message;
throw new FaultException<FormatFault>(fault);
}
}
// client calling code
private static void InvokeWCF2()
{
ServiceClient service = new ServiceClient();
try
{
service.DoWork2();
}
catch (FaultException<FormatFault> e)
{
// This is a strongly typed try catch instead of the weakly typed where we need to do -- if (e.Code.Name == "Format_Error")
Console.WriteLine("Handling format exception: " + e.Detail.AdditionalDetails);
}
}
Нет необходимости добавлять причину ошибки, если она не требуется. Просто убедитесь, что атрибут FaultContract верен.
Ответ 4
Я решил эту проблему, используя два конструктора параметров.
// service method implementation
throw new FaultException<FormatFault>(fault,new FaultReason(fault.CustomFaultMassage));
CustomFaultMassage является свойством из контракта данных.
Ответ 5
Можно также встретить это исключение, если не указать атрибут FaultContract (typeof (className)) для метода
Ответ 6
У меня есть код, точно такой же, как у Rashmi, и я получил ошибку "Создатель этой ошибки....". Это происходило, когда я отлаживался в VS2010. Я нашел этот пост:
http://sergecalderara.wordpress.com/2008/11/25/systemservicemodelfaultexception1-was-unhandled-by-user-code/
который объяснил пару параметров отладки, которые мне нужно было отключить. Проблема решена.
Ответ 7
Если вы не хотите получать уведомления об этих исключениях, перейдите в "Отладка" → "Исключения" и снимите флажок "Пользовательский необработанный" для "Исключения на время обычного языка" или для определенных исключений.
Ответ 8
Вы можете попробовать это в настройках сервера (поведение → serviceBehaviors → ):
<serviceDebug includeExceptionDetailInFaults="true" />
Ответ 9
Используя сильно типизированный try catch, я смог обойтись с ошибкой "Создатель этой ошибки не определил причину".
Ответ 10
Обновление справочной службы в клиенте решило проблему. То же самое может сработать для вас.