2013-05-16 30 views
0

我使用通用Razor视图来允许编辑任何实体框架对象。下面是它的一个砍下版本:@ Html.Editor在使用反射属性时显示奇怪的结果

@model Object 
@using (Html.BeginForm()) 
{ 
     @foreach (var property in Model.VisibleProperties()) 
     { 
      @Html.Label(property.Name.ToSeparatedWords()) 
      @Html.Editor(property.Name, new { @class = "input-xlarge" }) 
     } 
} 

而且VisibleProperties()函数是这样的:

public static PropertyInfo[] VisibleProperties(this Object model) 
     { 
      return model.GetType().GetProperties().Where(info => 
       (info.PropertyType.IsPrimitive || info.PropertyType.Name == "String") && 
       info.Name != model.IdentifierPropertyName()).OrderedByDisplayAttr().ToArray(); 
     } 

(我是从​​重用代码)

我的一个样本控制器如下:

public ActionResult Edit(int id = 0) 
     { 
      TaskTemplate tasktemplate = db.TaskTemplates.Single(t => t.TaskTemplateID == id); 
      return View(tasktemplate); 
     } 

现在问题: 除了有一个与'父'表相关的ID属性(如UserID)之外,它一切正常。对于这些字段,@ Html.Editor的输出很简单: FalseFalseTrueFalse。

True似乎对应于有问题的用户 - 在本例中是数据库中的第4个用户。

为什么它不输出一个不错的带有数字4(或任何UserID)的文本框?

我希望我已经解释清楚。

回答

1

原因是编辑器/显示模板没有递归到复杂的子对象中。如果您希望发生这种情况,您可以编写一个自定义编辑器模板(~/Views/Shared/Object.cshtml),如Brad Wilson在this blog post(更具体地说是Shallow Dive vs. Deep Dive部分)中所示。

所以:

<table cellpadding="0" cellspacing="0" border="0"> 
@foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm))) 
{ 
    if (prop.HideSurroundingHtml) 
    { 
     @Html.Editor(prop.PropertyName) 
    } 
    else 
    { 
     <tr> 
      <td> 
       <div class="editor-label" style="text-align: right;"> 
        @(prop.IsRequired ? "*" : "") 
        @Html.Label(prop.PropertyName) 
       </div> 
      </td> 
      <td> 
       <div class="editor-field"> 
        @Html.Editor(prop.PropertyName) 
        @Html.ValidationMessage(prop.PropertyName, "*") 
       </div> 
      </td> 
     </tr> 
    } 
} 
</table> 
+0

嗯,我不知道这就是我要找的。我仍然不明白为什么它不会将FirmID显示为可编辑的整数值?毕竟,这是财产是不是?奇怪的是,我也有一个索引控制器和视图,它使用IEnumerable来显示所有的属性。在这种情况下,它工作正常并且完美地呈现整数值。 – rwalter

+0

正如我在默认情况下的回答所解释的那样,'Html.Editor'帮手不会递归到复杂的子属性中。如果您希望发生这种情况,您必须为对象类型编写自定义编辑器模板。 –

+0

对不起 - 仍然不明白!数据库中的FirmID只是一个“int”。也许问题是:如果我只想让'int'出来,我该如何阻止MVC将它看作一些复杂的值?有什么我可以使用LINQ或dbcontext来阻止这种情况发生吗?我知道这是可能的,因为我的其他代码使用了“Enumerable”对象列表。在这种情况下,'int'被正确地返回。 – rwalter