C# 如何动态声明注释[DataFormat(DataFormatString)]以单位表示值?
如何在数值上使用注释C# 如何动态声明注释[DataFormat(DataFormatString)]以单位表示值?,c#,asp.net-mvc,entity-framework-6,data-annotations,C#,Asp.net Mvc,Entity Framework 6,Data Annotations,如何在数值上使用注释[DataFormat(DataFormatString=”“)]以及单位值(因条目而异)来显示带有标签的值(例如“$1.00每磅” 在ASP.NET MVC 5应用程序中,我有三个实体:产品,商店,和价格(价格是桥梁实体).Product有int Amount和enum Units字段,用于存储例如10盎司或1加仑。在Price中,我试图找出如何创建格式良好的UnitPrice字段,该字段是一个计算字段,将产品价格除以给定单位的数量,然后显示以正确的单位放置。例如,一罐10
[DataFormat(DataFormatString=”“)]
以及单位
值(因条目而异)来显示带有标签的值(例如“$1.00每磅”
在ASP.NET MVC 5应用程序中,我有三个实体:产品
,商店
,和价格
(价格是桥梁实体).Product
有int Amount
和enum Units
字段,用于存储例如10盎司或1加仑。在Price
中,我试图找出如何创建格式良好的UnitPrice
字段,该字段是一个计算字段,将产品价格除以给定单位的数量,然后显示以正确的单位放置。例如,一罐10盎司的汤,价格为1.00美元,当显示在视图中时,读数为每盎司0.10美元。
在Price
中,当显示在视图中时,我能够使用以下代码片段正确计算值,并使用尾随字符串literal“每单位”
对其进行格式化:
[DisplayFormat(DataFormatString="{0:$#,##0.00' per unit'}")]
[Display(Name = "Unit Price")]
public decimal UnitPrice
{
get { return Value / Product.Amount; }
}
然而,当我尝试以下方法时:
[DisplayFormat(DataFormatString="{0:$#,##0.00' per " + this.Product.Amount + "'}")]
代替第一个注释,Visual Studio告诉我关键字“this”不在当前上下文中。如果我删除它,它会认为产品引用的是类而不是字段。如果我将字段的名称更改为其他名称,它会告诉我“非静态字段、方法或属性需要对象引用”
我无法找到一个优雅的解决方案。我知道我可以创建一个单独的字段来处理它,如下所示:
// Edited to include String.Format
[Display(Name = "Unit Price")]
public String LabeledUnitPrice
{
get { return String.Format("{0:$#,##0.00}", UnitPrice) + " per " + this.Product.Units; }
}
我也可以在视图中处理这个问题,但我更希望它在模型代码中一起处理,以使事情保持最简单。这是可能的,还是有其他方法可以做到
我的相关代码:
public enum UnitType
{
Each, Pound, Ounce, Fluid_Ounce, Liter, Gallon
}
public class Product
{
[Key]
public int ID { get; set; }
[StringLength(50, MinimumLength = 1)]
public String Name { get; set; }
[RegularExpression(@"^[0-9]{0,12}$")]
public String UPC { get; set; }
public int CategoryID { get; set; }
public int Amount { get; set; }
public UnitType Units{ get; set; }
[Display(Name = "Amount")]
public string AmountInUnits
{
get { return Amount + " " + Units; }
}
public virtual ICollection<Price> Prices { get; set; }
public virtual Category Category { get; set; }
}
public class Price
{
public int PriceID { get; set; }
[DataType(DataType.Currency)]
[Display(Name="Price")]
public decimal Value { get; set; }
public int ProductID { get; set; }
public int StoreID { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
[Display(Name = "Entry Date")]
public DateTime Date { get; set; }
[DisplayFormat(DataFormatString="{0:$#,##0.00' per unit'}")]
[Display(Name = "Unit Price")]
public decimal UnitPrice
{
get { return Value / Product.Amount; }
}
public virtual Product Product { get; set; }
public virtual Store Store { get; set; }
}
公共枚举单元类型
{
每磅、每盎司、每盎司、每升、每加仑
}
公共类产品
{
[关键]
公共int ID{get;set;}
[StringLength(50,最小长度=1)]
公共字符串名称{get;set;}
[正则表达式(@“^[0-9]{0,12}$”)
公共字符串UPC{get;set;}
public int CategoryID{get;set;}
公共整数金额{get;set;}
公共单位类型单位{get;set;}
[显示(名称=“金额”)]
公共字符串amountunits
{
获取{返回金额+“”+单位;}
}
公共虚拟ICollection价格{get;set;}
公共虚拟类别{get;set;}
}
公共类价格
{
public int PriceID{get;set;}
[数据类型(数据类型.货币)]
[显示(Name=“价格”)]
公共十进制值{get;set;}
public int ProductID{get;set;}
public int StoreID{get;set;}
[数据类型(DataType.Date)]
[DisplayFormat(DataFormatString=“{0:MM dd yyyy}”,ApplyFormatInEditMode=true)]
[显示(Name=“输入日期”)]
公共日期时间日期{get;set;}
[DisplayFormat(DataFormatString=“{0:$#,###0.00每单位”}”)]
[显示(名称=“单价”)]
公共十进制单价
{
获取{返回值/Product.Amount;}
}
公共虚拟产品产品{get;set;}
公共虚拟存储{get;set;}
}
具有行为的属性通常是一种格式。虽然在大多数情况下,使属性显示静态格式是可以接受的,但您已经发现,如果需要动态数据,则很难进行自定义
最好的办法是创建一个包含计算和显示逻辑的ViewModel,这样它们既不是模型的一部分,也不是视图的一部分。数据批注在编译时进行计算,不能包含任何运行时数据。计算属性
LabeledUnitPrice
有什么问题吗?这些都很好,很有意义。技术性事实上,LabeledUnitPrice
没有什么问题,因为它功能完美。我只是想要一个更好的解决方案,如果可能的话。所谓更好,我的意思是通过修复我缺少的一些小细节来避免不必要的实例变量,我觉得这是一个更好的解决问题的方法。请注意,我仍然需要计算字段UnitPrice
,因为应用程序需要该值来比较其他地方的产品价格。计算属性不会是实例变量。我认为您将很难找到比~2行代码更好的解决方案。这些是非常常见的。