模型中名为 Title 的属性与视图中名为 View.Title 的属性之间的绑定冲突(在 MVC 中)
我的模型包含一个名为 Title
的属性,在我的 Create
视图中,我使用 ViewBag.Title
设置页面标题。
这会产生以下问题:Html.Editor
生成的表单将显示 ViewBag.Title
中的文本,而不是模型的 Title
值。
我发现的唯一解决方法是首先调用 Html.Editor
,然后设置 View.Title
。
有人有更好的解决方案吗?
编辑 1:我正在使用 MVC 3。
编辑 2:这是我的 DisplayTemplates/Object.cshtml
:
@model dynamic
@using Iconum.VS10CS040.Library.Web.MVC3.Helpers
@if (ViewData.TemplateInfo.TemplateDepth > 1) {
<span class="editor-object simple">@ViewData.ModelMetadata.SimpleDisplayText</span>
} else {
foreach (var prop in ViewData.ModelMetadata.Properties.Where(
pm =>
pm.ShowForEdit
&& !ViewData.TemplateInfo.Visited(pm)
&& pm.ModelType != typeof(System.Data.EntityState)
&& !pm.IsComplexType
)
)
{
if (prop.HideSurroundingHtml) {
<text>@Html.Editor(prop.PropertyName)</text>
} else {
string css = "";
if (prop.Model != null && prop.Model.GetType() != null)
{
css += " " + prop.Model.GetType().ToString().ToLower().Replace('.', '-');
}
if (prop.DataTypeName != null)
{
css += " " + prop.DataTypeName.ToLower();
}
if (prop.IsRequired && prop.ModelType.FullName != "System.Boolean")
{
css += " required";
}
<div class="editor-container @css">
<div class="editor-label">
@if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString()))
{
// Use LabelWithForThatMatchesTheIdOfTheInput instead of Label because of a bug (fixed in MVC 3)
@Html.LabelWithForThatMatchesTheIdOfTheInput(prop.PropertyName)
}
@if (prop.IsRequired && prop.ModelType.FullName != "System.Boolean")
{
@Html.Raw(" <span class=\"required\">*<span>");
}
</div>
<div class="editor-field">
@* This the line that causes my problem *@
@Html.Editor(prop.PropertyName)
@Html.ValidationMessage(prop.PropertyName)
</div>
</div>
}
} //foreach
// Loop though all items in the Model with an TemplateHint (UIHint)
foreach (var prop in ViewData.ModelMetadata.Properties.Where(
pm => pm.ShowForEdit
&& !ViewData.TemplateInfo.Visited(pm)
&& pm.ModelType != typeof(System.Data.EntityState)
&& !pm.IsComplexType
&& pm.TemplateHint != null
&& (
pm.TemplateHint == "jWYSIWYG0093"
||
pm.TemplateHint == "jQueryUIDatepicker"
||
pm.TemplateHint == "CKEditor"
)
)
)
{
// TODO: check for duplicate js file includes
@Html.Editor(prop.PropertyName, prop.TemplateHint + "-Script")
}
}
My Model contains a property named Title
, and in my Create
view I set the page title using ViewBag.Title
.
This creates the following problem: the form generated by Html.Editor
will display the text from ViewBag.Title
, instead of the model's Title
value.
The only workaround I have found is first calling Html.Editor
, and then setting the View.Title
.
Does anyone have a better solution?
Edit 1: I am using MVC 3.
Edit 2: This is my DisplayTemplates/Object.cshtml
:
@model dynamic
@using Iconum.VS10CS040.Library.Web.MVC3.Helpers
@if (ViewData.TemplateInfo.TemplateDepth > 1) {
<span class="editor-object simple">@ViewData.ModelMetadata.SimpleDisplayText</span>
} else {
foreach (var prop in ViewData.ModelMetadata.Properties.Where(
pm =>
pm.ShowForEdit
&& !ViewData.TemplateInfo.Visited(pm)
&& pm.ModelType != typeof(System.Data.EntityState)
&& !pm.IsComplexType
)
)
{
if (prop.HideSurroundingHtml) {
<text>@Html.Editor(prop.PropertyName)</text>
} else {
string css = "";
if (prop.Model != null && prop.Model.GetType() != null)
{
css += " " + prop.Model.GetType().ToString().ToLower().Replace('.', '-');
}
if (prop.DataTypeName != null)
{
css += " " + prop.DataTypeName.ToLower();
}
if (prop.IsRequired && prop.ModelType.FullName != "System.Boolean")
{
css += " required";
}
<div class="editor-container @css">
<div class="editor-label">
@if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString()))
{
// Use LabelWithForThatMatchesTheIdOfTheInput instead of Label because of a bug (fixed in MVC 3)
@Html.LabelWithForThatMatchesTheIdOfTheInput(prop.PropertyName)
}
@if (prop.IsRequired && prop.ModelType.FullName != "System.Boolean")
{
@Html.Raw(" <span class=\"required\">*<span>");
}
</div>
<div class="editor-field">
@* This the line that causes my problem *@
@Html.Editor(prop.PropertyName)
@Html.ValidationMessage(prop.PropertyName)
</div>
</div>
}
} //foreach
// Loop though all items in the Model with an TemplateHint (UIHint)
foreach (var prop in ViewData.ModelMetadata.Properties.Where(
pm => pm.ShowForEdit
&& !ViewData.TemplateInfo.Visited(pm)
&& pm.ModelType != typeof(System.Data.EntityState)
&& !pm.IsComplexType
&& pm.TemplateHint != null
&& (
pm.TemplateHint == "jWYSIWYG0093"
||
pm.TemplateHint == "jQueryUIDatepicker"
||
pm.TemplateHint == "CKEditor"
)
)
)
{
// TODO: check for duplicate js file includes
@Html.Editor(prop.PropertyName, prop.TemplateHint + "-Script")
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我建议使用
EditorFor
而不是Editor
。而不是:
这样,视图不仅可以利用您的视图模型,而且在这种情况下它的行为也符合预期。
ASP.NET MVC 3.0 RTM (Razor) 示例:
模型:
控制器:
视图:
因此,无论我们如何尝试在这里滥用,编辑器模板都会使用正确的模型标题(如果我们使用
Html.html,则情况并非如此)。编辑器(“标题”)
)。I would recommend using
EditorFor
instead ofEditor
.instead of:
This way not only that the view takes advantage of your view model but it behaves as expected in this case.
Example with ASP.NET MVC 3.0 RTM (Razor):
Model:
Controller:
View:
So no matter how much we try to abuse here the editor template uses the correct model title (which is not the case if we used
Html.Editor("Title")
).正如其他答案所建议的,使用
EditorFor
而不是Editor
似乎可以解决该问题。但是,使用EditorFor
需要在编译时了解模型类型和属性类型,而Object.cshtml
则不然。您仍然可以通过使用反射构建并调用正确的通用构造的
EditorFor
方法来实现此目的。执行此操作的代码确实很混乱,因此这里有一些可重用的扩展方法来为您执行此操作。在
Object.cshtml
中像这样使用它们,其中prop
是ModelMetadata
的实例,如问题中所示:以下是扩展方法:
As suggested by the other answers, using
EditorFor
instead ofEditor
seems to work around the problem. However, usingEditorFor
requires knowledge of the model type and property type at compile-time, which isn't the case forObject.cshtml
.You can still do this by building up and calling the correct generically-constructed
EditorFor
method using reflection. The code to do this is really messy, so here are some re-usable extension methods to do it for you.Use them like this in
Object.cshtml
whereprop
is an instance ofModelMetadata
like in the question:Here are the extension methods:
我自己找到了部分解决方案。
只需使用:
而不是:
Html.EditorForModel() 方法返回相同的结果,但没有描述的问题。
I found partial solution myself.
Just use:
instead of:
Html.EditorForModel() method return same results, but without described problem.
我解决同样的问题。使用此语法代替 Html.Editor
I solve same problem. Use this syntax instead Html.Editor