javascript asp.net-mvc json

javascript - json date to datetime c#



ASP.NET MVC JsonResult Date Format (22)

Tengo una acción de controlador que efectivamente simplemente devuelve un JsonResult de mi modelo. Entonces, en mi método tengo algo como lo siguiente:

return new JsonResult(myModel);

Esto funciona bien, excepto por un problema. Hay una propiedad de fecha en el modelo y esto parece que se devuelve en el resultado de Json como tal:

"//Date(1239018869048)//"

¿Cómo debo tratar con las fechas para que se devuelvan en el formato que requiero? ¿O cómo manejo este formato arriba en el script?


Usando jQuery para convertir automáticamente las fechas con $.parseJSON

Nota : esta respuesta proporciona una extensión jQuery que agrega compatibilidad automática con el formato de fecha ISO y .net.

Ya que está usando Asp.net MVC, sospecho que está usando jQuery en el lado del cliente. Le sugiero que lea esta publicación de blog que tiene un código de cómo usar $.parseJSON para convertir automáticamente las fechas para usted.

El código admite fechas con formato Asp.net como las que usted mencionó, así como fechas con formato ISO. Todas las fechas se formatearán automáticamente usando $.parseJSON() .


Aquí hay un código JavaScript que escribí que establece un valor de <input type="date"> partir de una fecha pasada desde 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); } };

Llamas a esta función así:

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

Donde commissionStartDate es la fecha JSON pasada por MVC.


Descubrí que crear un nuevo JsonResult y devolver eso no es satisfactorio, tener que reemplazar todas las llamadas para return Json(obj) con return new MyJsonResult { Data = obj } es una molestia.

Así que pensé, ¿por qué no secuestrar el JsonResult usando 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)); } } } }

Esto se puede aplicar a cualquier método que devuelva un JsonResult para usar JSON.Net en su lugar:

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

que responderá con

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

¡como se desee!

Puede, si no le importa llamar a la comparación en cada solicitud, agregue esto a su FilterConfig :

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

y todo su JSON ahora será serializado con JSON.Net en lugar del JavaScriptSerializer incorporado.


Devuelve el formato de fecha del servidor. Necesitas definir tu propia función.

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

};


Esta es mi solución en Javascript, muy parecida a JPot, pero más corta (y posiblemente un poco más rápida):

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

"value.substr (6)" saca la parte "/ Date (" y la función parseInt ignora los caracteres que no son números que aparecen al final.

EDITAR: he intencionalmente omitido el radix (el segundo argumento a analizar); ver mi comentario a continuación . Además, tenga en cuenta que las fechas ISO-8601 son preferibles a este formato antiguo, por lo que este formato generalmente no debe usarse para nuevos desarrollos. Vea la excelente biblioteca Json.NET para una excelente alternativa que serializa fechas utilizando el formato ISO-8601.

Para las fechas JSON con formato ISO-8601, simplemente pase la cadena al constructor Fecha:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support


Formato de la fecha dentro de la consulta.

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

El único problema con esta solución es que no obtendrá ningún resultado si CUALQUIERA de los valores de fecha son nulos. Para evitar esto, puede poner declaraciones condicionales en su consulta ANTES de seleccionar la fecha que ignora los nulos de la fecha o puede configurar una consulta para obtener todos los resultados y luego recorrer toda esa información usando un bucle foreach y asignar un valor a todas las fechas que sean nulas ANTES de hacer su SELECCIONAR nuevo.

Ejemplo de ambos:

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

La segunda opción requiere otra consulta por completo para que pueda asignar valores a todos los valores nulos. Esto y el bucle foreach tendrían que ser ANTES de su consulta que seleccione los valores.

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"); } }

Solo una idea que encontré más fácil que todos los ejemplos de javascript.


Hay bastantes respuestas para manejar el lado del cliente, pero puede cambiar el lado del servidor de salida si lo desea.

Hay algunas maneras de enfocar esto, comenzaré con lo básico. Tendrá que subclasificar la clase JsonResult y anular el método ExecuteResult. A partir de ahí puede tomar algunos enfoques diferentes para cambiar la serialización.

Enfoque 1: la implementación predeterminada utiliza el JsonScriptSerializer . Si echa un vistazo a la documentación, puede usar el método RegisterConverters para agregar JavaScriptConverters personalizados. Sin embargo, hay algunos problemas con esto: el JavaScriptConverter se serializa a un diccionario, es decir, toma un objeto y se serializa a un diccionario Json. Para hacer que el objeto se serialice en una cadena, se requiere un poco de piratería, vea la post . Este hack en particular también se escapará de la cadena.

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)); } } }

Enfoque 2 (recomendado): el segundo enfoque es comenzar con el JsonResult anulado e ir con otro serializador Json, en mi caso, el serializador Json.NET . Esto no requiere la piratería del enfoque 1. Aquí está mi implementación de la subclase 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)); } } }

Ejemplo de uso:

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

Créditos adicionales: James Newton-King


He estado trabajando en una solución a este problema ya que ninguna de las respuestas anteriores realmente me ayudó. Estoy trabajando con el calendario de jquery week y necesité mis fechas para tener información de zona horaria en el servidor y localmente en la página. Después de investigar un poco, encontré una solución que podría ayudar a otros.

Estoy usando asp.net 3.5, vs 2008, asp.net MVC 2 y calendario de jquery week,

Primero, estoy usando una biblioteca escrita por Steven Levithan que ayuda a manejar las fechas en el lado del cliente, la biblioteca de fechas de Steven Levithan . El formato isoUtcDateTime es perfecto para lo que necesitaba. En mi llamada AJAX de jquery, uso la función de formato provista con la biblioteca con el formato isoUtcDateTime y cuando la llamada ajax llega a mi método de acción, el Tipo de fecha y hora se establece en local y refleja la hora del servidor.

Cuando envío fechas a mi página a través de AJAX, las envío como cadenas de texto formateando las fechas usando "ddd, dd MMM yyyy HH '':'' mm '':'' ss ''GMT''zzzz". Este formato se convierte fácilmente del lado del cliente usando

var myDate = new Date(myReceivedDate);

Aquí está mi solución completa menos la fuente de Steve Levithan, que puede descargar:

Controlador:

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>

Espero que este rápido ejemplo ayude a otros en la misma situación en la que estaba. En este momento, parece funcionar muy bien con la serialización JSON de Microsoft y mantiene las fechas correctas en todas las zonas horarias.


La comunicación Ajax entre el cliente y el servidor a menudo involucra datos en formato JSON. Si bien JSON funciona bien con cadenas, números y valores booleanos, puede plantear algunas dificultades para las fechas debido a la forma en que ASP.NET las serializa. Como no tiene ninguna representación especial para las fechas, se serializan como cadenas simples. Como solución, el mecanismo de serialización predeterminado de los formularios web de ASP.NET y MVC serializa las fechas en una forma especial - / Fecha (marcas) / - donde marcas es el número de milisegundos desde el 1 de enero de 1970.

Este problema se puede resolver de 2 maneras:

lado del cliente

Convierta la cadena de fecha recibida en un número y cree un objeto de fecha utilizando el constructor de la clase de fecha con las marcas como parámetro.

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();

}

lado del servidor

La solución anterior utiliza un script del lado del cliente para convertir la fecha en un objeto Fecha de JavaScript. También puede usar el código del lado del servidor que serializa las instancias de .NET DateTime en el formato de su elección. Para realizar esta tarea, debe crear su propio ActionResult y luego serializar los datos de la forma que desee.

referencia: http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html


La más fácil:

var milisegundos = parseInt (data.replace ("/ Date (", "") .replace (") /", ""));
Var newDate = new Date (milisegundos). toLocaleDateString ("en-UE");


La mejor manera de manejar las fechas en knockoutjs es usar la biblioteca del momento y manejar las fechas como jefe. Puede tratar fácilmente con fechas como / Fecha (-62135578800000) /. No hay necesidad de preocuparse de cómo su fecha de serialización en el controlador.

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

utilízalo como

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

momentjs admite muchos formatos de fecha y hora y funciones de utilidad en las fechas.


Lo que funcionó para mí fue crear un modelo de vista que contuviera la propiedad de fecha como una cadena. Asignando la propiedad DateTime desde el modelo de dominio y llamando a .ToString () en la propiedad de fecha mientras asigna el valor al modelo de vista.

Un resultado JSON de un método de acción MVC devolverá la fecha en un formato compatible con la vista.

Ver Modelo

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

Modelo de dominio

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

Método de acción del controlador

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); }


Molesto, ¿no es así?

Mi solución fue cambiar mi servicio WCF para que devuelva DateTimes en un formato más legible (no Microsoft). Observe a continuación, el " UpdateDateOriginal ", que es el formato de fechas predeterminado de WCF, y mi " UpdateDate ", que está formateado para algo más legible.

Aquí está cómo hacerlo:

Cambio de formato de fecha WCF

Espero que esto ayude.



No es la forma más elegante pero esto funcionó para mí:

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; }


No por nada, pero hay otra manera. Primero, construye tu consulta LINQ. Luego, construya una consulta del resultado Enumerado y aplique cualquier tipo de formato que funcione para usted.

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") };

Tengo que decir que el paso adicional es molesto, pero funciona bien.


Puedes usar este método:

String.prototype.jsonToDate = function(){ try{ var date; eval(("date = new " + this).replace(////g,'''')); return date; } catch(e){ return new Date(0); } };



Solo para ampliar la respuesta de casperOne .

La especificación JSON no tiene en cuenta los valores de fecha. MS tuvo que hacer una llamada, y la ruta que eligieron fue explotar un pequeño truco en la representación javascript de cadenas: la cadena literal "/" es la misma que "/ /", y una cadena literal nunca se serializará a " / / "(incluso" / / "debe asignarse a" // / ").

Consulte http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2 para obtener una mejor explicación (desplácese hasta "De los literales de JavaScript a JSON")

Uno de los puntos importantes de JSON es la falta de un literal de fecha / hora. Muchas personas se sorprenden y se sienten decepcionadas de aprender esto cuando se encuentran con JSON. La explicación simple (de consolación o no) para la ausencia de un literal de fecha / hora es que JavaScript nunca tuvo uno: el soporte para los valores de fecha y hora en JavaScript se proporciona completamente a través del objeto Date. Por lo tanto, la mayoría de las aplicaciones que usan JSON como formato de datos, por lo general, tienden a usar una cadena o un número para expresar los valores de fecha y hora. Si se utiliza una cadena, generalmente puede esperar que esté en el formato ISO 8601. Si se usa un número, en cambio, el valor generalmente se toma como el número de milisegundos en el Tiempo Universal Coordinado (UTC) desde la época, donde la época se define como la medianoche del 1 de enero de 1970 (UTC). Nuevamente, esto es una mera convención y no es parte del estándar JSON. Si está intercambiando datos con otra aplicación, deberá consultar su documentación para ver cómo codifica los valores de fecha y hora dentro de un literal JSON. Por ejemplo, ASP.NET AJAX de Microsoft no utiliza ninguna de las convenciones descritas. Más bien, codifica los valores de .NET DateTime como una cadena JSON, donde el contenido de la cadena es / Fecha (marcas) / y donde las marcas representan milisegundos desde la época (UTC). Así que el 29 de noviembre de 1989, 4:55:30 AM, en UTC se codifica como "/ / Date (628318530718) / /".

Una solución sería simplemente analizarlo:

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

Sin embargo, he escuchado que hay una configuración en algún lugar para que el serializador DateTime objetos DateTime con la new Date(xxx) sintaxis de new Date(xxx) . Voy a tratar de desenterrar eso.

El segundo parámetro de JSON.parse() acepta una función reviver en la que prescribe cómo el valor originalmente producido antes de ser devuelto.

Aquí hay un ejemplo para la fecha:

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; });

Ver los documentos de JSON.parse()


Tuve el mismo problema y, en lugar de devolver el valor de fecha real, solo usé ToString ("dd MMM yyyy") en él. Luego, en mi javascript, utilicé la nueva Fecha (valor de fecha), donde el valor de fecha puede ser "01 de enero de 2009".


Ver este hilo:

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

Básicamente, mientras que el formato Fecha () es un javascript válido, NO es un JSON válido (hay una diferencia). Si desea el formato antiguo, probablemente tendrá que crear una fachada y transformar el valor, o encontrar una manera de obtener el serializador para su tipo en el JsonResult y hacer que use un formato personalizado para las fechas.


Agregue el plugin jquery ui en su página.

function JsonDateFormate(dateFormate, jsonDateTime) { return $.datepicker.formatDate(dateFormate, eval(''new '' + jsonDateTime.slice(1, -1))); };