简体   繁体   English

剃刀引擎模板中的类

[英]Classes in razor engine template

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. 我想获取XML内容并使用XmlSerializer在模板中创建MyClass的实例。 I can't do the deserialization before hand and shove it into the model because the classes could vary depending on the template. 我不能事先进行反序列化并将其推入模型中,因为类可能因模板而异。

Yes, this is completely possible. 是的,这是完全可能的。 Use the @functions keyword: 使用@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; }
    }
}

I'll post my response from the CodePlex Discussion here: 我将在此处发布CodePlex讨论的回复:

I'm not sure that is currently possible. 我不确定目前是否可行。 When you use codeblocks (@{ }), you're actually writing code within a method, eg 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#. ...当然,这是无效的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? 您将面临的另一个问题是,使用xml序列化/反序列化,必须知道类型,但如果您在模板本身中定义类型,那么您如何首先对其进行反序列化?

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. “我的应用程序”中某处定义了“MyClass”。 The important thing is, I'm creating an instance per template. 重要的是,我正在为每个模板创建一个实例。

I would suggest using a specific ViewModel class, which could have a dynamic property (ExpandoObject) allowing you to populate it with any custom data structure as needed while still communicating strongly typed for whatever else your view might need. 我建议使用一个特定的ViewModel类,它可以有一个动态属性(ExpandoObject),允许您根据需要使用任何自定义数据结构填充它,同时仍然可以根据您的视图可能需要的其他内容进行强类型传递。

This also keeps your view models separate from the views themselves, which is good practice (html and code don't mix too well where readability is a concern). 这也使您的视图模型与视图本身分离,这是一种很好的做法(在可读性问题时,html和代码不能很好地混合)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM