Подтвердить что ты не робот

Классы в шаблоне двигателя бритвы

Можно ли создавать классы внутри шаблона? Что-то вроде...

@{
    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 в шаблоне. Я не могу выполнить десерилизацию перед рукой и вставить ее в модель, потому что классы могут меняться в зависимости от шаблона.

4b9b3361

Ответ 1

Я отправлю свой ответ из 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;}
    }
}

... что, конечно, недействительно С#. Другая проблема, с которой вы столкнетесь, заключается в том, что для использования сериализации/десериализации 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" определен где-то в моем приложении. Важно то, что я создаю экземпляр для каждого шаблона.

Ответ 2

Да, это вполне возможно. Используйте ключевое слово @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; }
    }
}

Ответ 3

Я бы предложил использовать определенный класс ViewModel, который мог бы иметь динамическое свойство (ExpandoObject), позволяющее вам заполнять его любой настраиваемой структурой данных по мере необходимости, при этом все еще сохраняя строго типизированное значение для всего, что может потребоваться для вашего представления.

Это также сохраняет ваши модели взглядов отдельно от самих представлений, что является хорошей практикой (html и код не слишком хорошо смешиваются с читабельностью).