Изменение при добавлении HTML-атрибутов в Html.BeginForm () - PullRequest
4 голосов
/ 01 марта 2012

Мне нужна форма на моей странице бритвы ASP.NET MVC. Я бы предпочел использовать следующий синтаксис:

@using (Html.BeginForm())
{
}

Однако мне нужно добавить несколько атрибутов в форму. В итоге я получил что-то вроде следующего:

@using (Html.BeginForm(null, null, FormMethod.Post, new { name = "value" }))
{
}

Однако, это имеет нежелательный побочный эффект. Если в запросе этой страницы есть аргументы запроса, первая форма передает их при отправке формы. Однако второй версии нет.

Я действительно не знаю, почему BeginForm() не поддерживает атрибуты, но есть ли прямой способ добавить атрибуты в BeginForm() и все еще передавать любые аргументы запроса при отправке for?

EDIT:

После изучения этого может показаться, что лучшим решением будет что-то вроде этого:

<form action="@Request.RawUrl" method="post" name="value">
</form>

Однако при использовании этого синтаксиса проверка на стороне клиента отключается. Кажется, нет хорошего решения этой ситуации без более сложных и потенциально ненадежных конструкций.

Ответы [ 3 ]

5 голосов
/ 01 марта 2012

Это действительно так, но я бы пошел с пользовательским помощником, чтобы сохранить контекст формы внутри, который используется для проверки на стороне клиента:

public static class FormExtensions
{
    private static object _lastFormNumKey = new object();

    public static IDisposable BeginForm(this HtmlHelper htmlHelper, object htmlAttributes)
    {
        string rawUrl = htmlHelper.ViewContext.HttpContext.Request.RawUrl;
        return htmlHelper.FormHelper(rawUrl, FormMethod.Post, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    private static int IncrementFormCount(IDictionary items)
    {
        object obj2 = items[_lastFormNumKey];
        int num = (obj2 != null) ? (((int)obj2) + 1) : 0;
        items[_lastFormNumKey] = num;
        return num;
    }

    private static string DefaultFormIdGenerator(this HtmlHelper htmlhelper)
    {
        int num = IncrementFormCount(htmlhelper.ViewContext.HttpContext.Items);
        return string.Format(CultureInfo.InvariantCulture, "form{0}", new object[] { num });
    }

    private static IDisposable FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes)
    {
        var builder = new TagBuilder("form");
        builder.MergeAttributes<string, object>(htmlAttributes);
        builder.MergeAttribute("action", formAction);
        builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
        bool flag = htmlHelper.ViewContext.ClientValidationEnabled && !htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled;
        if (flag)
        {
            builder.GenerateId(htmlHelper.DefaultFormIdGenerator());
        }
        htmlHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
        var form = new MvcForm(htmlHelper.ViewContext);
        if (flag)
        {
            htmlHelper.ViewContext.FormContext.FormId = builder.Attributes["id"];
        }
        return form;
    }
}

, который можно использовать так:

@using (Html.BeginForm(htmlAttributes: new { name = "value" }))
{
    ...
}
1 голос
/ 13 ноября 2012

У меня была похожая проблема, и вот быстрое решение (она работает с MVC4).

Объявите метод расширения:

public static MvcForm BeginForm(this HtmlHelper helper, object htmlAttributes)
{
        return helper.BeginForm(helper.ViewContext.RouteData.Values["Action"].ToString(),
                                helper.ViewContext.RouteData.Values["Controller"].ToString(), 
                                FormMethod.Post, htmlAttributes);
}

и используйте его на своей странице:

@using (Html.BeginForm(htmlAttributes: new {@class="form-horizontal"})) 
{
...
}
0 голосов
/ 31 января 2014

Небольшая модификация исходного кода:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/FormExtensions.cs

public static MvcForm BeginForm(this HtmlHelper htmlHelper, object htmlAttributes)
{
   // generates <form action="{current url}" method="post">...</form>
   string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl;
   return FormHelper(htmlHelper, formAction, FormMethod.Post, new RouteValueDictionary(htmlAttributes));
}

private static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes)
{
   TagBuilder tagBuilder = new TagBuilder("form");
   tagBuilder.MergeAttributes(htmlAttributes);
   // action is implicitly generated, so htmlAttributes take precedence.
   tagBuilder.MergeAttribute("action", formAction);
   // method is an explicit parameter, so it takes precedence over the htmlAttributes.
   tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);

   bool traditionalJavascriptEnabled = htmlHelper.ViewContext.ClientValidationEnabled
                                       && !htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled;

   if (traditionalJavascriptEnabled)
   {
       // forms must have an ID for client validation
       tagBuilder.GenerateId(htmlHelper.ViewContext.FormIdGenerator());
   }

   htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
   MvcForm theForm = new MvcForm(htmlHelper.ViewContext);

   if (traditionalJavascriptEnabled)
   {
       htmlHelper.ViewContext.FormContext.FormId = tagBuilder.Attributes["id"];
   }

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