我有一个模型,它有一些双重属性,并带有一个DisplayFormat,它将double转换为一个很好的可读百分比..例如
[DisplayFormat(DataFormatString = "{0:P2}")]
public Nullable<double> Yearly_act_pct { get; set; }
这在HTML部分中很好用,我在
中包装了调用@Html.DisplayFor(modelItem => item.Yearly_act_pct)
但是,当我将其中一些对象转储到JSON提要中时,DisplayFormats似乎被忽略了,所以我最终得到了原始小数,而且往往是大小数。
我该如何制作
return Json(myObjects, JsonRequestBehavior.AllowGet);
尊重DisplayFormats?
答案 0 :(得分:2)
对return Json(myObjects, JsonRequestBehavior.AllowGet)
的调用实际上会返回JsonResult
。 JsonResult
的内部执行呼叫:
JavaScriptSerializer serializer = new JavaScriptSerializer();
response.Write(serializer.Serialize(Data));
如果你查看JavascriptSerializer的MSDN,你会有一个简单的转换。此实现似乎不尊重DisplayFormat。
您可以编写一个派生自JsonResult
的类,以尊重DisplayFormat属性。
答案 1 :(得分:1)
DataAnnotations
命名空间属性仅处理动态数据控件和显示格式。在将对象传递给Json()
方法之前,您需要做的只是一些基本的舍入。这样的东西就足够了:
myObjects.Yearly_act_pct = Math.Round(myObjects.Yearly_act_pct, 2); // provided you wanted to round to nearest two fractional digits
return Json(myObjects, JsonRequestBehavior.AllowGet);
这会为您提供“小双倍”值,但您仍然传递double
,而不是string
,可以是格式化double
。不确定这是否有意义,但double
是double
,你可以做的最好是将其舍入,以便它没有超出的小数位数。
答案 2 :(得分:1)
人们在使用Serialization时需要自定义输出格式时使用的一种解决方法是创建字符串属性:
[DataMember(Name = "price", Order = 23)]
[XmlElement("price", Order = 23)]
public string Price_String
{
get
{
return Formatter.FormatAsCurrency(this.Price);
}
set
{
this.Price = Formatter.ParseCurrency(value);
}
}
[XmlIgnore]
public decimal Price { get; set; }
Formatter是我自己的一个自定义类,它可以解析特定类型的格式。这些不相关,但我会将它们包括在内:
public static string FormatAsCurrency(decimal? amount)
{
return amount.HasValue ? String.Format("{0:C}USD", amount).Replace("$","") : null;
}
public static decimal ParseCurrency(string value)
{
return !String.IsNullOrEmpty(value) ? decimal.Parse(value.Replace("USD", "")) : 0;
}
public static decimal? ParseNullableCurrency(string value)
{
return !String.IsNullOrEmpty(value) ? decimal.Parse(value.Replace("USD", "")) as decimal? : null;
}
在我的示例中,我已经为DataContract和Xml序列化标记了我的属性。这不是理想的,但当时是唯一的解决方法。
我还在我的控制器中创建了一个方法来返回响应“
public ContentResult GetContentResult(object responseObject)
{
#region Output Format
if (this.ResponseFormat == ResponseFormatEnum.JSON)
{
string json = "";
try
{
System.Runtime.Serialization.Json.DataContractJsonSerializer jsonserializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(responseObject.GetType());
MemoryStream ms = new MemoryStream();
jsonserializer.WriteObject(ms, responseObject);
json = Encoding.Default.GetString(ms.ToArray());
ms.Close();
ms.Dispose();
jsonserializer = null;
}
catch(System.Exception ex)
{
string err = ex.Message;
}
return new ContentResult() { Content = json, ContentType = "application/json" };
}
else
{
string xml = "";
try
{
MemoryStream ms = new MemoryStream();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(responseObject.GetType());
System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add("", "");
ms = new MemoryStream();
serializer.Serialize(ms, responseObject, ns);
xml = Encoding.Default.GetString(ms.ToArray()); ms.Close();
ms.Dispose();
serializer = null;
}
catch (System.Exception ex)
{
throw ex;
}
return new ContentResult() { Content = xml, ContentType = "text/xml" };
}
#endregion
}
使用它:
public ActionResult Feed()
{
ViewModels.API.Deals.Response response = new ViewModels.API.Deals.Get();
return GetContentResult(response);
}
我的示例比您使用的示例复杂一点,但它的工作原理(包括XML和JSON)