2011-02-26 68 views
16

是否可以在模板中创建类?像...剃刀引擎模板中的类

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

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

+1

如果它不能完全绕过模型/视图/控制器的整个想法? – rene

+0

你不能把'MyClass'放到一个单独的文件中吗?好吧,这样每个模板都会生成2个文件,但它会起作用。 –

+1

你可以不选中“答案”,而选择“Kirk Woll”答案,因为这是正确的答案。 –

回答

5

我会后从这里CodePlex Discussion我的回应:

我不知道这是目前可能的。当您使用代码块(@ {})时,实际上是在代码中写入代码,例如你的上面的代码会做这样的事情:

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

......这当然是无效的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); 
    } 
} 

使用动态属性和动态的返回类型,我们定义这将让我们创建一个实例(通过激活的方法或反序列化等)并在其上调用成员访问权限。要在模板中使用它,你可以这样做:

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

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

3

我建议使用特定的ViewModel类,它可以有一个动态属性(ExpandoObject),允许您根据需要使用任何自定义数据结构来填充它,同时仍然可以强制类型化您的视图可能需要的任何其他类型。

这也保持你的视图模型与视图本身分开,这是很好的做法(html和代码在可读性是一个问题时不能混合太好)。

64

是的,这是完全可能的。使用@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

不管它是不是一个好主意,都可以进行辩论,但是这确实回答了这个问题,所以从我这里得到了赞赏。 (Ans,因为我只能编辑我的解决方案中的视图,这是我需要的;尽管有代码味道) – DarcyThomas

+3

这对于想要创建中间转换类型但不想在您使用匿名类型的情况非常适用不能将这些传递给剃刀助手。 不幸的是,像Umbraco这样的平台在代码繁重的方法中效果不佳。如果您的控制器完全能够执行所有必要的转换成更具体的ViewModel,我不会经常这样做。 –

+1

upvote。在一个较大的项目中,你通常不会那么做,但是在普通的小型网络矩阵中,它会更智能,更容易。为什么所有这些踌躇的bug? –