我有一个控制器动作,它有效地简单地返回模型的JsonResult。所以,在我的方法中,我有如下内容:
return new JsonResult(myModel);
这很有效,除了一个问题。在模型中有一个日期属性,这似乎在Json结果中返回,如下所示:
"\/Date(1239018869048)\/"
我应该如何处理日期,以便它们以我所需的格式返回?或者我如何处理脚本上面的这种格式?
我有一个控制器动作,它有效地简单地返回模型的JsonResult。所以,在我的方法中,我有如下内容:
return new JsonResult(myModel);
这很有效,除了一个问题。在模型中有一个日期属性,这似乎在Json结果中返回,如下所示:
"\/Date(1239018869048)\/"
我应该如何处理日期,以便它们以我所需的格式返回?或者我如何处理脚本上面的这种格式?
请看这个帖子:
http://forums.asp.net/p/1038457/1441866.aspx#1441866
基本上,虽然Date()格式是有效的javascript,但它不是有效的JSON(有区别)。如果您想要使用旧格式,您可能必须自己创建一个外观并转换值,或者找到一种方法来获取JsonResult中类型的序列化器,并让它使用日期的自定义格式。
让我们扩展一下casperOne的答案。
JSON规范没有说明Date值。MS不得不进行调用,他们选择的路径是利用javascript字符串表示中的一个小技巧:字符串字面量“/”与“\/”相同,字符串字面量永远不会被序列化为“\/”(甚至“\/”也必须映射为“\\/”)。
参见http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2获得更好的解释(向下滚动到“从JavaScript文字到JSON”)
One of the sore points of JSON is the lack of a date/time literal. Many people are surprised and disappointed to learn this when they first encounter JSON. The simple explanation (consoling or not) for the absence of a date/time literal is that JavaScript never had one either: The support for date and time values in JavaScript is entirely provided through the Date object. Most applications using JSON as a data format, therefore, generally tend to use either a string or a number to express date and time values. If a string is used, you can generally expect it to be in the ISO 8601 format. If a number is used, instead, then the value is usually taken to mean the number of milliseconds in Universal Coordinated Time (UTC) since epoch, where epoch is defined as midnight January 1, 1970 (UTC). Again, this is a mere convention and not part of the JSON standard. If you are exchanging data with another application, you will need to check its documentation to see how it encodes date and time values within a JSON literal. For example, Microsoft's ASP.NET AJAX uses neither of the described conventions. Rather, it encodes .NET DateTime values as a JSON string, where the content of the string is /Date(ticks)/ and where ticks represents milliseconds since epoch (UTC). So November 29, 1989, 4:55:30 AM, in UTC is encoded as "\/Date(628318530718)\/".
一个解决办法就是把它解析出来:
value = new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10));
然而,我听说在某个地方有一个设置,可以让序列化器用新的Date(xxx)语法输出DateTime对象。我试着把它挖出来。
JSON.parse()的第二个参数接受一个恢复函数,其中规定了在返回值之前最初是如何生成值的。
下面是一个关于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;
});
查看JSON.parse()的文档
下面是我的Javascript解决方案——非常像JPot,但更短(可能更快一点):
value = new Date(parseInt(value.substr(6)));
"value.substr(6)"去掉"/Date("部分,parseInt函数忽略出现在结尾的非数字字符。
编辑:我故意省略了基数(parseInt的第二个参数);请看我下面的评论。另外,请注意ISO-8601日期比这种旧格式更受欢迎——因此这种格式通常不应该用于新的开发。
对于ISO-8601格式的JSON日期,只需将字符串传递给Date构造函数:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
这不是最优雅的方式,但对我来说很管用:
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;
}
我有同样的问题,而不是返回实际的日期值,我只是使用ToString(“dd MMM yyyy”)。然后在我的javascript中,我使用了新的日期(datevalue),其中datevalue可能是“01 Jan 2009”。
我一直在研究这个问题的解决方案,因为上面的答案都没有真正帮助到我。我正在使用jquery周日历,需要我的日期在服务器和本地页面上有时区信息。经过一番深入研究,我想出了一个可能会帮助到其他人的解决方案。
我使用asp.net 3.5, vs 2008, asp.net MVC 2,和jquery周日历,
首先,我使用Steven Levithan编写的一个库,它有助于处理客户端上的日期,Steven Levithan的日期库。isoUtcDateTime格式非常适合我所需要的。在我的jquery AJAX调用中,我使用isoUtcDateTime格式库提供的格式函数,当AJAX调用命中我的动作方法时,datetime Kind被设置为本地并反映服务器时间。
当我通过AJAX发送日期到我的页面时,我通过使用“ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz”格式化日期将它们作为文本字符串发送。这种格式在客户端使用时很容易转换
var myDate = new Date(myReceivedDate);
以下是我的完整解决方案,减去Steve Levithan的源代码,你可以下载:
控制器:
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>
我希望这个简单的例子能帮助那些和我处境相同的人。在这个时候,它似乎工作得很好与微软JSON序列化和保持我的日期跨时区正确。
使用jQuery自动转换日期$.parseJSON
注意:这个答案提供了一个jQuery扩展,添加了自动ISO和.net日期格式支持。
因为你使用Asp.net MVC,我怀疑你在客户端使用jQuery。我建议你阅读这篇有代码如何使用$的博客文章。parseJSON自动转换日期。
代码支持Asp.net格式的日期,就像你提到的,以及ISO格式的日期。所有日期都将使用$. parsejson()自动格式化。
在查询中格式化日期。
var _myModel = from _m in model.ModelSearch(word)
select new { date = ((DateTime)_m.Date).ToShortDateString() };
此解决方案的唯一问题是,如果任何日期值为空,则不会得到任何结果。为了解决这个问题,你可以在你选择忽略日期null的日期之前在你的查询中放入条件语句,或者你可以设置一个查询来获得所有结果,然后使用foreach循环遍历所有这些信息,并在你执行select new之前为所有日期赋值。
两者的例子:
var _test = from _t in adc.ItemSearchTest(word)
where _t.Date != null
select new { date = ((DateTime)_t.Date).ToShortDateString() };
第二个选项需要完全另一个查询,因此可以将值赋给所有空值。这个循环和foreach循环必须在选择值的查询之前。
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");
}
}
只是一个想法,我发现比所有的javascript例子更容易。
客户端有很多解决方案,但是如果您愿意,可以更改输出服务器端。
有一些方法可以解决这个问题,我将从基本的开始。您必须创建JsonResult类的子类,并重写ExecuteResult方法。在此基础上,您可以采用几种不同的方法来更改序列化。
方法1: 默认实现使用JsonScriptSerializer。如果查看文档,可以使用RegisterConverters方法添加自定义JavaScriptConverters。但是有一些问题:JavaScriptConverter序列化到一个字典,也就是它接受一个对象并序列化到一个Json字典。为了使对象序列化为字符串,它需要一点技巧,请参阅post。这个特殊的hack也将转义字符串。
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));
}
}
}
方法二(推荐): 第二种方法是从重写的JsonResult开始,然后使用另一个Json序列化器,在我的例子中是Json。净序列化器。这并不需要方法1的技巧。这是我的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));
}
}
}
使用的例子:
[HttpGet]
public ActionResult Index() {
return new CustomJsonResult { Data = new { users=db.Users.ToList(); } };
}
额外的学分: 詹姆斯Newton-King
在页面中添加jquery UI插件。
function JsonDateFormate(dateFormate, jsonDateTime) {
return $.datepicker.formatDate(dateFormate, eval('new ' + jsonDateTime.slice(1, -1)));
};
js是一个扩展的datetime库,它也支持这个功能。http://momentjs.com/docs/#/parsing/asp-net-json-dates/
ex - Date(1198908717056-0700):时刻(“”)
这可能会有帮助。恰好输出
它返回服务器日期格式。你需要定义自己的函数。
function jsonDateFormat(jsonDate) {
// Changed data format;
return (new Date(parseInt(jsonDate.substr(6)))).format("mm-dd-yyyy / h:MM tt");
};
这里是我写的一些JavaScript代码,它设置了一个<input type="date">值,从一个从ASP传递的日期。净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);
}
};
你可以这样调用这个函数:
setDate('#productCommissionStartDate', data.commissionStartDate);
其中commissionStartDate是MVC传递的JSON日期。
你可以使用这个方法:
String.prototype.jsonToDate = function(){
try{
var date;
eval(("date = new " + this).replace(/\//g,''));
return date;
}
catch(e){
return new Date(0);
}
};
不是没有原因,而是还有别的办法。首先,构造LINQ查询。然后,构造枚举结果的查询,并应用适合您的格式类型。
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") };
我不得不说,额外的步骤很烦人,但效果很好。
在knockoutjs中处理日期的更好方法是使用moment库并像boss一样处理日期。您可以轻松地处理/Date(-62135578800000)/这样的日期。不需要担心如何在控制器中序列化日期。
function jsonToDate(date,format) {
return moment(date).format(format);
}
像这样使用它
var formattedDate = jsonToDate(date,'MM/DD/YYYY')
Momentjs支持大量的日期时间格式和日期实用函数。
Ajax communication between the client and the server often involves data in JSON format. While JSON works well for strings, numbers and Booleans it can pose some difficulties for dates due to the way ASP.NET serializes them. As it doesn't have any special representation for dates, they are serialized as plain strings. As a solution the default serialization mechanism of ASP.NET Web Forms and MVC serializes dates in a special form - /Date(ticks)/- where ticks is the number of milliseconds since 1 January 1970.
这个问题有两种解决方法:
客户端
将接收到的日期字符串转换为数字,并使用日期类的构造函数以tick为参数创建日期对象。
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();
}
服务器端
前面的解决方案使用客户端脚本将日期转换为JavaScript date对象。您还可以使用服务器端代码以您选择的格式序列化. net DateTime实例。 要完成这个任务,你需要创建自己的ActionResult,然后以你想要的方式序列化数据。
参考: http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html
对我来说有用的是创建一个包含date属性为字符串的视图模型。从域模型分配DateTime属性,并在为视图模型分配值时调用date属性上的. tostring()。
来自MVC操作方法的JSON结果将以与视图兼容的格式返回日期。
视图模型
public class TransactionsViewModel
{
public string DateInitiated { get; set; }
public string DateCompleted { get; set; }
}
域模型
public class Transaction{
public DateTime? DateInitiated {get; set;}
public DateTime? DateCompleted {get; set;}
}
控制器动作方法
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);
}
我发现创建一个新的JsonResult并返回它是不令人满意的-必须用返回新的MyJsonResult {Data = obj}替换所有返回Json(obj)的调用是一种痛苦。
所以我想,为什么不只是劫持JsonResult使用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));
}
}
}
}
这可以应用于任何返回JsonResult以使用JSON的方法。网:
[JsonNetFilter]
public ActionResult GetJson()
{
return Json(new { hello = new Date(2015, 03, 09) }, JsonRequestBehavior.AllowGet)
}
它会回应
{"hello":"2015-03-09T00:00:00+00:00"}
根据需要!
你可以,如果你不介意在每个请求时调用is比较,添加这个到你的FilterConfig:
// ...
filters.Add(new JsonNetFilterAttribute());
所有的JSON都将被JSON序列化。Net而不是内置的JavaScriptSerializer。
很烦人,不是吗?
我的解决方案是改变我的WCF服务,让它以更可读(非微软)的格式返回DateTimes。请注意下面的“UpdateDateOriginal”,这是WCF的默认日期格式,以及我的“UpdateDate”,它被格式化为更易于阅读的格式。
以下是如何做到这一点:
更改WCF日期格式
希望这能有所帮助。
最简单的一个:
var milisegundos = parseInt(data.replace(“/Date(”, “”).replace(“)/”, “”)); Var newDate = new Date(milisegundos).toLocaleDateString("en-UE");
我发现这是更改服务器端的最简单的方法。
using System.Collections.Generic;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace Website
{
/// <summary>
/// This is like MVC5's JsonResult but it uses CamelCase and date formatting.
/// </summary>
public class MyJsonResult : ContentResult
{
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter> { new StringEnumConverter() }
};
public FindersJsonResult(object obj)
{
this.Content = JsonConvert.SerializeObject(obj, Settings);
this.ContentType = "application/json";
}
}
}
我遇到了一些JSON日期的问题,并决定通过在SQL中解决日期问题来摆脱这个问题。将日期格式更改为字符串格式
select flddate from tblName
select flddate, convert(varchar(12), flddate, 113) as fldDateStr from tblName
通过使用fldDateStr,问题消失了,我仍然可以使用日期字段进行排序或其他目的。
0
在你的cshtml中,
<tr ng-repeat="value in Results">
<td>{{value.FileReceivedOn | mydate | date : 'dd-MM-yyyy'}} </td>
</tr>
在你的JS文件中,也许是app。JS,
在app.controller之外,添加下面的过滤器。
这里的“mydate”是用来解析日期的函数。这里的"app"是包含angular.module的变量
app.filter("mydate", function () {
var re = /\/Date\(([0-9]*)\)\//;
return function (x) {
var m = x.match(re);
if (m) return new Date(parseInt(m[1]));
else return null;
};
});