Я тоже несколько дней бился головой об стену и собирался пойти по пути удаления тега формы, но просто заставил его работать немного менее хакерским способом, если вы все еще заинтересованы. Мой сценарий был похож в том, что у меня есть форма с набором элементов для первоначальной проверки, но пользователи могут динамически добавлять новые строки через ajax.
Я сломаю это, так что, надеюсь, будет легче увидеть, что происходит. Глядя на исходный код MVC, форма и проверка работают примерно так:
Html.BeginForm () выводит открывающий тег формы, затем создает и возвращает новый экземпляр MvcForm, который внешне мало что делает, за исключением того, что вам легче управлять областью формы.
Однако он создает новый FormContext и сохраняет его в ViewContext.FormContext. Именно этот FormContext отслеживает проверку клиента.
Последнее, что делает Html.BeginForm () - устанавливает свойство FormId нового FormContext, используя идентификатор тега формы. Это необходимо для того, чтобы клиентский сценарий мог сопоставлять формы и правила проверки.
Html.EndForm () удаляет MvcForm. Этот метод Dispose выводит закрывающий тег формы, а затем вызывает ViewContext.OutputClientValidation (), который является ответственным за вывод javascript. Наконец, он удаляет текущий FormContext и устанавливает его обратно в родительский FormContext или ноль, если его нет.
Таким образом, чтобы не выводить тег формы, нам нужно каким-то образом извлечь часть управления FormContext из конструктора / деструктора MvcForm.
Итак, в своем Частичном обзоре я сделал следующее:
Вверху я проверяю, имеет ли ViewContext.FormContext значение. Если это так, мы находимся в начальной загрузке, поэтому не нужно возиться. Если нет, то это ajax-вызов, поэтому я включаю проверку клиента, создаю новую MvcForm напрямую ( не с BeginForm) - это вызывает создание FormContext - и задаю для FormContext.FormId тот же Моя родительская страница
В конце представления я проверяю, есть ли у меня экземпляр формы, и если да, вызываю ViewContext.OutputClientValidation () и сбрасываю ViewContext.FormContext в ноль. Я не утилизирую () MvcForm, так как это выведет закрывающий тег, а MvcForm не содержит одноразовых объектов.
Каркас вида выглядит так:
<%
MvcForm dummyForm = null;
if (this.ViewContext.FormContext == null)
{
Html.EnableClientValidation();
dummyForm = new MvcForm(this.ViewContext);
this.ViewContext.FormContext.FormId = "mainform";
}
%>
// standard partial view markup goes here
<%
if (dummyForm != null)
{
this.ViewContext.OutputClientValidation();
this.ViewContext.FormContext = null;
}
%>
Вы можете легко обернуть это в метод расширения
Phil