Asp.net mvc 我的模型中名为Title的属性与视图中名为Title的属性之间的绑定冲突。我的视图中的Title(在MVC中)
我的模型包含一个名为Asp.net mvc 我的模型中名为Title的属性与视图中名为Title的属性之间的绑定冲突。我的视图中的Title(在MVC中),asp.net-mvc,razor,model,conflict,Asp.net Mvc,Razor,Model,Conflict,我的模型包含一个名为Title的属性,在我的Create视图中,我使用ViewBag.Title设置页面标题 这会产生以下问题:由Html.Editor生成的表单将显示ViewBag.Title中的文本,而不是模型的Title值 我找到的唯一解决方法是首先调用Html.Editor,然后设置视图.Title 有谁有更好的解决方案吗 编辑1:我正在使用MVC3 编辑2:这是我的显示模板/Object.cshtml: @model dynamic @using Iconum.VS10CS040.Li
Title
的属性,在我的Create
视图中,我使用ViewBag.Title
设置页面标题
这会产生以下问题:由Html.Editor
生成的表单将显示ViewBag.Title
中的文本,而不是模型的Title
值
我找到的唯一解决方法是首先调用Html.Editor
,然后设置视图.Title
有谁有更好的解决方案吗
编辑1:我正在使用MVC3
编辑2:这是我的显示模板/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")
}
}
@模型动态
@使用Iconum.VS10CS040.Library.Web.MVC3.Helpers
@如果(ViewData.TemplateInfo.TemplateDepth>1){
@ViewData.ModelMetadata.SimpleDisplayText
}否则{
foreach(ViewData.ModelMetadata.Properties.Where中的var prop(
pm=>
ShowForEdit下午
&&!ViewData.TemplateInfo.Visited(下午)
&&pm.ModelType!=typeof(System.Data.EntityState)
&&!pm.IsComplexType
)
)
{
if(项目隐藏周围TML){
@编辑器(prop.PropertyName)
}否则{
字符串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+=“必需”;
}
@如果(!String.IsNullOrEmpty(Html.Label(prop.PropertyName.ToHtmlString()))
{
//使用LabelWithforthatMatchestHeidOfInput代替Label,因为有一个bug(在MVC 3中修复)
@Html.labelWithForthatMatchestHeidOfInput(prop.PropertyName)
}
@if(prop.IsRequired&&prop.ModelType.FullName!=“System.Boolean”)
{
@Html.Raw(“*”);
}
@*这就是引起我问题的原因*@
@编辑器(prop.PropertyName)
@Html.ValidationMessage(prop.PropertyName)
}
}//foreach
//使用TemplateHint(UIHint)循环遍历模型中的所有项
foreach(ViewData.ModelMetadata.Properties.Where中的var prop(
pm=>pm.ShowForEdit
&&!ViewData.TemplateInfo.Visited(下午)
&&pm.ModelType!=typeof(System.Data.EntityState)
&&!pm.IsComplexType
&&pm.TemplateHint!=null
&& (
pm.TemplateHint==“jWYSIWYG0093”
||
pm.TemplateHint==“jQueryUIDatepicker”
||
pm.TemplateHint==“CKEditor”
)
)
)
{
//TODO:检查重复的js文件包括
@编辑器(prop.PropertyName、prop.TemplateHint+“-Script”)
}
}
我建议使用EditorFor
而不是Editor
Html.EditorFor(x => x.Title)
而不是:
Html.Editor("Title")
@foreach (var property in Model.GetMetadata().Properties)
{
<div class="editor-label">
@Html.Label(property.PropertyName)
</div>
<div class="editor-field">
@Html.Editor(property.PropertyName)
@Html.ValidationMessage(property.PropertyName)
</div>
}
这样,视图不仅可以利用您的视图模型,而且在这种情况下,它的行为与预期的一样
ASP.NET MVC 3.0 RTM(Razor)示例:
型号:
public class MyViewModel
{
public string Title { get; set; }
}
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "ViewBag title";
ViewData["Title"] = "ViewData title";
var model = new MyViewModel
{
Title = "Model title"
};
return View(model);
}
}
视图:
因此,无论我们在这里如何滥用,编辑器模板都使用了正确的模型标题(如果我们使用
Html.editor(“标题”)
,则情况并非如此)。我自己找到了部分解决方案
只需使用:
@Html.EditorForModel()
而不是:
Html.Editor("Title")
@foreach (var property in Model.GetMetadata().Properties)
{
<div class="editor-label">
@Html.Label(property.PropertyName)
</div>
<div class="editor-field">
@Html.Editor(property.PropertyName)
@Html.ValidationMessage(property.PropertyName)
</div>
}
@foreach(Model.GetMetadata().Properties中的var属性)
{
@Html.Label(property.PropertyName)
@编辑器(property.PropertyName)
@Html.ValidationMessage(property.PropertyName)
}
EditorForModel()方法返回相同的结果,但没有描述的问题。我解决了相同的问题。使用此语法代替Html.Editor
@(Html.EditorFor(p => property.Model))
正如其他答案所建议的,使用
EditorFor
而不是Editor
似乎可以解决这个问题。但是,使用EditorFor
需要在编译时了解模型类型和属性类型,而Object.cshtml
则不是这样
您仍然可以通过使用反射构建并调用正确的泛型构造的EditorFor
方法来实现这一点。执行此操作的代码非常凌乱,因此这里有一些可重用的扩展方法可供您使用
在Object.cshtml
中这样使用它们,其中prop
是ModelMetadata
的一个实例,如问题中所示:
@Html.DisplayFor(prop)
@Html.LabelFor(prop)
@Html.EditorFor(prop)
@Html.ValidationMessageFor(prop)
以下是扩展方法:
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
namespace ASP
{
public static class NonStronglyTypedStronglyTypedHtmlHelpers
{
public static MvcHtmlString DisplayFor<TModel>(this HtmlHelper<TModel> html, ModelMetadata prop)
{
return StronglyTypedHelper(html, h => h.DisplayFor, prop);
}
public static MvcHtmlString EditorFor<TModel>(this HtmlHelper<TModel> html, ModelMetadata prop)
{
return StronglyTypedHelper(html, h => h.EditorFor, prop);
}
public static MvcHtmlString LabelFor<TModel>(this HtmlHelper<TModel> html, ModelMetadata prop)
{
return StronglyTypedHelper(html, h => h.LabelFor, prop);
}
public static MvcHtmlString ValidationMessageFor<TModel>(this HtmlHelper<TModel> html, ModelMetadata prop)
{
return StronglyTypedHelper(html, h => h.ValidationMessageFor, prop);
}
private static MvcHtmlString StronglyTypedHelper(HtmlHelper html, Func<HtmlHelper<object>, GenericHelper<object>> accessMethod, ModelMetadata prop)
{
var constructedMethod = MakeStronglyTypedHelper(html, accessMethod, prop);
var genericPropertyExpression = MakePropertyExpression(prop);
var typedHtmlHelper = MakeStronglyTypedHtmlHelper(html, prop.ContainerType);
return (MvcHtmlString)constructedMethod.Invoke(null, new object[] { typedHtmlHelper, genericPropertyExpression });
}
private static MethodInfo MakeStronglyTypedHelper(HtmlHelper html, Func<HtmlHelper<object>, GenericHelper<object>> accessMethod, ModelMetadata prop)
{
var objectTypeHelper = new HtmlHelper<object>(html.ViewContext, html.ViewDataContainer, html.RouteCollection);
var runMethod = accessMethod(objectTypeHelper);
var constructedMehtod = runMethod.Method;
var genericHelperDefinition = constructedMehtod.GetGenericMethodDefinition();
return genericHelperDefinition.MakeGenericMethod(prop.ContainerType, prop.ModelType);
}
private static object MakeStronglyTypedHtmlHelper(HtmlHelper html, Type type)
{
var genericTypeDefinition = typeof(HtmlHelper<>);
var constructedType = genericTypeDefinition.MakeGenericType(type);
var constructor = constructedType.GetConstructor(new[] { typeof(ViewContext), typeof(IViewDataContainer), typeof(RouteCollection) });
return constructor.Invoke(new object[] { html.ViewContext, html.ViewDataContainer, html.RouteCollection });
}
private static LambdaExpression MakePropertyExpression(ModelMetadata prop)
{
var propertyInfo = prop.ContainerType.GetProperty(prop.PropertyName);
var expressionParameter = Expression.Parameter(prop.ContainerType);
var propertyExpression = Expression.MakeMemberAccess(expressionParameter, propertyInfo);
return Expression.Lambda(propertyExpression, expressionParameter);
}
private delegate MvcHtmlString GenericHelper<TModel>(Expression<Func<TModel, object>> expression);
}
}
使用系统;
使用System.Linq.Expressions;
运用系统反思;
使用System.Web.Mvc;
使用System.Web.Mvc.Html;
使用System.Web.Routing;
命名空间ASP
{
公共静态类NonStronglyTypedStronglyTypedHtmlHelpers
{
公共静态MvcHtmlString DisplayFor(此HtmlHelper html,ModelMetadata prop)
{
返回StronglyTypedHelper(html,h=>h.DisplayFor,prop);
}
公共静态MvcHtmlString编辑器(此HtmlHelper html,ModelMetadata prop)
{
返回StronglyTypedHelper(html,h=>h.EditorFor,prop);
}
公共静态MvcHtmlString LabelFor(此HtmlHelper html,ModelMetadata prop)
{
返回StronglyTypedHelper(html,h=>h.LabelFor,prop);
}
public static MvcHtmlString ValidationMessageFor(此HtmlHelper html,ModelMetadata prop)
{
返回街