C# 以百分比表示的十进制数据批注
我对c#.netcore razor pages应用程序中数据对象上的字段使用以下DataAnnotation:C# 以百分比表示的十进制数据批注,c#,razor,C#,Razor,我对c#.netcore razor pages应用程序中数据对象上的字段使用以下DataAnnotation: [Display(Name = "Markup For Profit")] [Required] [DisplayFormat(DataFormatString = "{0:P0}", ApplyFormatInEditMode = true)] public double ProfitMarkup { get;
[Display(Name = "Markup For Profit")]
[Required]
[DisplayFormat(DataFormatString = "{0:P0}", ApplyFormatInEditMode = true)]
public double ProfitMarkup { get; set; }
在Razor页面上,我在输入中使用此字段:
<input asp-for="ProfitMarkup" class="form-control" autocomplete="off" />
ProfitMarkup的十进制值正确显示(即0.2显示为20%),这是好的。但是,当我提交表单时,客户端验证会引发错误:
“利润的字段标记必须是数字。”
我很确定这是因为“%”符号是由显示格式添加的
允许20%页面上的输入进入对象并将小数点设置为0.2的最佳方法是什么?当您在输入框中有百分比符号作为DataAnnotation的一部分时,默认ModelBinder将无法获得正确的发布值。您可以创建自定义ModelBinder。使用ASP.Net MVC的示例:
// The ViewModel
public class HomeViewModel
{
[Display(Name = "Markup For Profit")]
[Required]
[DisplayFormat(DataFormatString = "{0:P2}", ApplyFormatInEditMode =true)]
public double ProfitMarkup { get; set; }
}
// Two Classes to implement custom ModelBinder
public class DoublePercentDataBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(HomeViewModel))
{
HttpRequestBase request = controllerContext.HttpContext.Request;
string pMarkup = request.Form.Get("ProfitMarkup").TrimEnd('%');
return new HomeViewModel
{
ProfitMarkup = Double.Parse(pMarkup)/100
};
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}
public class DoublePercentBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
string pMarkup = request.Form.Get("ProfitMarkup").TrimEnd('%');
return new HomeViewModel
{
ProfitMarkup = Double.Parse(pMarkup)/100
};
}
}
// Attach it in Application_Start in Global.asax
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(HomeViewModel), new DoublePercentBinder());
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
// HomeController Get and Post
public class HomeController : Controller
{
public ActionResult Index()
{
HomeViewModel vm = new HomeViewModel();
vm.ProfitMarkup = 1.2;
return View(vm);
}
[HttpPost]
public ActionResult Index([ModelBinder(typeof(DoublePercentBinder))] HomeViewModel hvm)
{
return View(hvm);
}
// The Razor View
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<div>
@Html.EditorFor(x => x.ProfitMarkup)
@Html.ValidationMessageFor(x => x.ProfitMarkup)
</div>
<br />
<input type="submit" value="Submit" />
}
//视图模型
公共类HomeViewModel
{
[显示(Name=“利润标记”)]
[必需]
[DisplayFormat(DataFormatString=“{0:P2}”,ApplyFormatInEditMode=true)]
公共双利润标记{get;set;}
}
//实现自定义ModelBinder的两个类
公共类DoublePercentDataBinder:DefaultModelBinder
{
公共重写对象BindModel(ControllerContext ControllerContext,ModelBindingContext bindingContext)
{
if(bindingContext.ModelType==typeof(HomeViewModel))
{
HttpRequestBase请求=controllerContext.HttpContext.request;
字符串pMarkup=request.Form.Get(“ProfitMarkup”).TrimEnd(“%”);
返回新的HomeViewModel
{
ProfitMarkup=Double.Parse(pMarkup)/100
};
}
其他的
{
返回base.BindModel(controllerContext、bindingContext);
}
}
}
公共类绑定器:IModelBinder
{
公共对象绑定模型(ControllerContext ControllerContext,ModelBindingContext bindingContext)
{
HttpRequestBase请求=controllerContext.HttpContext.request;
字符串pMarkup=request.Form.Get(“ProfitMarkup”).TrimEnd(“%”);
返回新的HomeViewModel
{
ProfitMarkup=Double.Parse(pMarkup)/100
};
}
}
//将其附加到Global.asax中的应用程序_Start中
受保护的无效应用程序\u Start()
{
添加(typeof(HomeViewModel),新的DoublePercentBinder());
RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
//HomeController获取和发布
公共类HomeController:控制器
{
公共行动结果索引()
{
HomeViewModel vm=新的HomeViewModel();
vm.ProfitMarkup=1.2;
返回视图(vm);
}
[HttpPost]
公共行动结果索引([ModelBinder(typeof(DoublePercentBinder))]HomeViewModel hvm)
{
返回视图(hvm);
}
//剃刀视野
@使用(Html.BeginForm(“Index”,“Home”,FormMethod.Post))
{
@EditorFor(x=>x.ProfitMarkup)
@Html.ValidationMessageFor(x=>x.ProfitMarkup)
}
添加新的百分比类型和百分比转换器TypeConverter为我解决了这个问题
我声明了一个新属性,它读取double ProfitMarkup属性,如下所示:
[Display(Name = "Markup For Profit")]
[Required]
[NotMapped]
public Percentage ProfitMarkupPercentage { get { return new Percentage(ProfitMarkup); } set { ProfitMarkup = value; } }
<input asp-for="ProfitMarkupPercentage" class="form-control" autocomplete="off" />
ProfitMarkup以双精度形式写入数据库或从数据库写入,ProfitMarkupCentage显示在razor页面上,如下所示:
[Display(Name = "Markup For Profit")]
[Required]
[NotMapped]
public Percentage ProfitMarkupPercentage { get { return new Percentage(ProfitMarkup); } set { ProfitMarkup = value; } }
<input asp-for="ProfitMarkupPercentage" class="form-control" autocomplete="off" />
默认的模型绑定器现在可以正确地在razor页面上的属性之间填充
还可以使用正则表达式将验证数据注释添加到ProfitMarkupPercentage属性:
[RegularExpression(@"^(0*100{1,1}\.?((?<=\.)0*)?%?$)|(^0*\d{0,2}\.?((?<=\.)\d*)?%?)$", ErrorMessage = "Invalid percentage")]
[RegularExpression(@“^(0*100{1,1}\)(?您可以使用字符串而不是双精度和RegularExpression属性来仅获取数字和%