我遇到了我的团队和我创建的一些自定义强类型HTML帮助程序的问题。 它们所基于的自定义HTML帮助程序工作得很好,但是当我尝试使用它们的强类型版本时,它们使用Lambda表达式接受并读取模型,但是当我提交表单时,它们不会返回值。 我很确定在开发它们时我们已经错过了一些东西,因为内置的强类型Html Helpers效果很好(我使用相同的模型进行了一些测试)。
以下是我的一个自定义助手的定义:
public static MvcHtmlString Label(this HtmlHelper html, string idControl, string contenido, string alto = "", string ancho = "",
Boolean activo = true, Boolean visible = true, string tooltip = "", Color cLetra = Color.Negro, EjeZ ejeZ = EjeZ.Normal) {
TagBuilder label = new TagBuilder("label");
label.MergeAttribute("for", idControl);
//label.MergeAttribute("class", "Label");
string estilos = string.Empty;
if(alto.Length > 0) { estilos += "height:" + alto + ";"; }
if(ancho.Length > 0) { estilos += "width:" + ancho + ";"; }
if(!activo)
label.MergeAttribute("disabled", "disabled");
if(!visible) {
label.MergeAttribute("class", "Label Oculto");
} else {
label.MergeAttribute("class", "Label");
}
string letra = "none";
switch(cLetra) {
case Color.Rojo:
estilos += "color:red;";
break;
case Color.Azul:
estilos += "color:blue;";
break;
case Color.Verde:
estilos += "color:green;";
break;
default:
break;
}
label.MergeAttribute("Letra", letra);
label.MergeAttribute("style", estilos);
if(ejeZ == EjeZ.Frente) {
estilos += "z-index:" + maxEjeZ + ";";
} else if(ejeZ == EjeZ.Atras) {
estilos += "z-index:" + minEjeZ + ";";
}
label.MergeAttribute("style", estilos);
label.MergeAttribute("title", tooltip);
label.InnerHtml = contenido;
return MvcHtmlString.Create(label.ToString(TagRenderMode.Normal));
}
和我的强类型助手,它调用普通助手
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> label,
string idControl, string alto = "", string ancho = "", Boolean activo = true, Boolean visible = true,
string tooltip = "", Color cLetra = Color.Negro, EjeZ ejeZ = EjeZ.Normal) {
var name = ExpressionHelper.GetExpressionText(label);
return Label(html, idControl, name, alto, ancho, activo, visible, tooltip, cLetra, ejeZ);
}
这是我的视图(组合不接受Lambda表达式):
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
@using GridMvc.Html;
@model Consalud.ConsultaSalco.WebSite.Models.SuperModelo
<div>
@using (Html.BeginForm("VisorEventosModelo", "Test")) {
using (@Html.Grupo("gruBusqueda", "Búsqueda")) {
<div>@Html.Label("cmbTransaccion", "Transacción") @Html.Combo("cmbTransaccion", Model.transaccion)</div>
<div>@Html.Label("cmbEstadoTrans", "Estado Transacción") @Html.Combo("cbmEstadoTrans", Model.estadoTransaccion)</div>
<div>@Html.Label("numCodVenta", "Código Venta") @Html.NumeroFor(m => m.codigoVenta, "numCodVenta")</div>
<div>@Html.Label("rutBeneficiario", "Rut Beneficiario") @Html.RutFor(m => m.rutBeneficiario, "rutBeneficiario", modo: Modo.Calculo)</div>
<div>@Html.Label("cldInicio", "Inicio Vigencia") @Html.CalendarioFor(m => m.fechaInicioStr, "cldInicio")</div>
<div>@Html.Label("cldTermino", "Término Vigencia") @Html.CalendarioFor(m => m.fechaTerminoStr, "cldTermino")</div>
<button type="submit" class="Boton" value="Buscar">Buscar</button>
}
using (@Html.Grupo("grpGrilla", "Resultados")) {
@Html.Grid(Model.Eventos).AutoGenerateColumns().WithPaging(10).EmptyText("No hay datos para mostrar")
}
}
</div>
</body>
</html>
这是控制器代码
public ActionResult VisorEventosModelo() {
SuperModelo modelo = new SuperModelo();
//Cargo Dominios
svcHomologacion svc = new svcHomologacion(); //instances a WCF Service
Infrastructure.SvcHomo.Dominio[] svResultTransac = svc.ConsultaDominios("TRANSACCION", "0"); //gets the WCF service result
Infrastructure.SvcHomo.Dominio[] svResultEstado = svc.ConsultaDominios("ESTADOS SERVICIOS", "0"); //gets the WCF service result
List<Dominio> transac = new List<Dominio>();
foreach (Infrastructure.SvcHomo.Dominio d in svResultTransac) {
transac.Add(AutoMapper.Mapper.Map<Dominio>(d));
}
List<Dominio> estados = new List<Dominio>();
foreach (Infrastructure.SvcHomo.Dominio d in svResultEstado) {
estados.Add(AutoMapper.Mapper.Map<Dominio>(d));
}
foreach (Dominio d in transac) {
SelectListItem itm = new SelectListItem();
itm.Text = d.Codigo + " - " + d.Descripcion.ToUpper().Trim();
itm.Value = d.Codigo;
modelo.transaccion.Add(itm);
}
foreach (Dominio d in estados) {
SelectListItem itm = new SelectListItem();
itm.Text = d.Codigo + " - " + d.Descripcion.ToUpper().Trim();
itm.Value = d.Codigo;
modelo.estadoTransaccion.Add(itm);
}
modelo.fechaInicio = DateTime.Now.Date;
modelo.fechaTermino = DateTime.Now.Date;
return View(modelo);
}
[HttpPost]
public ActionResult VisorEventosModelo(SuperModelo model) {
if (ModelState.IsValid) {
svcHomologacion svc = new svcHomologacion();
Infrastructure.SvcHomo.Auditoria[] svAuditoria = svc.ConsultaAuditoria("0", "0", 0, model.rutBeneficiario, model.fechaInicio, model.fechaTermino);
List<Auditoria> audit = new List<Auditoria>();
foreach (Infrastructure.SvcHomo.Auditoria d in svAuditoria) {
audit.Add(AutoMapper.Mapper.Map<Auditoria>(d));
}
foreach (Auditoria a in audit) {
model.Eventos.Add(a);
}
return View(model);
} else {
return View();
}
}
最后,我正在使用的模型:
public class SuperModelo {
public SuperModelo() {
transaccion = new List<System.Web.Mvc.SelectListItem>();
estadoTransaccion = new List<System.Web.Mvc.SelectListItem>();
Eventos = new List<Auditoria>();
}
public List<System.Web.Mvc.SelectListItem> transaccion { get; set; }
public List<System.Web.Mvc.SelectListItem> estadoTransaccion { get; set; }
public Decimal codigoVenta { get; set; }
public Decimal rutBeneficiario { get; set; }
public DateTime fechaInicio { get; set; }
public DateTime fechaTermino { get; set; }
public List<Auditoria> Eventos { get; set; }
public String fechaInicioStr {
get { return fechaInicio.ToString("dd/MM/yyyy").Replace('-','/'); }
set { fechaInicio = DateTime.ParseExact(value, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture); }
}
public String fechaTerminoStr {
get { return fechaTermino.ToString("dd/MM/yyyy").Replace('-', '/'); }
set { fechaTermino = DateTime.ParseExact(value, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture); }
}
}
当我加载View时,控制器将数据加载到模型中并在View中显示数据,但是当我提交表单进行搜索时,模型对控制器启用HttpPost的方法是空的。
我知道可能会对我的代码进行一些主要的优化,但是现在我需要找出为什么MVC Helper在我提交表单时不会返回模型。
注意:我发布了另一个自定义强类型html帮助程序的代码,它在我的视图中没有使用,但是视图中使用的帮助程序以相同的方式编码。
编辑:根据要求,我发布了以下代码: 组合:
public static MvcHtmlString Combo(this HtmlHelper html, string id, IEnumerable<SelectListItem> items, string alto = "", string ancho = "",
Boolean activo = true, Boolean visible = true, string tooltip = "", EjeZ ejeZ = EjeZ.Normal, Boolean multicolumna = false) {
TagBuilder select = new TagBuilder("select");
select.MergeAttribute("id", id);
select.MergeAttribute("name", id);
string estilos = string.Empty;
if(alto.Length > 0) { estilos += "height:" + alto + ";"; }
if(ancho.Length > 0) { estilos += "width:" + ancho + ";"; }
if(!activo)
select.MergeAttribute("disabled", "disabled");
if(!visible) {
select.MergeAttribute("class", "Combo Oculto");
} else {
select.MergeAttribute("class", "Combo");
}
//select.AddCssClass("ComboNew");
if(multicolumna) {
select.MergeAttribute("multicol", "true");
} else {
select.MergeAttribute("multicol", "false");
}
if(ejeZ == EjeZ.Frente) {
estilos += "z-index:" + maxEjeZ + ";";
} else if(ejeZ == EjeZ.Atras) {
estilos += "z-index:" + minEjeZ + ";";
}
select.MergeAttribute("style", estilos);
TagBuilder option;
foreach(SelectListItem item in items) {
option = new TagBuilder("option");
option.MergeAttribute("value", item.Value);
option.MergeAttribute("label", item.Text);
option.InnerHtml += item.Text;
select.InnerHtml += option.ToString(TagRenderMode.Normal);
}
select.MergeAttribute("title", tooltip);
return MvcHtmlString.Create(select.ToString(TagRenderMode.Normal));
}
NÚMERO:
public static MvcHtmlString Numero(this HtmlHelper html, string id, string alto = "", string ancho = "", Boolean activo = true,
Boolean visible = true, int maxlength = 0, string valMax = "", string valMin = "", Boolean spinner = false,
Int32 step = 1, Int32 decimales = 10, string tooltip = "", EjeZ ejeZ = EjeZ.Normal, string Numero = "") {
var numero = new TagBuilder("input");
numero.MergeAttribute("type", "text");
numero.MergeAttribute("id", id);
numero.MergeAttribute("name", id);
numero.MergeAttribute("spinner", spinner.ToString( ));
numero.MergeAttribute("step", step.ToString( ));
numero.MergeAttribute("title", tooltip);
numero.MergeAttribute("value", Numero);
if(maxlength > 0)
numero.MergeAttribute("maxlength", maxlength.ToString( ));
numero.MergeAttribute("maximo", valMax);
numero.MergeAttribute("minimo", valMin);
numero.MergeAttribute("decimales", decimales.ToString( ));
string estilos = string.Empty;
if(alto.Length > 0) { estilos += "height:" + alto + ";"; }
if(ancho.Length > 0) { estilos += "width:" + ancho + ";"; }
if(!activo)
numero.MergeAttribute("disabled", "disabled");
if(!visible) {
numero.MergeAttribute("class", "Numero Oculto");
} else {
numero.MergeAttribute("class", "Numero");
}
if(ejeZ == EjeZ.Frente) {
estilos += "z-index:" + maxEjeZ + ";";
} else if(ejeZ == EjeZ.Atras) {
estilos += "z-index:" + minEjeZ + ";";
}
numero.MergeAttribute("style", estilos);
return MvcHtmlString.Create(numero.ToString(TagRenderMode.SelfClosing));
}
NumeroFor:
public static MvcHtmlString NumeroFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> numero, string id, string alto = "",
string ancho = "", Boolean activo = true, Boolean visible = true, int maxlength = 0, string valMax = "", string valMin = "", Boolean spinner = false,
Int32 step = 1, Int32 decimales = 10, string tooltip = "", EjeZ ejeZ = EjeZ.Normal) {
var name = ExpressionHelper.GetExpressionText(numero);
var metadata = ModelMetadata.FromLambdaExpression(numero, html.ViewData);
string valor = (metadata.Model == null) ? "" : metadata.Model.ToString( );
return Numero(html, id, alto, ancho, activo, visible, maxlength, valMax, valMin, spinner, step, decimales, tooltip, ejeZ, valor);
}
Calendario:
public static MvcHtmlString Calendario(this HtmlHelper html, string id, string fecha = "", string fechaFinal = "",
string fechaInicial = "", string alto = "", string ancho = "", Boolean activo = true,
Boolean visible = true, Boolean deshabilitaFeriados = false, string tooltip = "", EjeZ ejeZ = EjeZ.Normal) {
var calendario = new TagBuilder("input");
calendario.MergeAttribute("type", "Text");
calendario.MergeAttribute("id", id);
calendario.MergeAttribute("name", id);
calendario.MergeAttribute("datepicker", id);
calendario.MergeAttribute("fecha", fecha);
calendario.MergeAttribute("fechafinal", fechaFinal);
calendario.MergeAttribute("fechainicial", fechaInicial);
calendario.MergeAttribute("deshabilitaferiados", deshabilitaFeriados.ToString( ));
string estilos = string.Empty;
if(alto.Length > 0) { estilos += "height:" + alto + ";"; }
if(ancho.Length > 0) { estilos += "width:" + ancho + ";"; }
if(!activo)
calendario.MergeAttribute("disabled", "disabled");
if(!visible) {
calendario.MergeAttribute("class", "Calendario Oculto");
} else {
calendario.MergeAttribute("class", "Calendario");
}
if(ejeZ == EjeZ.Frente) {
estilos += "z-index:" + maxEjeZ + ";";
} else if(ejeZ == EjeZ.Atras) {
estilos += "z-index:" + minEjeZ + ";";
}
calendario.MergeAttribute("style", estilos);
calendario.MergeAttribute("title", tooltip);
return MvcHtmlString.Create(calendario.ToString(TagRenderMode.StartTag));
}
CalendarioFor:
public static MvcHtmlString CalendarioFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> calendario,
string id, string fechaFinal = "", string fechaInicial = "", string alto = "", string ancho = "", Boolean activo = true,
Boolean visible = true, Boolean deshabilitaFeriados = false, string tooltip = "", EjeZ ejeZ = EjeZ.Normal) {
var name = ExpressionHelper.GetExpressionText(calendario);
var metadata = ModelMetadata.FromLambdaExpression(calendario, html.ViewData);
string valor = (metadata.Model == null) ? "" : metadata.Model.ToString( );
return Calendario(html, id, valor, fechaFinal, fechaInicial, alto, ancho, activo, visible, deshabilitaFeriados, tooltip, ejeZ);
}