MVC3 EditorFor动态属性(或需要解决方法)
我正在构建一个提出问题并接收答案的系统。每个问题都可以有自己类型的答案。现在我们将其限制为 String
和 DateTime
。在域中,问题以以下方式表示:
public class Question
{
public int Id
{
get;
set;
}
public string Caption
{
get;
set;
}
public AnswerType
{
get;
set;
}
}
,其中 AnswerType
是
enum AnswerType
{
String,
DateTime
}
请注意,实际上我有更多的答案类型。
我提出了创建一个 MVC 模型的想法,该模型源自 Question 并向其中添加 Answer 属性。所以它必须是这样的:
public class QuestionWithAnswer<TAnswer> : Question
{
public TAnswer Answer
{
get;
set;
}
}
问题就从这里开始。我想要一个通用视图来绘制任何问题,所以它需要是这样的:
@model QuestionWithAnswer<dynamic>
<span>@Model.Caption</span>
@Html.EditorFor(m => m.Answer)
对于 String
我想在这里有简单的输入,对于 DateTime
我要去来定义我自己的观点。我可以从控制器传递具体模型。但问题是,在渲染阶段,它自然无法确定 Answer 的类型,特别是如果它最初为 null
(默认为 String
),因此 EditorFor
不会为 String
绘制任何内容,也不会为 DateTime
中的所有属性绘制输入。
我确实理解问题的本质,但是有什么优雅的解决方法吗?或者我必须实现自己的逻辑来根据控件类型选择编辑器视图名称(又大又丑的 switch
)?
I am building a system which asks questions and receives answers to them. Each question can have an aswer of its own type. Let's limit it to String
and DateTime
for now. In Domain, question is represented the following way:
public class Question
{
public int Id
{
get;
set;
}
public string Caption
{
get;
set;
}
public AnswerType
{
get;
set;
}
}
, where AnswerType
is
enum AnswerType
{
String,
DateTime
}
Please note that actually I have much more answer types.
I came up with an idea of creating a MVC model, deriving from Question and adding Answer property to it. So it has to be something like this:
public class QuestionWithAnswer<TAnswer> : Question
{
public TAnswer Answer
{
get;
set;
}
}
And here start the problems. I want to have a generic view to draw any question, so it needs to be something like that:
@model QuestionWithAnswer<dynamic>
<span>@Model.Caption</span>
@Html.EditorFor(m => m.Answer)
For String
I want to have simple input here, for DateTime
I am going to define my own view. I can pass the concrete model from the controller. But the problem is that on the rendering stage, naturally, it cannot determine the type of Answer, especially if it is initially null
(default for String
), so EditorFor
draws nothing for String
and inputs for all properties in DateTime
.
I do understand the nature of the problem, but is there any elegant workaround? Or I have to implement my own logic for selecting editor view name basing on control type (big ugly switch
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我个人不喜欢这样:
我更喜欢使用 .NET 类型系统。让我向您推荐一种替代设计。一如既往,我们首先定义视图模型:
然后是控制器:
然后是主
Index.cshtml
视图:现在我们可以为我们的答案提供编辑器模板:
~/Views/Home/EditorTemplates /StringAnswer.cshtml
:~/Views/Home/EditorTemplates/DateAnswer.cshtml
:最后一块是我们答案的自定义模型绑定器:
它将注册在
Application_Start
:Personally I don't like this:
I prefer using .NET type system. Let me suggest you an alternative design. As always we start by defining out view models:
then a controller:
then the main
Index.cshtml
view:and now we can have editor templates for our answers:
~/Views/Home/EditorTemplates/StringAnswer.cshtml
:~/Views/Home/EditorTemplates/DateAnswer.cshtml
:and the last piece is a custom model binder for our answers:
which will be registered in
Application_Start
:您仍然可以使用 Html.EditorFor(..),但指定第二个参数,即编辑器模板的名称。您的 Question 对象有一个属性,即 AnswerType,因此您可以执行类似的操作...
在您的 EditorTemplates 文件夹中只需为每个 AnswerType 定义一个视图。即“String”、“DateTime”等。
编辑:就 String 的 Answer 对象为 null 而言,我会在那里放置一个占位符对象,以便“String”编辑器模板中的模型不为 null。
You can still use the Html.EditorFor(..), but specify a second parameter which is the name of the editor template. You have a property on the Question object that is the AnswerType, so you could do something like...
The in your EditorTemplates folder just define a view for each of the AnswerTypes. ie "String", "DateTime", etc.
EDIT: As far as the Answer object being null for String, i would put a placeholder object there just so the model in you "String" editor template is not null.