ASP.NET MVC 3: générer une validation discrète lorsque BeginForm est sur la mise en page

Translate

Je viens de réaliser que lorsque je place une balise de formulaire sur ma page de mise en page, entourant la section RenderBody, la validation discrète n'est pas générée. Quelque chose comme ça:

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

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

Comme vous l'avez peut-être deviné, je souhaite générer des boutons sur mon contenu. Est-ce le comportement correct du discret?

BTW, si je place le formulaire dans une page particulière, tout fonctionne comme un charme: les attributs data-val * sont bien générés.

J'apprécierai votre précieuse aide.

meilleures salutations

Rodrigo

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

Vous pouvez appliquer un hack grotesque à l'intérieur de votre vue:

@{
    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;
}
La source
Translate

En mettant@using (Html.BeginForm())dans la page de contenu corrige le problème de validation, il met également un ensemble supplémentaire de<form>balises dans la sortie. J'ai créé une petite extension qui résout le problème sans rien écrire dans la sortie.

Utilisez-le comme@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;
        }
    }
}
La source
Translate

Merci pour votre aide, je l'ai essayé mais j'ai trouvé une solution pas aussi "grotesque" (comme vous l'avez dit) que vous l'aviez suggéré: D

J'ai simplement mis une méthode BeginForm dans ma page et aussi une méthode BeginForm sur la mise en page:

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

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


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

donc, à la fin, j'ai deux méthodes BeginForm: le moteur ASP.NET MVC utilise celui situé sur la page de mise en page, de sorte que les attributs data-val * sont rendus correctement et le formulaire est placé juste là où je le voulais, donc tout bouton d'envoi sur la mise en page peut soumettre ma page particulière avec les validations rendues

Ça marche plutôt bien

Merci beaucoup

Cordialement,Rodrigo

La source
Translate

Je viens de rencontrer le même problème, mais peut-être une meilleure solution basée surDarin Dimitrovrépondre.

L'astuce consiste à créer un type de base de page, basé sur leWebViewPage<T>class, la classe de base par défaut pour les vues et faites leFormContextéchangez-y.

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;
    }
}

Et puis dans leWeb.configfichier sous le~/Views/dossier, modifiez lepageBaseTypeattribut souspagesélément, qui se trouve dans lesystem.web.webPages.razorsection:

<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>
La source
Translate

Ajoutez simplement le code ci-dessous en haut du fichier de vue enfant ...

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

ça marche bien pour moi.

J'espère que cela t'aidera....

La source
Leave a Reply
You must be logged in to post a answer.
A propos de l'auteur