MVC4 ViewData.TemplateInfo.HtmlFieldPrefix生成一个额外的点

时间:2014-09-08 08:18:21

标签: asp.net-mvc-4 razor-2

我正在尝试输入正确的名称,以便我的视图模型上的对象集合可以被绑定。

   @{ViewData.TemplateInfo.HtmlFieldPrefix = listName;}
            @Html.EditorFor(m => m, "DoubleTemplate", new { 
                Name = listName,
                Index = i,
                Switcher = (YearOfProgram >= i +1)
            })

正如您在此处所见,我将“listName”作为模板的前缀传递。 listName =“MyItems”的值

这是我的模板:

@model Web.Models.ListElement

@if (ViewData["Switcher"] != null)
{

    var IsVisible = (bool)ViewData["Switcher"];
    var index = (int)ViewData["Index"];
    var thisName = (string)ViewData["Name"] + "[" + index + "].Value";
    var thisId = (string)ViewData["Name"] + "_" + index + "__Value";
    if (IsVisible)
    {
        @*<input type="text" value="@Model.Value" name="@thisName" id ="@thisId" class="cell@(index + 1)"/>*@
        @Html.TextBoxFor(m => m.Value, new { @class ="cell" + (index + 1)})
        @Html.ValidationMessageFor(m => m.Value)
    }
}

但我发现生成的名称变为this-&gt; 的 MyItems。[0]。价值

它有一个额外的 DOT

谁能告诉我如何摆脱它?

顺便说一下,我试图在模板中手动指定名称,发现名称被Html助手覆盖。

所以请帮忙解决如何摆脱额外的点。

由于


更新

hi @StephenMuecke我必须手动设置HtmlFieldPrefix的原因是当MyItems从主视图传递到局部视图时,属性名称(MyItems是一个对象列表)将会丢失。到那时,部分视图称为我的模板并传递给MyItems中的一个对象,模板本身无法找出MyItems的名称,因为它自上次“传入”以来已经丢失。这就是我必须手动设置html字段前缀名称的原因。我甚至尝试使用类似于反射的东西(但不是重新选择,我忘了名字)来检查传入对象的名称,发现它返回“模型”。

我希望我的解释对你有意义。


更新2

我尝试过Stephen的方法,但找不到html助手PartialFor()。

enter image description here

我甚至试图在我的主视图中使用它:

Html.Partial(Model, "_MyPartialView");

在部分视图中:

@model MvcApplication1.Models.MyModel
<h2>My Partial View</h2>


@Html.EditorFor(m => m.MyProperty)

这是我的模板:

@model  MvcApplication1.Models.ListElement

@Html.TextBoxFor(m => m.Value)

这是我的模特:

 public class MyModel
    {
        private List<ListElement> myProperty;
        public List<ListElement> MyProperty
        {
            get
            {
                if (myProperty == null)
                {
                    this.myProperty = new List<ListElement>() { new ListElement() { Value = 12 }, new ListElement() { Value = 13 }, new ListElement() { Value = 14 }, new ListElement() { Value = 15 }, };
                }
                return this.myProperty;
            }
            set
            {
                this.myProperty = value;
            }
        }
    }

    public class ListElement
    {
        [Range(0, 999)]
        public double Value { get; set; }
    }

这是我的控制器:

public ActionResult MyAction()
{
    return View(new MyModel());
}

它只为我生成原始文本(“12131415”),而不是用12 13 14 15

填写的通缉文本框

但是如果我指定了模板名称,那么它会抛出一个异常,说模板视图需要ListElement,并且不能将List转换为ListElement。

4 个答案:

答案 0 :(得分:6)

无需设置HtmlFieldPrefix值。如果您根据属性类型使用EditorTemplate(并且没有模板名称),MVC将正确命名元素。

假设模型

public class ListElement
{
  public string Value { get; set; }
  ....
}

public class MyViewModel
{
  public IEnumerable<ListElement> MyItems { get; set; }
  ....
}

编辑模板(ListElement.cshtml

@model YourAssembly.ListElement
@Html.TextBoxFor(m => m.Value)

主视图

@model YourAssembly.MyViewModel
...
@Html.EditorFor(m => m.MyItems) // note do not specify the template name

这将呈现

<input type="text" name="MyItems[0].Value" ...>
<input type="text" name="MyItems[1].Value" ...>
....

如果你想使用partial来做这件事,你可以将整个模型传递给部分

MyPartial.cshtml

@model @model YourAssembly.MyViewModel
@Html.EditorFor(m => m.MyItems)

并在主视图中

@Html.Partial("MyPartial")

或创建扩展方法

public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
  Expression<Func<TModel, TProperty>> expression, string partialViewName)
  {
    string name = ExpressionHelper.GetExpressionText(expression);
    object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
    var viewData = new ViewDataDictionary(helper.ViewData)
    {
      TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = name }
    };
    return helper.Partial(partialViewName, model, viewData);
  }
}

并用作

@Html.PartialFor(m => m.MyItems, "MyPartial")

和部分

@model IEnumerable<YourAssembly.ListElement>
@Html.EditorFor(m => m)

答案 1 :(得分:2)

  1. 以这种方式打电话给你的部分:
  2. @Html.Partial("_SeatTypePrices", Model.SeatTypePrices, new ViewDataDictionary
    {
        TemplateInfo = new TemplateInfo() {HtmlFieldPrefix = nameof(Model.SeatTypePrices)}
    })
    1. 部分观点:
    2. @model List
      @Html.EditorForModel()
      1. 编辑模板实施:

        @using Cinema.Web.Helpers
        @model Cinema.DataAccess.SectorTypePrice
        @Html.TextBoxFor(x => Model.Price)
        
      2. 这样,您的部分视图将包含带前缀的项目列表。 然后从EditorForModel()文件夹中拨打EditorTemplates

答案 2 :(得分:0)

我发现我可以在模板中更改HtmlFeildPrefix的值。

所以我解决问题的方法就是直接在模板中为HtmlFeildPrefix分配正确的值,而不是在调用模板的页面中。

我希望它有所帮助。

答案 3 :(得分:0)

如果我想传递HtmlFieldPrefix,请使用以下构造:

<div id="_indexmeetpunttoewijzingen">
    @Html.EditorFor(model => model.MyItems, new ViewDataDictionary()
    {
        TemplateInfo = new TemplateInfo()
        {
            HtmlFieldPrefix = "MyItems"
        }
    })
</div>