Модель MVC3 DisplayFormat и JSON - PullRequest
       6

Модель MVC3 DisplayFormat и JSON

3 голосов
/ 02 марта 2012

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

@Html.DisplayFor(modelItem => item.Yearly_act_pct)

Однако, когда я выгружаю некоторые из этих объектов в канал JSON, DisplayFormats, кажется, игнорируются, поэтому я получаю необработанные десятичные и часто большие.

Как мне сделать так, чтобы

return Json(myObjects, JsonRequestBehavior.AllowGet);

соответствовал форматам отображения?

Ответы [ 3 ]

2 голосов
/ 02 марта 2012

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

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

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

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

1 голос
/ 02 марта 2012

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

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

1 голос
/ 02 марта 2012

Атрибуты пространства имен 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);

Это даст вам значение "small double", но вы все равно передаете double, а не string, который может быть отформатирован double,Не уверен, что это имеет смысл, но double - это double, и лучшее, что вы можете сделать, это округлить его, чтобы в нем не было избыточного количества дробных цифр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...