Изменяет правила переопределения приоритетов каскадов CSS. См. спецификацию CSS2 .
Я все еще немного запутался в различных решениях и как атрибуты могут мешать друг другу, но я выбрал следующее решение:
public class LogErrorsAttribute: FilterAttribute, IExceptionFilter
{
#region IExceptionFilter Members
void IExceptionFilter.OnException(ExceptionContext filterContext)
{
if (filterContext != null && filterContext.Exception != null)
{
string controller = filterContext.RouteData.Values["controller"].ToString();
string action = filterContext.RouteData.Values["action"].ToString();
string loggerName = string.Format("{0}Controller.{1}", controller, action);
log4net.LogManager.GetLogger(loggerName).Error(string.Empty, filterContext.Exception);
}
}
#endregion
}
Я по-прежнему использую атрибут [HandleError], как описано в исходном вопросе, и просто украшаю каждый контроллер атрибутом [LogErrors].
Это работает для меня, так как он хранит журнал ошибок в одном месте и не приводит к тому, что повторяющиеся исключения регистрируются несколько раз (что произойдет, если я расширю [HandleError] и использую атрибут в нескольких местах).
Я не делаю ' Я думаю, что можно будет объединить и ведение журнала исключений, и обработку ошибок в один атрибут или класс, не делая это очень утомительным и сложным и не влияя на использование [HandleError]
. Но это работает для меня, поскольку я украшаю каждый контроллер только один раз с атрибутом [LogErrors] и декорируйте Контроллеры и Действия с помощью [HandleError] именно так, как я хочу, чтобы они не мешали друг другу.
Обновление:
Вот пример того, как я его использую:
[LogErrors(Order = 0)]
[HandleError(Order = 99)]
public class ContactController : Controller
{
public ActionResult Index()
{
return View(Views.Index);
}
public ActionResult Directions()
{
return View(Views.Directions);
}
public ActionResult ContactForm()
{
FormContactMessage formContactMessage = new FormContactMessage();
return View(Views.ContactForm,formContactMessage);
}
[HandleError(ExceptionType = typeof(SmtpException), View = "MessageFailed", Order = 1)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ContactForm(FormContactMessage formContactMessage)
{
if (ModelState.IsValid)
{
if (formContactMessage.IsValid)
{
SmtpClient client = new SmtpClient();
MailAddress recipientAddress = new MailAddress(Properties.Settings.Default.ContactFormRecipientEmailAddress);
MailAddress senderAddress = new MailAddress(Properties.Settings.Default.ContactFormSenderEmailAddress);
MailMessage mailMessage = formContactMessage.ToMailMessage(recipientAddress, senderAddress);
client.Send(mailMessage);
return View("MessageSent");
}
else
{
ModelState.AddRuleViolations(formContactMessage.GetRuleViolations());
}
}
return View(Views.ContactForm, formContactMessage);
}
private static class Views
{
public static string Index { get { return "Index"; } }
public static string Directions { get { return "Directions"; } }
public static string ContactForm { get { return "ContactForm"; } }
}
}
В приведенном выше коде исключения SmtpExceptions в перегрузке действия ContactForm
обрабатываются очень специфическим образом - пользователю предоставляется ViewPage, относящийся к не отправленным сообщениям, в этом случае он называется «MessageFailed» . Все остальные исключения обрабатываются поведением по умолчанию [HandleError]. Также обратите внимание, что сначала происходит регистрация ошибок, с последующей обработкой ошибок. На это указывает следующее:
[LogErrors(Order = 0)]
[HandleError(Order = 99)]
Обновление:
Существует альтернативное решение этой проблемы с очень хорошим объяснением. Я рекомендую прочитать его, чтобы лучше понять возникающие проблемы.
Атрибут ASP.NET MVC HandleError, настраиваемые страницы ошибок и исключения из журнала (Спасибо Скотту Шеперду ниже, который предоставил ссылку в ответе ниже).