ASP.NET MVC JsonResult date Format

j'ai une action de controller qui retourne simplement un JsonResult de mon model. Ainsi, dans ma méthode, j'ai quelque chose comme ceci:

return new JsonResult(myModel);

Cela fonctionne bien, sauf pour un problème. Il y a une propriété date dans le modèle et celle-ci semble être retournée dans le résultat Json comme suit:

"/Date(1239018869048)/"

Comment dois-je traiter les dates afin qu'elles soient retournées dans le format que j'exige? Ou comment manipuler ce format ci-dessus dans script?

207
demandé sur JustinStolle 2009-04-07 19:27:06

22 réponses

Juste pour élargir sur casperOne la réponse de .

le JSON spec ne tient pas compte des valeurs de Date. MS a dû faire un appel, et le chemin qu'ils ont choisi était d'exploiter un petit truc dans la représentation javascript des chaînes de caractères: la chaîne littérale "/" est la même que "\/", et une chaîne littérale sera jamais obtenir sérialisé à "\/" (même "\/" doit être mappé à "\\/").

voir http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2 pour une meilleure explication (faites défiler jusqu'à "à Partir de JavaScript Littéraux JSON")

un des points sensibles de JSON est le l'absence d'une date/heure littérale. Beaucoup les gens sont surpris et déçu pour apprendre cela quand ils rencontre JSON. L'explication simple (consolante ou pas) pour l'absence de une date / heure littérale est que JavaScript jamais a l'une ou l'autre: La prise en charge de les valeurs de date et d'heure en JavaScript est entièrement fourni à la Date objet. La plupart des applications utilisant JSON en tant que format de données, donc, généralement tendance à utiliser une chaîne ou une nombre pour exprimer la date et l'heure valeur. Si une chaîne est utilisée, vous pouvez généralement s'attendre à ce qu'il soit dans L'ISO 8601. Si un nombre est utilisé, au lieu de cela, la valeur est généralement pris pour le nombre de millisecondes Universel Coordonné L'heure (UTC) depuis l'époque, où l'époque est défini comme minuit le 1er janvier 1970 (UTC). Encore une fois, ce n'est qu'une simple convention et ne fait pas partie du JSON norme. Si vous échangez des données avec une autre application, vous aurez besoin de vérifier sa documentation pour voir comment il Code les valeurs de date et d'heure dans un JSON littéral. Exemple, Microsoft ASP.NET AJAX n'utilise ni L'un ni L'autre des conventions. Plutôt, IL code les valeurs de DateTime .NET comme un JSON string, où le contenu du la chaîne est /Date(tiques) et où les tiques représentent des millisecondes depuis époque (UTC). Donc 29 Novembre 1989, 4: 55: 30 AM, en UTC est codé comme "\/Date (628318530718)\/".

Une solution serait de simplement l'analyser:

value = new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10));

cependant j'ai entendu qu'il y a un paramètre quelque part pour obtenir le serialiseur de sortie DateTime objets avec la syntaxe new Date(xxx) . Je vais essayer de creuser ça.


le second paramètre de JSON.parse() accepte une fonction reviver où prescrit comment la valeur produite à l'origine par, avant d'être retournée.

voici un exemple de date:

var parsed = JSON.parse(data, function(key, value) {
  if (typeof value === 'string') {
    var d = /\/Date\((\d*)\)\//.exec(value);
    return (d) ? new Date(+d[1]) : value;
  }
  return value;
});

voir les documents de JSON.parse ()

175
répondu JPot 2017-05-23 12:18:01

voici ma solution en Javascript - tout comme JPot, mais plus court (et peut-être un tout petit peu plus rapide):

value = new Date(parseInt(value.substr(6)));

valeur".substr (6) "prend la partie" /Date ( " , et la fonction parseInt ignore les caractères non-nombre qui se produisent à la fin.

EDIT: j'ai volontairement laissé de côté l'radix (le 2ème argument de parseInt); voir mon commentaire ci-dessous . Veuillez également noter que les dates ISO-8601 sont préférées. sur cet ancien format -- donc ce format ne devrait généralement pas être utilisé pour un nouveau développement. Voir l'excellent Json.NET bibliothèque pour une excellente alternative qui sérialise les dates en utilisant le format ISO-8601.

pour les dates JSON formatées ISO-8601, il suffit de passer la chaîne dans le constructeur de Date:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
89
répondu Roy Tinker 2017-05-23 12:10:08

il y a pas mal de réponses pour gérer le côté client, mais vous pouvez changer le côté serveur de sortie si vous le souhaitez.

il y a plusieurs façons d'aborder cela, je vais commencer par les bases. Vous devrez classer la classe JsonResult et remplacer la méthode ExecuteResult. De là, vous pouvez prendre quelques approches différentes pour changer la sérialisation.

approche 1: La mise en œuvre par défaut utilise JsonScriptSerializer . Si vous regardez la documentation, vous pouvez utiliser la méthode RegisterConverters pour ajouter custom Javasriptconverters . Il y a quelques problèmes avec ceci cependant: le javascriptconverter serialise à un dictionnaire, c'est-à-dire qu'il prend un objet et serialise à un dictionnaire Json. Afin de rendre l'objet sérialize à une chaîne, il nécessite un peu de hackery, voir post . Ce piratage particulier va aussi échapper à la chaîne.

public class CustomJsonResult : JsonResult
{
    private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        HttpResponseBase response = context.HttpContext.Response;

        if (!String.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data != null)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            // Use your custom JavaScriptConverter subclass here.
            serializer.RegisterConverters(new JavascriptConverter[] { new CustomConverter });

            response.Write(serializer.Serialize(Data));
        }
    }
}

approche 2 (recommandée): La deuxième approche est de commencer avec le JsonResult surchargé et aller avec un autre serializer Json, dans mon cas le Json.NET serializer. Cela ne nécessite pas le hackery de l'approche 1. Voici ma mise en œuvre de la sous-classe JsonResult:

public class CustomJsonResult : JsonResult
{
    private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        HttpResponseBase response = context.HttpContext.Response;

        if (!String.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data != null)
        {
            // Using Json.NET serializer
            var isoConvert = new IsoDateTimeConverter();
            isoConvert.DateTimeFormat = _dateFormat;
            response.Write(JsonConvert.SerializeObject(Data, isoConvert));
        }
    }
}

Exemple D'Utilisation:

[HttpGet]
public ActionResult Index() {
    return new CustomJsonResult { Data = new { users=db.Users.ToList(); } };
}

Crédits supplémentaires: James Newton-King

60
répondu Perishable Dave 2016-03-24 15:59:27

Moment.js est une bibliothèque de datetime étendue qui supporte aussi cela. http://momentjs.com/docs/#/parsing/asp-net-json-dates/

ex: ("/Date(1198908717056-0700)/")

ça pourrait aider. sortie plunker

28
répondu Eric 2015-06-29 07:21:48

utilisant jQuery pour auto-convertir les dates avec $.parseJSON

Note : cette réponse fournit une extension jQuery qui ajoute automatiquement la prise en charge des formats ISO et .net date.

puisque vous utilisez Asp.net MVC je soupçonne que vous utilisez jQuery du côté du client. Je vous suggère de lire ce billet de blog qui a le code comment utiliser $.parseJSON pour convertir automatiquement les dates pour vous.

Prise en charge du Code

Asp.net les dates formatées comme celles que vous avez mentionnées ainsi que les dates formatées ISO. Toutes les dates seront automatiquement formatées pour vous en utilisant $.parseJSON() .

19
répondu Robert Koritnik 2013-04-04 09:53:02

j'ai trouvé que la création d'un nouveau JsonResult et le retour qui est insatisfaisant - avoir à remplacer tous les appels à return Json(obj) par return new MyJsonResult { Data = obj } est une douleur.


alors j'ai pensé, pourquoi ne pas détourner le JsonResult en utilisant un ActionFilter :

public class JsonNetFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Result is JsonResult == false)
        {
            return;
        }

        filterContext.Result = new JsonNetResult(
            (JsonResult)filterContext.Result);
    }

    private class JsonNetResult : JsonResult
    {
        public JsonNetResult(JsonResult jsonResult)
        {
            this.ContentEncoding = jsonResult.ContentEncoding;
            this.ContentType = jsonResult.ContentType;
            this.Data = jsonResult.Data;
            this.JsonRequestBehavior = jsonResult.JsonRequestBehavior;
            this.MaxJsonLength = jsonResult.MaxJsonLength;
            this.RecursionLimit = jsonResult.RecursionLimit;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            var isMethodGet = string.Equals(
                context.HttpContext.Request.HttpMethod, 
                "GET", 
                StringComparison.OrdinalIgnoreCase);

            if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet
                && isMethodGet)
            {
                throw new InvalidOperationException(
                    "GET not allowed! Change JsonRequestBehavior to AllowGet.");
            }

            var response = context.HttpContext.Response;

            response.ContentType = string.IsNullOrEmpty(this.ContentType) 
                ? "application/json" 
                : this.ContentType;

            if (this.ContentEncoding != null)
            {
                response.ContentEncoding = this.ContentEncoding;
            }

            if (this.Data != null)
            {
                response.Write(JsonConvert.SerializeObject(this.Data));
            }
        }
    }
}

ceci peut être appliqué à n'importe quelle méthode retournant un JsonResult à utiliser JSON.Net à la place:

[JsonNetFilter]
public ActionResult GetJson()
{
    return Json(new { hello = new Date(2015, 03, 09) }, JsonRequestBehavior.AllowGet)
}

qui répondra par

{"hello":"2015-03-09T00:00:00+00:00"}

comme vous le souhaitez!


vous pouvez, si cela ne vous dérange pas d'appeler la comparaison is à chaque demande, ajouter ceci à votre FilterConfig :

// ...
filters.Add(new JsonNetFilterAttribute());

et tout votre JSON sera maintenant sérialisé avec JSON.Net au lieu du JavaScriptSerializer intégré .

13
répondu dav_i 2016-07-18 11:49:35

communication Ajax entre le client et le serveur implique souvent des données dans le format JSON. Bien que JSON fonctionne bien pour les chaînes, les nombres et les booléens, il peut poser quelques difficultés pour les dates en raison de la façon ASP.NET les sérialise. Comme il n'y a pas de représentation spéciale pour les dates, elles sont sérialisées en chaînes simples. Comme solution le mécanisme de sérialisation par défaut de ASP.NET formulaires Web et MVC sérialise les dates dans un formulaire spécial - / Date (tiques) / - où le nombre de tiques est le nombre de millisecondes depuis le 1er janvier 1970.

ce problème peut être résolu de 2 façons:

côté client

convertissez la chaîne de date reçue en un nombre et créez un objet date en utilisant le constructeur de la classe date avec les tiques comme paramètre.

function ToJavaScriptDate(value) {
  var pattern = /Date\(([^)]+)\)/;
  var results = pattern.exec(value);
  var dt = new Date(parseFloat(results[1]));
  return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();

}

côté serveur

la solution précédente utilise script côté client pour convertir la date en objet Date JavaScript. Vous pouvez également utiliser le code côté serveur qui sérialise les instances .net DateTime dans le format de votre choix. Pour accomplir cette tâche, vous devez créer votre propre ActionResult puis sérialiser les données comme vous le souhaitez.

de référence : http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html

11
répondu Mischa 2014-10-10 15:31:09

j'ai eu le même problème et au lieu de retourner la valeur réelle de la date j'ai juste utilisé ToString ("JJ MMM AAAA") sur elle. Puis dans mon javascript j'ai utilisé la nouvelle Date (datevalue), où datevalue peut être "01 Jan 2009".

7
répondu Joe 2010-03-11 17:44:01

voir ce fil:

http://forums.asp.net/p/1038457/1441866.aspx#1441866

essentiellement, alors que le format Date() est valide javascript, il n'est pas valide JSON (il y a une différence). Si vous voulez l'ancien format, vous devrez probablement créer une façade et de transformer cette valeur vous-même, ou de trouver un moyen d'obtenir le sérialiseur pour votre type dans le JsonResult et l'avoir utiliser un format personnalisé pour les dates.

4
répondu casperOne 2009-04-07 15:47:58

pas la manière la plus élégante mais cela a fonctionné pour moi:

var ms = date.substring(6, date.length - 2);
var newDate = formatDate(ms);


function formatDate(ms) {

    var date = new Date(parseInt(ms));
    var hour = date.getHours();
    var mins = date.getMinutes() + '';
    var time = "AM";

    // find time 
    if (hour >= 12) {
        time = "PM";
    }
    // fix hours format
    if (hour > 12) {
        hour -= 12;
    }
    else if (hour == 0) {
        hour = 12;
    }
    // fix minutes format
    if (mins.length == 1) {
        mins = "0" + mins;
    }
    // return formatted date time string
    return date.getMonth() + 1 + "/" + date.getDate() + "/" + date.getFullYear() + " " + hour + ":" + mins + " " + time;
}
2
répondu Gabe 2010-01-11 20:50:49

j'ai travaillé sur une solution à ce problème car aucune des réponses ci-dessus m'a vraiment aidé. Je travaille avec le calendrier de la semaine de jquery et j'avais besoin de mes dates pour avoir des informations sur les fuseaux horaires sur le serveur et localement sur la page. Après avoir creusé un peu, j'ai trouvé une solution qui pourrait aider les autres.

j'utilise asp.net 3.5, vs 2008, asp.net MVC 2, et jQuery Week calendar,

tout d'abord, j'utilise une bibliothèque écrite par Steven Levithan qui aide à traiter avec des dates sur le côté client, Steven Levithan date de bibliothèque . Le format isoUtcDateTime est parfait pour ce dont j'avais besoin. Dans mon appel AJAX jquery j'utilise la fonction format fournie avec la bibliothèque avec le format isoUtcDateTime et lorsque l'appel ajax touche ma méthode d'action, le type datetime est défini à local et reflète l'heure du serveur.

lorsque j'envoie des dates à ma page via AJAX, je les envoie sous forme de chaînes de texte en formatant les dates en utilisant "ddd, JJ MMM aaaa HH':'mm':'ss 'GMT'zzz". Ce format est facilement converti côté client en utilisant

var myDate = new Date(myReceivedDate);

voici ma solution complète moins la source de Steve Levithan, que vous pouvez télécharger:

contrôleur:

public class HomeController : Controller
{
    public const string DATE_FORMAT = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz";

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }


    public JsonResult GetData()
    {
        DateTime myDate = DateTime.Now.ToLocalTime();

        return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
    }

    public JsonResult ReceiveData(DateTime myDate)
    {
        return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
    }
}

Javascript:

<script type="text/javascript">

function getData() {
    $.ajax({
        url: "/Home/GetData",
        type: "POST",
        cache: "false",
        dataType: "json",
        success: function(data) {
            alert(data.myDate);
            var newDate = cleanDate(data.myDate);
            alert(newDate);
            sendData(newDate);
        }
    });
} 

function cleanDate(d) {
    if (typeof d == 'string') {
        return new Date(d) || Date.parse(d) || new Date(parseInt(d));
    }
    if (typeof d == 'number') {
        return new Date(d);
    }
    return d;
}

function sendData(newDate) {
    $.ajax({
        url: "/Home/ReceiveData",
        type: "POST",
        cache: "false",
        dataType: "json",
        data:
        {
            myDate: newDate.format("isoUtcDateTime")
        },
        success: function(data) {
            alert(data.myDate);
            var newDate = cleanDate(data.myDate);
            alert(newDate);
        }
    });
}

// bind myButton click event to call getData
$(document).ready(function() {
    $('input#myButton').bind('click', getData);
});
</script>

j'espère que cet exemple rapide aidera d'autres dans la même situation que moi. A cette époque, il semble fonctionner très bien avec la sérialisation JSON de Microsoft et garde mes dates correctes à travers les fuseaux horaires.

2
répondu Jesse 2011-01-18 14:59:51

la meilleure façon de gérer les dates dans knockoutjs est d'utiliser la bibliothèque des moments et de gérer les dates comme boss. Vous pouvez facilement traiter avec des dates comme / Date (-62135578800000)/. Pas besoin de se soucier de la façon dont votre date serialize dans le contrôleur.

function jsonToDate(date,format) {
   return moment(date).format(format);
}

utiliser comme

var formattedDate = jsonToDate(date,'MM/DD/YYYY')

momentjs prend en charge de nombreux formats de date time et des fonctions d'utilité sur les dates.

2
répondu Ajay Kelkar 2014-07-06 14:15:30

formater la date dans la requête.

var _myModel = from _m in model.ModelSearch(word)
    select new { date = ((DateTime)_m.Date).ToShortDateString() };

le seul problème avec cette solution est que vous n'obtiendrez aucun résultat si L'une des valeurs de date est nulle. Pour contourner cela, vous pouvez soit mettre des énoncés conditionnels dans votre requête avant de sélectionner la date qui ignore la date nulls ou vous pouvez configurer une requête pour obtenir tous les résultats et ensuite boucler toute l'information en utilisant une boucle foreach et attribuer une valeur à toutes les dates qui sont null avant de le faire votre SÉLECTIONNEZ nouveau.

exemple des deux:

var _test = from _t in adc.ItemSearchTest(word)
                        where _t.Date != null
                        select new { date = ((DateTime)_t.Date).ToShortDateString() };

la seconde option nécessite une autre requête entièrement pour que vous puissiez attribuer des valeurs à tous les nulls. Ceci et la boucle foreach devraient être avant votre requête qui sélectionne les valeurs.

var _testA = from _t in adc.ItemSearchTest(word)
                         select _i;

            foreach (var detail in _testA)
            {
                if (detail.Date== null)
                {
                    detail.Date= Convert.ToDateTime("1/1/0001");
                }
            }

juste une idée que j'ai trouvé plus facile que tous les exemples javascript.

1
répondu Chad 2011-03-05 06:03:08

Vous pouvez utiliser cette méthode:

String.prototype.jsonToDate = function(){
    try{
        var date;
        eval(("date = new " + this).replace(/\//g,''));
        return date;
    } 
    catch(e){
        return new Date(0);
    }
};
1
répondu eladmat 2013-05-09 19:53:48

ajouter jQuery ui plugin dans votre page.

function JsonDateFormate(dateFormate, jsonDateTime) {
    return $.datepicker.formatDate(dateFormate, eval('new ' + jsonDateTime.slice(1, -1)));
};
0
répondu Thulasiram 2012-06-29 12:08:37

retourne le format Date du serveur. Vous devez définir votre propre fonction.

function jsonDateFormat(jsonDate) {

// Changed data format;
return (new Date(parseInt(jsonDate.substr(6)))).format("mm-dd-yyyy / h:MM tt");

};

0
répondu Manish Kundu 2013-02-25 08:44:03

voici un code JavaScript que j'ai écrit qui définit une valeur <input type="date"> à partir d'une date passée de ASP.NET MVC.

    var setDate = function (id, d) {
    if (d !== undefined && d !== null) {
        var date = new Date(parseInt(d.replace("/Date(", "").replace(")/", ""), 10));
        var day = ('0' + date.getDate()).slice(-2);
        var month = ('0' + (date.getMonth() + 1)).slice(-2);
        var parsedDate = date.getFullYear() + "-" + (month) + "-" + (day);
        $(id).val(parsedDate);
    }
};

vous appelez cette fonction comme ceci:

setDate('#productCommissionStartDate', data.commissionStartDate);

où commissionStartDate est la date JSON passée par MVC.

0
répondu Tribal Coder 2013-03-07 23:06:44

pas pour rien, mais il y a un autre chemin. Tout d'abord, construisez votre requête LINQ. Ensuite, construisez une requête du résultat énuméré et appliquez n'importe quel type de formatage fonctionne pour vous.

var query = from t in db.Table select new { t.DateField };
var result = from c in query.AsEnumerable() select new { c.DateField.toString("dd MMM yyy") };

je dois dire, le pas supplémentaire est ennuyeux, mais il fonctionne bien.

0
répondu skrile 2013-08-13 18:02:55

ce qui a fonctionné pour moi était de créer un viewmodel qui contenait la propriété date comme une chaîne. Attribution de la date de la propriété à partir du modèle de domaine et l'appel de la .ToString() sur la date de la propriété, tout en affectant la valeur pour le viewmodel.

un résultat JSON d'une méthode D'action MVC retournera la date dans un format compatible avec la vue.

Modèle De Vue

public class TransactionsViewModel
{
    public string DateInitiated { get; set; }
    public string DateCompleted { get; set; }
}

Modèle De Domaine

public class Transaction{
   public DateTime? DateInitiated {get; set;}
   public DateTime? DateCompleted {get; set;}
}

Méthode D'Action Du Contrôleur

public JsonResult GetTransactions(){

var transactions = _transactionsRepository.All;
        var model = new List<TransactionsViewModel>();

        foreach (var transaction in transactions)
        {
            var item = new TransactionsViewModel
            {
                ...............
                DateInitiated = transaction.DateInitiated.ToString(),
                DateCompleted = transaction.DateCompleted.ToString(),
            };

            model.Add(item);
        }
        return Json(model, JsonRequestBehavior.AllowGet);
}
0
répondu Oladipo Olasemo 2015-02-06 23:00:41

outrepasser les contrôleurs Json/JsonResult pour revenir JSON.Net:

cette oeuvre traite

0
répondu Ian 2017-05-23 12:03:05

Ennuyeux, n'est-ce pas ?

ma solution était de changer mon service WCF pour le faire retourner DateTimes dans un format plus lisible (non-Microsoft). Notez ci-dessous, le " UpdateDateOriginal ", qui est le format par défaut de la WCF des dates, et mon " UpdateDate ", qui est formaté à quelque chose de plus lisible.

enter image description here

Voici comment le faire:

Modification du format de la date de la WCF

Espérons que cette aide.

0
répondu Mike Gledhill 2017-05-23 11:54:46

le plus facile:

var milisegundos = parseInt (data.remplacer ("/Date (","").remplacer(")/", ""));

Var newDate = new Date (milisegundos). tolocaledestring ("en-UE");

-1
répondu Kenlly Acosta 2018-02-21 15:32:14