【问题标题】:Classes in razor engine templateRazor 引擎模板中的类
【发布时间】:2013-10-28 22:01:51
【问题描述】:

是否可以在模板中创建类?比如……

@{
    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 的实例。我无法事先进行反序列化并将其推入模型中,因为类可能因模板而异。

【问题讨论】:

  • 如果这不能完全绕过首先拥有模型/视图/控制器的整个想法?
  • 你不能把MyClass 放到一个单独的文件中吗?好的,这样每个模板会生成 2 个文件,但它会起作用。
  • 您能否取消选中“答案”并改为选中“Kirk Woll”答案,因为那是正确答案。
  • @rene you 和 Vilx 都适用于一般清洁开发问题,但在我的情况下,我需要填写一个问题的在线重现,所以我必须将所有内容放在一个视图中,包括我的模型类定义。它也可以用于快速测试。柯克沃尔给出了我正在寻找的答案。

标签: c# razor


【解决方案1】:

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

【讨论】:

  • 这是否是一个好主意,还有待商榷,但这确实回答了这个问题,所以请支持我。 (Ans,因为我只能在我的解决方案中编辑视图,这就是我需要的;尽管代码有异味)
  • 这非常适合您想要创建中间转换类型但又不想使用匿名类型的情况,因为您无法将它们传递给 razor 助手。遗憾的是,像 Umbraco 这样的平台不能很好地处理大量代码的方法。如果您的控制器完全能够执行所有需要的转换为更具体的 ViewModel,我不会经常这样做。
  • 点赞。在较大的项目中,您通常不会这样做,但在普通的小型 Web 矩阵的东西上,它会更聪明、更容易。为什么所有自鸣得意的错误?
  • 赞成并同意@DarcyThomas 和其他人的保留意见/cmets。
  • 谢谢。对测试非常有用。
【解决方案2】:

我将在此处发布来自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 和代码不要混合得很好)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 2016-09-04
      相关资源
      最近更新 更多