Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Classes in razor engine template

Tags:

c#

razor

Is it possible to create classes within a template? Something like...

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

Currently I get "Unable to compile template. Check the Errors list for details." when I try to do this. I would like to take XML content and use XmlSerializer to create an instance of MyClass within the template. I can't do the deserialization before hand and shove it into the model because the classes could vary depending on the template.

like image 929
Rush Frisby Avatar asked Feb 26 '11 20:02

Rush Frisby


People also ask

How do you use a class in Razor view?

Just use a view model. If you are, you can make List<ObjectData> part of it. In your controller, you load up that list (lets call it ObjectDataList ), and send it to your view.

What is Razor template?

Razor is a templating engine that was introduced with ASP.NET MVC, originally to run on the server and generate HTML to be served to web browsers. The Razor templating engine extends standard HTML syntax with C# so that you can express the layout and incorporate CSS stylesheets and JavaScript easily.

What is razor engine in C#?

Razor is a markup syntax that lets you embed server-based code into web pages using C# and VB.Net. It is not a programming language. It is a server side markup language. Razor has no ties to ASP.NET MVC because Razor is a general-purpose templating engine. You can use it anywhere to generate output like HTML.

What is Razor syntax?

Razor is a markup syntax for embedding . NET based code into webpages. The Razor syntax consists of Razor markup, C#, and HTML. Files containing Razor generally have a . cshtml file extension.


Video Answer


2 Answers

Yes, this is completely possible. Use the @functions keyword:

@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; }     } } 
like image 116
Kirk Woll Avatar answered Oct 18 '22 19:10

Kirk Woll


I'll post my response from the CodePlex Discussion here:

I'm not sure that is currently possible. When you use codeblocks (@{ }), you're actually writing code within a method, e.g. your above code would do something like:

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

...which of course, is not valid C#. The other problem you will face, is that to use xml serialisation/deserialisation, the type must be known, but if you are defining your type within the template itself, how could you deserialise it in the first place?

What you could do, is use a custom base template:

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

Using a dynamic property and dynamic return type, we've defined a method that will let us create an instance (through activation or deserialisation, etc.) and call member access on it. To use that in a template, you could then do:

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

Where "MyClass" is a defined somewhere in my application. The important thing is, I'm creating an instance per template.

like image 22
Matthew Abbott Avatar answered Oct 18 '22 17:10

Matthew Abbott