ASP.NET MVC 3: создание ненавязчивой проверки, когда BeginForm находится на макете - PullRequest
7 голосов
/ 15 февраля 2011

Я только что понял, что когда я размещаю тег формы на своей странице макета, окружающей раздел RenderBody, ненавязчивая проверка не генерируется. Примерно так:

@using (Html.BeginForm())
{
    <input type="submit" value="save" />

    <div>
        @RenderBody()
    </div>
}

Как вы уже догадались, я хочу создавать кнопки для моего контента. Это правильное ненавязчивое поведение?

Кстати, если я помещу форму внутри определенной страницы, все работает как шарм: атрибуты data-val * хорошо генерируются.

Буду признателен за вашу ценную помощь.

С наилучшими пожеланиями

Rodrigo

Ответы [ 5 ]

12 голосов
/ 15 февраля 2011

Вы можете применить гротескный хак в вашем представлении:

@{
    var originalContext = ViewContext.FormContext;
    ViewContext.FormContext = new FormContext();
}

<!-- This will generate proper HTML5 data-* validation attributes -->
@Html.TextBoxFor(x => x.Prop1)
@Html.ValidationMessageFor(x => x.Prop1)

@Html.TextBoxFor(x => x.Prop2)
@Html.ValidationMessageFor(x => x.Prop2)

@{
    ViewContext.FormContext = originalContext;
}
4 голосов
/ 06 января 2012

Хотя добавление @using (Html.BeginForm()) на страницу содержимого устраняет проблему проверки, оно также добавляет в вывод дополнительный набор тегов <form>. Я создал небольшое расширение, которое исправляет проблему, ничего не записывая в вывод.

Используйте как @using (Html.BeginSubForm())

public static class FormExtensions
{
    public static MvcSubForm BeginSubForm(this HtmlHelper html)
    {
        return new MvcSubForm(html.ViewContext);
    }
}


public sealed class MvcSubForm : IDisposable
{
    private readonly ViewContext _viewContext;
    private readonly FormContext _originalFormContext;

    public MvcSubForm(ViewContext viewContext)
    {
        _viewContext = viewContext;
        _originalFormContext = viewContext.FormContext;

        viewContext.FormContext = new FormContext();
    }


    public void Dispose()
    {
        if (_viewContext != null)
        {
            _viewContext.FormContext = _originalFormContext;
        }
    }
}
1 голос
/ 24 мая 2012

Просто добавьте приведенный ниже код в верхней части дочернего файла просмотра ...

@{
   Layout = "~/Views/Shared/_Layout.cshtml";
   this.ViewContext.FormContext = new FormContext();
}

он отлично работает для меня.

Я надеюсь, это поможет вам ....

1 голос
/ 11 мая 2011

Я только что столкнулся с той же проблемой, но, возможно, лучшее решение основано на ответе Дарина Димитрова .

Хитрость заключается в создании базового типа страницы на основе WebViewPage<T> class, базовый класс по умолчанию для представлений и выполните обмен FormContext там.

abstract public class FormFixWebViewPage : FormFixWebViewPage<object>
{
}

abstract public class FormFixWebViewPage<T> : WebViewPage<T>
{
    override public void Write(System.Web.WebPages.HelperResult result)
    {
        var originalFormContext = ViewContext.FormContext;
        ViewContext.FormContext = new FormContext();

        base.Write(result);

        ViewContext.FormContext = originalFormContext;
    }
}

А затем в файле Web.config подПапка ~/Views/, измените атрибут pageBaseType в элементе pages, который находится в разделе system.web.webPages.razor:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="<YOUR-NAMESPACE>.FormFixWebViewPage">
    <!--pages pageBaseType="System.Web.Mvc.WebViewPage"-->
        <namespaces>
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Helpers" />
            <add namespace="System.Web.Routing" />
        </namespaces>
    </pages>
</system.web.webPages.razor>
1 голос
/ 15 февраля 2011

Спасибо за вашу помощь, я попробовал это, но я нашел решение не такое "гротескное" (как вы сказали), как вы предлагали: D

Я просто поместил метод BeginForm на своей странице, а также метод BeginForm на макете:

@* On the layout page *@
@using (Html.BeginForm())
{
    <input type="submit" value="save" />

    <div>
        @RenderBody()
    </div>
}


@* On the content page *@
@using(Html.BeginForm())
{
  @* Content *@
}

Итак, в конце у меня есть два метода BeginForm: ASP.NET MVC использует механизм, расположенный на странице макета, поэтому атрибуты data-val * отображаются правильно, а форма размещается именно там, где я и хотел любая кнопка отправки на макете может отправить мою конкретную страницу с подтвержденными подтверждениями

Хорошо работает

Большое спасибо

С уважением, Rodrigo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...