Asp.net mvc Stronglytyped html帮助程序,具有不同的get和post模型

Asp.net mvc Stronglytyped html帮助程序,具有不同的get和post模型,asp.net-mvc,Asp.net Mvc,如果Get操作返回带有“汽车”模型的视图。该视图显示来自对象的信息,并将表单中的输入发布到另一个采取“付款”类型对象的操作 视图上的模型是Car类型的,为我提供了强类型的html支持和一些其他功能,如displaytext。但是对于发布I,没有像TextBox(x=>x.amount)这样的Htmlhelper支持,我需要将其设置为@Html.TextBox(“amount”。。。 这是可能的,但这是唯一的选择吗?您可以这样做: @{ var paymentHtml = Html.HtmlHel

如果Get操作返回带有“汽车”模型的视图。该视图显示来自对象的信息,并将表单中的输入发布到另一个采取“付款”类型对象的操作

视图上的模型是Car类型的,为我提供了强类型的html支持和一些其他功能,如displaytext。但是对于发布I,没有像TextBox(x=>x.amount)这样的Htmlhelper支持,我需要将其设置为@Html.TextBox(“amount”。。。 这是可能的,但这是唯一的选择吗?

您可以这样做:

@{
var paymentHtml = Html.HtmlHelperFor<Payment>();
}

@paymentHtml.EditorFor(p => p.Amount)
@{
var paymentHtml=Html.htmlhelperforf();
}
@paymentHtml.EditorFor(p=>p.Amount)
使用此扩展方法:

public static class HtmlHelperFactoryExtensions {

   public static HtmlHelper<TModel> HtmlHelperFor<TModel>(this HtmlHelper htmlHelper) {
      return HtmlHelperFor(htmlHelper, default(TModel));
   }

   public static HtmlHelper<TModel> HtmlHelperFor<TModel>(this HtmlHelper htmlHelper, TModel model) {
      return HtmlHelperFor(htmlHelper, model, null);
   }

   public static HtmlHelper<TModel> HtmlHelperFor<TModel>(this HtmlHelper htmlHelper, TModel model, string htmlFieldPrefix) {

      var viewDataContainer = CreateViewDataContainer(htmlHelper.ViewData, model);

      TemplateInfo templateInfo = viewDataContainer.ViewData.TemplateInfo;

      if (!String.IsNullOrEmpty(htmlFieldPrefix))
         templateInfo.HtmlFieldPrefix = templateInfo.GetFullHtmlFieldName(htmlFieldPrefix);

      ViewContext viewContext = htmlHelper.ViewContext;
      ViewContext newViewContext = new ViewContext(viewContext.Controller.ControllerContext, viewContext.View, viewDataContainer.ViewData, viewContext.TempData, viewContext.Writer);

      return new HtmlHelper<TModel>(newViewContext, viewDataContainer, htmlHelper.RouteCollection);
   }

   static IViewDataContainer CreateViewDataContainer(ViewDataDictionary viewData, object model) {

      var newViewData = new ViewDataDictionary(viewData) {
         Model = model
      };

      newViewData.TemplateInfo = new TemplateInfo { 
         HtmlFieldPrefix = newViewData.TemplateInfo.HtmlFieldPrefix 
      };

      return new ViewDataContainer {
         ViewData = newViewData
      };
   }

   class ViewDataContainer : IViewDataContainer {

      public ViewDataDictionary ViewData { get; set; }
   }
}
公共静态类HtmlHelperFactoryExtensions{
公共静态HtmlHelper HtmlHelperFor(此HtmlHelper HtmlHelper){
返回HtmlHelperFor(htmlHelper,默认值(TModel));
}
公共静态HtmlHelper HtmlHelperFor(此HtmlHelper HtmlHelper,TModel模型){
返回HtmlHelpPerf(htmlHelper,model,null);
}
公共静态HtmlHelper HtmlHelperFor(此HtmlHelper HtmlHelper,TModel模型,字符串htmlFieldPrefix){
var viewDataContainer=CreateViewDataContainer(htmlHelper.ViewData,模型);
TemplateInfo TemplateInfo=viewDataContainer.ViewData.TemplateInfo;
如果(!String.IsNullOrEmpty(htmlFieldPrefix))
templateInfo.HtmlFieldPrefix=templateInfo.GetFullHtmlFieldName(HtmlFieldPrefix);
ViewContext ViewContext=htmlHelper.ViewContext;
ViewContext newViewContext=新的ViewContext(ViewContext.Controller.ControllerContext,ViewContext.View,viewDataContainer.ViewData,ViewContext.TempData,ViewContext.Writer);
返回新的HtmlHelper(newViewContext、viewDataContainer、HtmlHelper.RouteCollection);
}
静态IViewDataContainer CreateViewDataContainer(ViewDataDictionary viewData,对象模型){
var newViewData=新ViewDataDictionary(viewData){
模型
};
newViewData.TemplateInfo=新的TemplateInfo{
HtmlFieldPrefix=newViewData.TemplateInfo.HtmlFieldPrefix
};
返回新的ViewDataContainer{
ViewData=newViewData
};
}
类ViewDataContainer:IViewDataContainer{
公共ViewDataDictionary ViewData{get;set;}
}
}

如果我正确理解您的问题,请尝试:

@Html.EditorFor(x => x.Amount)
您还可以为付款创建编辑器模板。有关此操作的详细信息,请参阅


如果我有误解,一些示例代码可能会有所帮助。

如果我正确理解了您的问题,以下是我为我的一个项目编写的一些代码,用于执行类似的操作。它不需要像Max Toro建议的任何特殊功能

@{
    var teamHelper = new HtmlHelper<Team>(ViewContext, this);
}

@using (teamHelper.BeginForm())
{
    @teamHelper.LabelFor(p => p.Name)
    @teamHelper.EditorFor(p => p.Name)  
}
@{
var teamHelper=newhtmlhelper(ViewContext,this);
}
@使用(teamHelper.BeginForm())
{
@LabelFor(p=>p.Name)
@teamHelper.EditorFor(p=>p.Name)
}

添加到Max Toro的实现中,当您有一个非空模型但没有静态类型信息时(这两个方法需要嵌入到Max提供的实现中),这里还有一些方法

当您动态检索了模型的属性名称,并且需要调用采用名称而不是表达式的非泛型HtmlHelper方法时,这些方法可以很好地工作:

@Html.TextBox(propertyName)
比如说

    public static HtmlHelper HtmlHelperFor( this HtmlHelper htmlHelper, object model )
    {
        return HtmlHelperFor( htmlHelper, model, null );
    }

    public static HtmlHelper HtmlHelperFor( this HtmlHelper htmlHelper, object model, string htmlFieldPrefix )
    {
        var t = model.GetType();
        var viewDataContainer = CreateViewDataContainer( htmlHelper.ViewData, model );

        TemplateInfo templateInfo = viewDataContainer.ViewData.TemplateInfo;

        if( !String.IsNullOrEmpty( htmlFieldPrefix ) )
            templateInfo.HtmlFieldPrefix = templateInfo.GetFullHtmlFieldName( htmlFieldPrefix );

        ViewContext viewContext = htmlHelper.ViewContext;
        ViewContext newViewContext = new ViewContext( viewContext.Controller.ControllerContext, viewContext.View, viewDataContainer.ViewData, viewContext.TempData, viewContext.Writer );

        var gt = typeof( HtmlHelper<> ).MakeGenericType( t );

        return Activator.CreateInstance( gt, newViewContext, viewDataContainer, htmlHelper.RouteCollection ) as HtmlHelper;
    }
公共静态HtmlHelper HtmlHelperFor(此HtmlHelper HtmlHelper,对象模型)
{
返回HtmlHelpPerf(htmlHelper,model,null);
}
公共静态HtmlHelper HtmlHelperFor(此HtmlHelper HtmlHelper,对象模型,字符串htmlFieldPrefix)
{
var t=model.GetType();
var viewDataContainer=CreateViewDataContainer(htmlHelper.ViewData,模型);
TemplateInfo TemplateInfo=viewDataContainer.ViewData.TemplateInfo;
如果(!String.IsNullOrEmpty(htmlFieldPrefix))
templateInfo.HtmlFieldPrefix=templateInfo.GetFullHtmlFieldName(HtmlFieldPrefix);
ViewContext ViewContext=htmlHelper.ViewContext;
ViewContext newViewContext=新的ViewContext(ViewContext.Controller.ControllerContext,ViewContext.View,viewDataContainer.ViewData,ViewContext.TempData,ViewContext.Writer);
var gt=typeof(HtmlHelper).MakeGenericType(t);
将Activator.CreateInstance(gt、newViewContext、viewDataContainer、htmlHelper.RouteCollection)作为htmlHelper返回;
}
用于ASP.NET核心2

public static class HtmlHelperFactoryExtensions
{
    public static IHtmlHelper<TModel> HtmlHelperFor<TModel>(this IHtmlHelper htmlHelper)
    {
        return HtmlHelperFor(htmlHelper, default(TModel));
    }

    public static IHtmlHelper<TModel> HtmlHelperFor<TModel>(this IHtmlHelper htmlHelper, TModel model)
    {
        return HtmlHelperFor(htmlHelper, model, null);
    }

    public static IHtmlHelper<TModel> HtmlHelperFor<TModel>(this IHtmlHelper htmlHelper, TModel model, string htmlFieldPrefix)
    {
        ViewDataDictionary<TModel> newViewData;
        var runtimeType = htmlHelper.ViewData.ModelMetadata.ModelType;
        if (runtimeType != null && typeof(TModel) != runtimeType && typeof(TModel).IsAssignableFrom(runtimeType))
        {
            newViewData = new ViewDataDictionary<TModel>(htmlHelper.ViewData, model);
        }
        else
        {
            newViewData = new ViewDataDictionary<TModel>(htmlHelper.MetadataProvider, new ModelStateDictionary())
            {
                Model = model
            };
        }

        if (!String.IsNullOrEmpty(htmlFieldPrefix))
            newViewData.TemplateInfo.HtmlFieldPrefix = newViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldPrefix);

        ViewContext newViewContext = new ViewContext(htmlHelper.ViewContext, htmlHelper.ViewContext.View, newViewData, htmlHelper.ViewContext.Writer);

        var newHtmlHelper = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IHtmlHelper<TModel>>();
        ((HtmlHelper<TModel>)newHtmlHelper).Contextualize(newViewContext);
        return newHtmlHelper;
    }
}
公共静态类HtmlHelperFactoryExtensions
{
公共静态IHtmlHelper HtmlHelperFor(此IHtmlHelper htmlHelper)
{
返回HtmlHelperFor(htmlHelper,默认值(TModel));
}
公共静态IHtmlHelper HtmlHelperFor(此IHtmlHelper htmlHelper,TModel模型)
{
返回HtmlHelpPerf(htmlHelper,model,null);
}
公共静态IHtmlHelper HtmlHelperFor(此IHtmlHelper htmlHelper,TModel模型,字符串htmlFieldPrefix)
{
ViewDataDictionary newViewData;
var runtimeType=htmlHelper.ViewData.ModelMetadata.ModelType;
if(runtimeType!=null&&typeof(TModel)!=runtimeType&&typeof(TModel)。IsAssignableFrom(runtimeType))
{
newViewData=新的ViewDataDictionary(htmlHelper.ViewData,模型);
}
其他的
{
newViewData=new ViewDataDictionary(htmlHelper.MetadataProvider,new ModelStateDictionary())
{
模型
};
}
如果(!String.IsNullOrEmpty(htmlFieldPrefix))
newViewData.TemplateInfo.HtmlFieldRefix=newViewData.TemplateInfo.GetFullHtmlFieldName(HtmlFieldRefix);
ViewContext newViewContext=新的ViewContext(htmlHelper.ViewContext,htmlHelper.ViewContext.View,newViewData,htmlHelper.ViewContext.Writer);
var newHtmlHelper=htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService();
((HtmlHelper)newHtmlHelper).上下文化(newViewContext);
返回newHtmlHelper;
}
}

最干净的解决方案。效果很好。