2011-02-26 10 views
16

¿Es posible crear clases dentro de una plantilla? Algo así como ...Clases en la plantilla del motor de afeitar

@{ 
    public class MyClass { 
     public MyClass() { 
      Three = new List<string>(); 
     } 

     public string One { get; set; } 
     public int Two { get; set; } 
     public List<string> Three { get; set; } 
    } 
} 

Actualmente aparece la frase "No se puede compilar la plantilla. Consulte la lista de errores para obtener más información". cuando trato de hacer esto Me gustaría tomar contenido XML y usar XmlSerializer para crear una instancia de MyClass dentro de la plantilla. No puedo hacer la deserialización de antemano y meterla en el modelo porque las clases pueden variar según la plantilla.

+1

Si se pudiera pasar por alto esta no sería completamente la idea de tener modelos/views/controladores en el primer lugar? – rene

+0

¿No puedes traer 'MyClass' en un archivo separado? OK, entonces eso hará 2 archivos por plantilla, pero funcionará. –

+1

Puede desmarcar la "respuesta" y marcar la respuesta "Kirk Woll", ya que esa es la respuesta correcta. –

Respuesta

5

voy a publicar mi respuesta por parte del CodePlex Discussion aquí:

No estoy seguro de que es posible en la actualidad. Cuando usas Codeblocks (@ {}), en realidad estás escribiendo código dentro de un método, p. su código anterior haría algo como:

public void Execute() 
{ 
    this.Clear(); 
    public class MyClass { 
     public MyClass() { 
      Three = new List<string>(); 
     } 

     public string One { get; set; } 
     public int Two { get; set; } 
     public List<string> Three { get; set;} 
    } 
} 

... que por supuesto, no es válido C#. El otro problema al que se enfrentará es que para usar la serialización/deserialización de xml, debe conocerse el tipo, pero si define su tipo dentro de la plantilla, ¿cómo podría deserializarlo en primer lugar?

Lo que podría hacer, es utilizar una plantilla de base personalizado:

public class CustomTemplateBase<T> : TemplateBase<T> 
{ 
    public dynamic Instance { get; set; } 

    public dynamic CreateInstance(string typeName) 
    { 
     Type type = Type.GetType(typeName); 

     // You'd to your deserialisation here, I'm going to 
     // just cheat and return a new instance. 
     return Activator.CreateInstance(type); 
    } 
} 

El uso de una propiedad dinámica y tipo de retorno dinámico, hemos definido un método que nos permitirá crear una instancia (a través de la activación o deserialización, etc.) y llamar al acceso de miembros en él. Para usar eso en una plantilla, puede hacer:

@{ 
    Instance = CreateInstance("ConsoleApplication1.MyClass, ConsoleApplication1"); 
    Instance.One = "Hello World"; 
} 
<h1>@Instance.One</h1> 

Donde "MyClass" está definido en alguna parte de mi aplicación. Lo importante es que estoy creando una instancia por plantilla.

3

Sugeriría utilizar una clase de ViewModel específica, que podría tener una propiedad dinámica (ExpandoObject) que le permita completarla con cualquier estructura de datos personalizada según sea necesario mientras sigue comunicándose fuertemente tipada para cualquier otra cosa que su vista pueda necesitar.

Esto también mantiene sus modelos de vista separados de las vistas en sí, lo cual es una buena práctica (el código html y no se mezclan muy bien cuando la legibilidad es una preocupación).

64

Sí, esto es completamente posible. Usar la palabra clave @functions:

@functions { 
    public class MyClass { 
     public MyClass() { 
      Three = new List<string>(); 
     } 

     public string One { get; set; } 
     public int Two { get; set; } 
     public List<string> Three { get; set; } 
    } 
} 
+4

Si es una buena idea o no, es tema de debate, pero esto responde a la pregunta, por lo que me envían un voto por adelantado. (Resp. Ya que solo puedo editar las vistas en mi solución, esto es lo que necesito, a pesar del olor a código) – DarcyThomas

+3

Esto es perfecto para la situación en la que desea crear tipos de transformación intermedios pero no desea usar tipos anónimos como usted no puede pasarlos a los ayudantes de afeitar. Lamentablemente, las plataformas como Umbraco no funcionan muy bien con los enfoques de código pesado. No haría esto muy a menudo si tus controladores son perfectamente capaces de realizar todas las transformaciones necesarias en un ViewModel más concreto. –

+1

upvote.en un proyecto más grande no se suele hacer eso, pero en una matriz web pequeña normal, sería más inteligente y fácil. ¿Por qué todos los errores engreídos? –

Cuestiones relacionadas