Передача ошибок (сообщений об исключениях) из репозитория в действие контроллера в asp.net MVC2 - PullRequest
0 голосов
/ 07 апреля 2011

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

Как передать обратно это сообщение об исключении или даже передать, что в хранилище произошло исключение.

http://www.asp.net/ajaxlibrary/jquery_errors.ashx

В следующем примере из приведенного выше URL-адреса "_repository.HasErrors" используется в качестве проверки, но я хочу знать, как это реализовано в репозитории в C #, поскольку я не знаю, как это реализовано, а также, если его можно также получить сообщение об ошибке.

01.// GET: /HandlejQueryErrors/Contact/Create   
02.public ActionResult Create()   
03.{   
04.    return View();   
05.}  
06.  
07.// POST: /HandlejQueryErrors/Contact/Create   
08.[HttpPost]   
09.public ActionResult Create(ContactViewModel viewModel)   
10.{   
11.    var response = new AjaxResponseViewModel();  
12.  
13.    try  
14.    {   
15.        var contact = _repository.SaveOrUpdate(viewModel);   
16.        if (!_repository.HasErrors)   
17.        {   
18.            response.Success = true;   
19.            response.Message = "Your contact was successfully created!";   
20.        }    
21.        else  
22.        {   
23.            response.Message = "There was an error updating your contact!";   
24.        }   
25.    }   
26.    catch (Exception exception)   
27.    {   
28.        response.Success = false;   
29.        response.Messages exception.Message;    
30.    }  
31.  
32.    return Json(response);   
33.}  

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 07 апреля 2011

Вы можете позволить исключениям вашего репозитория проходить и переопределять метод OnActionExecuted вашего контроллера для обработки определенных ошибок для вас. Пример:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    if (filterContext.Exception is RepositoryException)
    {
        filterContext.ExceptionHandled = true;

        filterContext.Result = View("Exception", filterContext.Exception);
    }

    base.OnActionExecuted(filterContext);
}
1 голос
/ 07 апреля 2011

Таким образом, в общем случае в ASP.NET MVC необходимо обрабатывать 2 вида ошибок: ошибки проверки и системные ошибки.

Для системных ошибок, возникающих из-за нарушения некоторых системных правил (например, внешнего ключа)Нарушение ограничения в базе данных во время вставки), вы должны использовать оператор try-catche, а затем каким-то образом передать их представлению, чтобы показать их пользователю.

Для ошибок проверки вы должны прочитать о ASP.NET MVCВалидация:

Итак, какВ заключение подумайте о том, чтобы отделить заботы о функциональности домена / бизнеса от забот, связанных с проверкой.Единственная распространенная вещь, которую они должны иметь (в идеальном сценарии), это представление, в котором вы показываете результаты проверки.

Лично я (используя 2-й подход) даже сохраняю проверку, чтобы реализация проверки былазнает о доменной / бизнес-логике и манипулирует ею для проверки всех правил.В конце проверки, если все правила были соблюдены, он пытается сохранить данные и возвращает сообщение об ошибке проверки в случае неудачи.Это также хорошее начало, чтобы пойти дальше и даже локализовать ваши пользовательские сообщения проверки.

Надеюсь, это поможет!

0 голосов
/ 07 апреля 2011

Мне лично все еще нравится подход GetRuleViolations (), начатый ScottGu, и я просто хотел бы выполнить это в репозитории.

В контроллере я бы сделал (псевдо здесь):

[HttpPost]
public ActionResult ControllerAction(MyViewModel viewModel)
{
  ModelState.AddRuleViolations(viewModel.GetRuleViolations);

  if (!ModelState.IsValid)
  {
    return View();
  }

  // Perform repository action (pseudo code to follow)
  _repository.ClearErrorState();
  _repository.DoSomething();
  ModelState.AddRuleViolation(repository.GetRuleViolations());

  if (!ModelState.IsValid)
  {
    return View();
  }

  return RedirectToAction("Foo","Bar");
}

class Repository
{
  List<RuleViolation> _errors = new List<RuleViolation>();

  public void ClearErrorState()
  {
    _errors.Clear();
  }

  public void DoSomething(...)
  {
     try
     {
       DoSomthingThatFails();
     }
     catch (Exception ex)
     {
       _errors.Add(new RuleViolation(null, "Error while saving customer");
       _errors.Add(new RuleViolation("SSN", "SSN must be unique"); // This one I struggle with as bad design, tying UI element to data elements is bad, so generally I try to prevent everything when checking the viewmodel and only catch general (unforeseen) errors here.
     }
  }

  public IEnumerable<RuleViolation> GetRuleViolations()
  {
    return _errors;
  }
}
...