为EditorFor添加前缀以用于所有元素

时间:2013-12-19 18:22:39

标签: asp.net-mvc asp.net-mvc-5 editorfor

我有以下型号:

public class CaseFormViewModel
{
    public int ID { get; set; }
    public int AppID { get; set; }

    public CaseGeneralFormViewModel General { get; set; }

    public CaseMedicalFormViewModel Medical { get; set; }

    public CaseLegalFormViewModel Legal { get; set; }

    public CaseCommentsFormViewModel Comments { get; set; }

    public List<UploadedDocumentModel> Attachments { get; set; }

    public string AzureStorage { get; set; }

}

public class CaseGeneralFormViewModel : CaseGeneralViewModelBase
{
    [Required]
    public new string PatientName { get; set; }

我也有一个CaseFormViewModel模型的视图,并且有一个带有CaseGeneralFormViewModel模型的Partial View。视图加载此部分视图:

@Html.Partial("PartialCaseGeneralForm", Model.General)

部分视图具有以下字符串:

@Html.ValidationMessageFor(model => model.PatientName)

然后,当我将此视图发布到控制器方法时:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult UpdateCase(int AppID, CHFN.Models.CaseFormViewModel model)
    {

model.General为null。我理解为什么,因为PatientName应该有id =“General.PatientName”而不是id =“PatientName”,但是如何将该前缀添加到页面上的所有元素?

我看到了一些能力:将post controller方法修改为:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult UpdateCase(int AppID, CaseGeneralFormViewModel general)
    {

但首先,代码是脏的(内部类的结构被破坏),其次 - 任何类(即CaseGeneralFormViewModel)都可以具有同一类的2个属性(即

public Class1 Prop1 { get; set; }
public Class1 Prop2 { get; set; }

)。如何解决 - 我不知道......

2 个答案:

答案 0 :(得分:1)

解决方案是:

为Partial:

创建扩展方法
public static MvcHtmlString PartialFor<TModel, TProperty>(
      this HtmlHelper<TModel> helper,
      System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, 
      string partialViewName)

{
       var name = ExpressionHelper.GetExpressionText(expression);
       var 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.General,"PartialCaseGeneralForm")

答案 1 :(得分:0)

在asp.net核心mvc

public static class HtmlHelperPartialExtensions
{
    public static IHtmlContent PartialWithPrefix(this IHtmlHelper htmlHelper, string partialViewName, object model, string prefix)
    {
        var htmlFieldPrefix = (string.Empty.Equals(prefix) ? "." : "") + prefix;
        return htmlHelper.Partial(partialViewName, model, new ViewDataDictionary(htmlHelper.ViewData) { TemplateInfo = { HtmlFieldPrefix = htmlFieldPrefix } });
    }

    public static Task<IHtmlContent> PartialWithPrefixAsync(this IHtmlHelper htmlHelper, string partialViewName, object model, string prefix)
    {
        var htmlFieldPrefix = (string.Empty.Equals(prefix) ? "." : "") + prefix;
        return htmlHelper.PartialAsync(partialViewName, model, new ViewDataDictionary(htmlHelper.ViewData) {TemplateInfo = {HtmlFieldPrefix = htmlFieldPrefix}});
    }

    public static IHtmlContent PartialWithPrefixFor<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string partialViewName)
    {
        string prefix = ExpressionHelper.GetExpressionText(expression);
        object model = ExpressionMetadataProvider.FromLambdaExpression(expression, helper.ViewData, helper.MetadataProvider).Model;
        return PartialWithPrefix(helper, partialViewName, model, prefix);
    }

    public static Task<IHtmlContent> PartialWithPrefixForAsync<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string partialViewName)
    {
        string prefix = ExpressionHelper.GetExpressionText(expression);
        object model = ExpressionMetadataProvider.FromLambdaExpression(expression, helper.ViewData, helper.MetadataProvider).Model;
        return PartialWithPrefixAsync(helper, partialViewName, model, prefix);
    }
}