Я вижу, что установка 404 страниц в web.config является хорошим чистым методом, НО это все еще первоначально отвечает 302 перенаправлениями к ошибочной странице. Как пример, если Вы перешли к:
https://stackoverflow.com/x.aspx
Вы будете перенаправлены через 302 перенаправления к:
https://stackoverflow.com/404? aspxerrorpath =/x.aspx
, Что я хочу произойти, является этим:
нет никакого перенаправления. Запрос на недостающий URL возвращает 404 кода статуса с дружественным сообщением об ошибке.
You can definitely catch and handle all exceptions that happen on your service class and turn them into a FaultException or FaultException exception.
That way, you won't "fault" (or tear down) the communications channel between your client and server.
Even better approach would be to implement the IErrorHandler
interface on your service class that provides a way to globally catch all exceptions as they happen and provide a FaultException instead, that's SOAP compliant.
You can even turn your IErrorHandler
into a configurable behavior that can be turned on or off in config.
See these articles and blog posts for more details:
[FaultContract (typeof (CustomFault))]
Лично я создаю базовый класс Fault, который имеет свойство Reason, и расширяю все пользовательские ошибки из этого класса. Когда я хочу выбросить ошибку, я вызываю:
throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));
Также стоит отметить, что я версирую свои классы ошибок (включая общий класс Fault) вместе со всеми моими другими службами. Это вызывает беспокойство только в том случае, если существует проблема с версией службы, хотя.
Вот основной класс Fault (я удалил проверку аргументов для краткости):
[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)]
public abstract class Fault
{
internal FaultReason Reason { get; set; }
protected Fault(string reasonText)
{
Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture));
}
public override string ToString()
{
return Reason.ToString();
}
internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault
{
return new FaultException<TDetail>(fault, fault.Reason);
}
}
You can design the specific Fault Data Contracts for each of the exception scenario in your WCF service so that you can handle the fault/exception at client side respectively.
try
{
// Actions
}
catch (Exception ex)
{
// Log the exception
// Throw Fault Exception back to client
FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code"));
//throw fault exception back to WCF client
throw fe;
}