Используя пользовательский объект ShiftContract, содержащий System.Exception вызывает «Добавить ссылку на обслуживание»
-
09-10-2019 - |
Вопрос
Я только что заметил что-то особенное. У меня есть внутренний сервис акций, который публикуется через BasichTTPBINDING, а также на заказ (HTTP + Binary), для которых включена метаданные. Я также включал конечную точку MEX для HTTP. Мы используем Visual Studio 2008 & VB.Net
Совсем недавно мы заметили, что мы не смогли успешно добавить ссылку на обслуживание на эту услугу в наших других проектах. Все, что он будет генерировать, было первым пользовательским исключением, которое мы включили через FaultContract (на самом деле, было только 1 тип). Если бы добавил простую веб-справочную ссылку, она также будет работать правильно. Кроме того, у WCFClient.exe не было проблем либо в загрузке служб. Просто vs.net Добавить ссылку на обслуживание не будет работать.
В службе это исключение наследует от исключения и помечается как сериализация. Это все, что вы должны делать, нет?
В любом случае, это я сбил с толку. Если я удаляю FaultContract для этого пользовательского исключения, все работает нормально. Я могу добавить ссылку на сервис, без проблем. Но есть ли способ, которым у меня все еще есть мои пользовательские исключения? Это известная проблема?
Решение
Я бежал в этом сам сегодня. Решение было использовать объект, не наследующий от исключения в неисправности. Если вы посмотрите на документы MSDN для FaipException. и FaultContract. Вы увидите, что официальные примеры используют обычные классы (с атрибутами DataContact), а не классы, расширяющие исключение для FILLEXCECTION.DETAIL. Я не уверен, почему исключение приводит к неудаче Add Service, но я подозреваю, что связано с сериализацией или извлечением информации о типе для пользовательских исключений. Я включил до и после примера реализации, чтобы продемонстрировать рабочий подход.
До (не работал):
[ServiceContract]
public interface IMyService
{
[OperationContract]
[FaultContract(typeof(MyException))]
MyResults MyServiceOperation(string myParameter);
}
[Serializable]
public class MyException : Exception
{
public string CustomData { get; set; }
}
[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
public MyResults MyServiceOperation(string myParameter)
{
...
throw new MyModelException { CustomData = "42" };
...
}
}
public class MyErrorHandler : IErrorHandler
{
public bool HandleError(Exception error) { return false; }
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
try { throw error; }
catch (MyModelException ex)
{
var faultEx = new FaultException<MyException>(new MyException { CustomData = ex.CustomData });
fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
}
catch { /* Supress all others */ }
}
}
После (работал):
[ServiceContract]
public interface IMyService
{
[OperationContract]
[FaultContract(typeof(MyFault))]
MyResults MyServiceOperation(string myParameter);
}
[DataContract]
public class MyFault
{
[DataMember]
public string CustomData { get; set; }
}
[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
public MyResults MyServiceOperation(string myParameter)
{
...
throw new MyModelException { CustomData = "42" };
...
}
}
public class MyErrorHandler : IErrorHandler
{
public bool HandleError(Exception error) { return false; }
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
try { throw error; }
catch (MyModelException ex)
{
var faultEx = new FaultException<MyFault>(new MyFault { CustomData = ex.CustomData });
fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
}
catch { /* Supress all others */ }
}
}
Источник: Макс Стрини Для использования его кода и помогите в нахождении решения этого вопроса.
Другие советы
Я нашел следующую статью о том, как создать неисправный контракт с использованием объектов, унаследованных от System.Exception: http://blog.clauskonrad.net/2008/06/wcf-and-custom-Exceptions.html.
Тем не менее, это не сработало для меня. Я подозреваю, причина, по которой она не сработала для меня, - это то, что я использую привязку базихтттта, а не связывание .NET-.NET.
Я также ударил эту проблему. Я закончил использовать svcutil.exe для создания прокси, который не пострадает от того же вопроса.
У меня была та же проблема и решила его, создавая прокси, используя svcutil.exe. У меня была настраиваемая настройка неисправностей именно то, как MSDN рекомендует, но «Добавить ссылку на сервис» не включал договор неисправности в прокси. Тогда я использовал Svcutil, и это работало как волшебство :)