2010-08-18 15 views
7

Considérese la siguiente configuración:¿Solo funciona ReadOnly (true) con Html.EditorForModel?

Modelo:

public class Product 
{ 
    [ReadOnly(true)] 
    public int ProductID 
    { 
     get; 
     set; 
    } 

    public string Name 
    { 
     get; 
     set; 
    } 
} 

Vista:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<MvcApplication4.Models.Product>" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Home Page 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
    <%= Html.EditorForModel() %> 
</asp:Content> 

controlador:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new Product 
      { 
       ProductID = 1, 
       Name = "Banana" 
      }); 
    } 
} 

Hay resultado es este: alt text

Estaba esperando que la propiedad ProductID no fuera editable a través del atributo ReadOnly(true). ¿Esto es compatible? Si no, ¿hay alguna forma de insinuar ASP.NET MVC que algunas propiedades de mi modelo son de solo lectura? No me gustaría simplemente ocultar ProductID a través de [ScaffoldColumn(false)].

Respuesta

9

Los atributos ReadOnly y Required serán consumidos por el proveedor de metadatos, pero no se usarán. Si desea deshacerse de la entrada con EditorForModel, necesitará una plantilla personalizada o [ScaffoldColumn(false)].

Para plantilla personalizada ~/Views/Home/EditorTemplates/Product.ascx:

<%@ Control Language="C#" Inherits="ViewUserControl<Product>" %> 

<%: Html.LabelFor(x => x.ProductID) %> 
<%: Html.TextBoxFor(x => x.ProductID, new { @readonly = "readonly" }) %> 

<%: Html.LabelFor(x => x.Name) %> 
<%: Html.TextBoxFor(x => x.Name) %> 

También tenga en cuenta que el aglutinante modelo por defecto no va a copiar un valor en una propiedad con [ReadOnly(false)]. Este atributo no influirá en la UI representada por las plantillas predeterminadas.

+1

Gracias. Ya me lo imaginaba. Lástima que no quiero usar [ScaffoldColumn (false)] y crear una plantilla de editor sería una especie de fracaso ... –

+1

Bueno, @naso, hay momentos como este cuando simplemente maldecimos a Microsoft y continuamos con nuestro diario trabajos :-) Saludos. –

11

He resuelto este problema agregando un UIHintAttribute a la propiedad en mi clase de "ReadOnly".

[UIHint("ReadOnly")] 
public int ClassID { get; set; } 

Entonces simplemente añade un ~ \ views \ archivo Shared \ EditorTemplates \ ReadOnly.ascx a mi proyecto con esto en él:

<%= Model %> 

Una forma muy sencilla de agregar plantillas personalizadas, podrías incluir formato o lo que sea.

+6

Un método aún más fresco podría ser subclasificar la clase ** DataAnnotationsModelMetadataProvider ** como en [la publicación de Brad Wilson] (http://bradwilson.typepad.com/blog/2010/01/why-you-dont-need-modelmetadataattributes. html) y simplemente agregue esta línea: 'if (metadata.IsReadOnly) metadata.TemplateHint =" ReadOnly ";' Combinado con el archivo ReadOnly.ascx en mi publicación, esto debería hacer que el atributo ReadOnly (verdadero) funcione como lo haría esperar. ASP.NET MVC rocas! – pwhe23

+1

Sé que esto es viejo, pero la técnica funciona. Sin embargo, podría hacer que se borren datos. Mi ReadOnly.cshtml es: @Model @ Html.HiddenFor (x => Model) para garantizar que siempre se devuelva el valor. – Andiih

2
<%@ Control Language="C#" Inherits="ViewUserControl<Product>" %> 

<%: Html.LabelFor(x => x.ProductID) %> 
<%: Html.TextBoxFor(x => x.ProductID, new { @readonly = true }) %> 

<%: Html.LabelFor(x => x.Name) %> 
<%: Html.TextBoxFor(x => x.Name) %> 
Cuestiones relacionadas