2012-03-02 4 views
3

У меня есть модель, которая имеет некоторые двойные свойства на него, и с ними придут DisplayFormat, который преобразует двойную в хороший читаемый процент .. примерMVC3 модели DisplayFormat и JSON

[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?

ответ

2

Звонок return Json(myObjects, JsonRequestBehavior.AllowGet) фактически возвращает JsonResult. Внутренности JsonResult выполнить вызов:

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
response.Write(serializer.Serialize(Data)); 

Если посмотреть на MSDN для JavascriptSerializer вы будете есть простое преобразование. Эта реализация, похоже, не одобряет DisplayFormat.

Вы можете написать класс, полученный из JsonResult, который отличит атрибут DisplayFormat.

+0

Программно, как я могу прочитать объект для параметров DisplayFormat его свойств? –

1

Атрибуты пространства именбудут обрабатывать его только для управления динамическими данными и форматирования отображения. То, что вам нужно сделать, - это просто базовое округление перед передачей объекта методу 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, и лучшее, что вы можете сделать, это округлить его, чтобы он не имел избыточного количества дробных цифр.

1

Один из рабочих обходные, что люди используют, когда необходимости настроить формат вывода при работе с сериализации создать свойство строки:

[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 является пользовательский класс у меня есть, что Handels разбор/форматирование для определенных типов. Это не имеет значения, но я включу их:

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)

Смежные вопросы