Как обработать модель, указывают ошибки в ajax-вызванном действии контроллера, которое возвращает PartialView

У меня есть действие контроллера POST, которое возвращает частичное представление. Все кажется действительно легким. но. Я загружаю его использование $.ajax(), установка типа как html. Но когда моя проверка допустимости модели перестала работать, я думал, что должен просто бросить ошибку с образцовыми ошибками состояния. Но мой ответ всегда возвращает 500 ошибок Сервера.

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

Править

Я также хотел бы постараться не возвращать ошибку частичное представление. Это было бы похоже на успех на клиенте. Наличие клиента анализирует результат, чтобы видеть, является ли это фактическим успехом, подвержено ошибкам. Разработчики могут изменить частичный вывод представления, и это одно повредило бы функциональность. Таким образом, я хочу выдать исключение, но с корректным сообщением об ошибке, возвращенным ajax клиенту.

22
задан Robert Koritnik 15 February 2010 в 15:59
поделиться

2 ответа

Решение

Мне пришлось написать две отдельные части, которые автоматически работают точно так, как предполагалось .

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

Для этого используются две основные части:

  • Пользовательский класс исключения , который выдается, когда что-то идет не так, чтобы мы могли различать общие исключения, которые могут произойти в любое время по любой причине, и связанные с ними ошибки. в нашу обработку (особенно недопустимое состояние модели)
  • Фильтр действий при исключении , который улавливает наше настраиваемое исключение и готовит результат на основе этого исключения; Как вы увидите из кода, наше настраиваемое исключение будет содержать информацию об ошибках состояния модели, поэтому этот фильтр сможет возвращать настраиваемый код состояния HTTP, а также некоторую текстовую информацию

Подробности, затем ...

Внешний ссылка : Вся эта информация (подробное объяснение, а также весь код) также доступна в моем блоге. Последние обновления кода всегда публикуются здесь .

Пользовательский класс исключений

Этот класс предоставляет две вещи

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

Этот класс позже используется в моем пользовательском фильтр ошибок.

public class ModelStateException : Exception
{
    public Dictionary<string, string> Errors { get; private set; }

    public ModelStateDictionary ModelState { get; private set; }

    public override string Message
    {
        get
        {
            if (this.Errors.Count > 0)
            {
                return this.Errors.First().Value;
            }
            return null;
        }
    }

    private ModelStateException()
    {
        this.Errors = new Dictionary<string, string>();
    }

    public ModelStateException(ModelStateDictionary modelState) : this()
    {
        this.ModelState = modelState;
        if (!modelState.IsValid)
        {
            foreach (KeyValuePair<string, ModelState> state in modelState)
            {
                if (state.Value.Errors.Count > 0)
                {
                    this.Errors.Add(state.Key, state.Value.Errors[0].ErrorMessage);
                }
            }
        }
    }
}

Атрибут фильтра ошибок

Этот атрибут помогает возвращать клиенту ошибки в терминах кодов ошибок HTTP, когда есть какие-либо ошибки состояния модели.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class HandleModelStateExceptionAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (filterContext.Exception != null && typeof(ModelStateException).IsInstanceOfType(filterContext.Exception) && !filterContext.ExceptionHandled)
        {
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = 400;
            filterContext.HttpContext.Response.StatusDescription = (filterContext.Exception as ModelStateException).Message;
        }
    }
}

После этого я просто украсил свое действие контроллера своим атрибутом и вуаля. Я получил ошибки на клиенте с кодом 400 и правильной информацией, которую я установил в своем фильтре. Затем эта информация отображается пользователю (когда она связана с ошибками состояния модели, она отображает информацию, какие поля формы следует изменить, чтобы сделать форму действительной).

[HandleModelStateException]
public ActionResult AddComment(MyModel data)
{
    // check if state is valid
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }
    // get data from store
    return PartialView("Comment", /* store data */ );
}

Это делает мой код пригодным для повторного использования с любыми ошибками состояния модели, и они будут отправлены клиенту должным образом.

Одна единственная проблема (теперь решена)

Но есть еще одна проблема, связанная с этим кодом. Когда мой фильтр действий при ошибке устанавливает StatusDescription и эта строка содержит некоторые специальные символы, такие как Č, я получаю мусор на клиенте. Если только я не использую IE (я использую версию 8). FF и CH отображают мусор. Вот почему я установил кодировки, но это не работает. Если у кого-то есть обходной путь для этой особенности, я был бы более чем рад выслушать его.
Если я верну сообщение об ошибке в самом контенте, все в порядке. Кодировка правильная, и я могу отображать все, что хочу.

17
ответ дан 29 November 2019 в 05:41
поделиться

Я сделал комбинацию вещей в этой нити и у меня, наконец, был успех.

В построителе интерфейсов (не xcode)

  1. Файл - > Перезагрузить все файлы классов
  2. Файл - > Чтение файлов классов (выберите MyClass.h)
  3. Повторно подключить владельца файла к
    A. Установка класса «MyClass»
    b. Повторное подключение представления к представлению владельца файла

Теперь все возвращается в нормальное состояние. Странно.

Надеюсь, что это поможет больше, чем сбивает с толку; -)

-121--1471527-

Для проверки возможностей скрытых отчетов необходимо использовать функции HidP_. Узнайте, какие возможности (использования) представлены устройством HIDPOS, и проверьте наличие этих возможностей с помощью HidD_GetPreparsedData (), HidP_GetCaps (), а затем HidP_GetValueCaps (и/или.. ButureCaps и т.д.). Хорошим местом для поиска примеров является страница Яна Аксельсона . Если используются устройства, то у вас есть POS-устройство. Если нет, то это должна быть клавиатура (если вы подтвердили, что устройство подключено)

-121--4998486-

Попробуйте.

public ActionResult DoAjaxAction(Entity entity)
{
   if(ModelState.IsValid)
   {
     return PartialView("Valid_View", entity);
   }
   else
   {
     return PartialView("Invalid_View", entity);
   } 

}
3
ответ дан 29 November 2019 в 05:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: