2011-02-14 13 views
7

Me acabo de dar cuenta de que cuando coloco una etiqueta de formulario en mi página de diseño, rodeando la sección RenderBody, la validación no intrusiva no se está generando. Algo como esto:ASP.NET MVC 3: Genere una validación discreta cuando BeginForm está en el diseño

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

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

Como ya habrás adivinado, quiero generar botones sobre mi contenido. ¿Es este el comportamiento correcto discreto?

BTW, si coloco el formulario dentro de una página en particular, todo funciona como un amuleto: los atributos data-val * están bien generados.

Agradeceré su valiosa ayuda.

mejores deseos

Rodrigo

Respuesta

1

Gracias por su ayuda, lo probé, pero he encontrado una solución no tan " grotesco "(como dijiste) como sugeriste: D

Simplemente puse un método BeginForm dentro de mi página y también un BeginForm método en el diseño:

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

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


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

así, al final tengo dos métodos BeginForm: motor de ASP.NET MVC está utilizando el ubicado en el diseño de la página, por lo que los datos-val * atributos se estén prestando correctamente y la forma se coloca justo donde quería por lo que cualquier botón de enviar en el diseño puede presentar mi página en particular con las validaciones prestados

funciona bastante bien

Muchas gracias

cordiales, Rodrigo

+0

Si esto pone etiquetas '

' adicionales en una página (como lo señala @AidanBoyle), podría romper la funcionalidad de la página. [Los formularios no se deben anidar de acuerdo con el estándar HTML] (http://www.w3.org/TR/2011/WD-html5-20110525/forms.html#the-form-element). –

12

Se podría aplicar un corte grotesca dentro de la vista:

@{ 
    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; 
} 
+2

Esto me salvó un poco de trabajo, es realmente estúpido el marco no puede manejar esto, para empezar. Me refiero a la construcción de elementos de forma dinámica de ajax es una práctica bastante común, y si se puede pasar en un nuevo contexto de formulario "simulado" solo para obtener una plantilla de editor para disparar, no hay ninguna razón por la que no puedan hacer esto en la parte superior de la función que procesa las plantillas del editor. –

+0

Tuve un problema similar al generar las entradas dentro de una etiqueta de plantilla. Tuve que aplicar el mismo truco para hacer que los atributos de validación no intrusivos se generen. –

1

Acabo de encontrarme con el mismo problema, pero posiblemente una mejor solución basada en la respuesta Darin Dimitrov's.

El truco consiste en crear un tipo base de página, basado en la clase WebViewPage<T>, la clase base predeterminada para las vistas y realizar el intercambio FormContext allí.

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

Y luego en el archivo Web.config bajo la carpeta ~/Views/, alterar el atributo pageBaseType bajo pages elemento, que se puede encontrar en la sección 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> 
+0

Hola Kieron, me temo que la solución de Darin Dimitrov no pudo ayudarme, porque en el orden de ejecución, primero viene la página específica, luego viene la página de diseño, por lo que el objeto FormContext es nulo la primera vez, y no puedo generar mis validadores Gracias por su comentario porque implementé su sugerencia y pude modificar el resultado reemplazando el formulario interno por una cadena vacía. Debo decir que colocar un BeginForm en la página en particular genera un elemento de formulario adicional que muestra un espacio en blanco en IE. –

4

Mientras que poner @using (Html.BeginForm()) en las correcciones en las páginas de contenido el problema de validación también pone un conjunto adicional de etiquetas <form> en la salida. Creé una pequeña extensión que corrige el problema sin escribir nada en la salida.

utilizarlo como @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

Sólo tiene que añadir a continuación el código en la parte superior del archivo de vista del niño ...

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

su trabajo muy bien para mí.

espero que esto le ayudará a ....

Cuestiones relacionadas