剃刀引擎模板中的类

Rus*_*sby 25 c# razor

是否可以在模板中创建类?就像是...

@{
    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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

目前我得到"无法编译模板.请查看错误列表以获取详细信息." 当我试着这样做的时候.我想获取XML内容并使用XmlSerializer在模板中创建MyClass的实例.我不能事先进行反序列化并将其推入模型中,因为类可能因模板而异.

Kir*_*oll 88

是的,这是完全可能的.使用@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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是否是一个好主意,是有争议的,但这确实回答了这个问题,所以从我这里投票.(因为我只能在我的解决方案中编辑视图,这就是我需要的;尽管有代码味道) (5认同)
  • 这对于您想要创建中间转换类型但不想使用匿名类型的情况非常适合,因为您无法将这些类型传递给剃刀帮助程序.可悲的是,像Umbraco这样的平台在代码密集的方法上效果不佳.如果您的控制器完全能够执行所有必需的转换到更具体的ViewModel,我不会经常这样做. (3认同)

Mat*_*ott 5

我将在这里发布我对CodePlex讨论的回复:

我不确定目前是否可行.当您使用代码块(@ {})时,您实际上是在方法中编写代码,例如您的上述代码将执行以下操作:

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;}
    }
}
Run Code Online (Sandbox Code Playgroud)

...当然,这是无效的C#.您将面临的另一个问题是,使用xml序列化/反序列化,必须知道类型,但如果您在模板本身中定义类型,那么您如何首先对其进行反序列化?

可以做的是使用自定义基本模板:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用动态属性和动态返回类型,我们已经定义了一个方法,它允许我们创建一个实例(通过激活或反序列化等)并在其上调用成员访问.要在模板中使用它,您可以执行以下操作:

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

"我的应用程序"中某处定义了"MyClass".重要的是,我正在为每个模板创建一个实例.