내 모델의 JsonResult를 효과적으로 반환하는 컨트롤러 작업이 있습니다. 그래서 내 방법에는 다음과 같은 것이 있습니다.
return new JsonResult(myModel);
이것은 하나의 문제를 제외하고는 잘 작동합니다. 모델에 날짜 속성이 있으며 이는 다음과 같이 Json 결과에 반환되는 것으로 나타납니다.
"\/Date(1239018869048)\/"
필요한 형식으로 반환되도록 날짜를 어떻게 처리해야합니까? 또는 스크립트에서이 형식을 어떻게 처리합니까?
답변
casperOne의 답변 을 확장하십시오 .
JSON 사양은 날짜 값을 고려하지 않습니다. MS는 전화를했고, 그들이 선택한 경로 문자열의 자바 스크립트 표현에 약간의 트릭을 악용했다 : 문자열 리터럴을 “/”, “\ /”와 동일하며, 문자열 리터럴이됩니다 결코 “에 연재하지 얻을 \ / “(“\ / “도”\\ / “에 매핑되어야 함)
자세한 설명 은 http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2 를 참조 하십시오 ( “JavaScript 리터럴에서 JSON으로”스크롤)
JSON의 아픈 점 중 하나는 날짜 / 시간 리터럴이 없다는 것입니다. 많은 사람들이 JSON을 처음 접했을 때 이것을 배우는 것에 놀랐고 실망했습니다. 날짜 / 시간 리터럴이없는 것에 대한 간단한 설명 (위안 여부)은 JavaScript에 다음 중 하나가 없다는 것입니다. JavaScript의 날짜 및 시간 값에 대한 지원은 전적으로 Date 객체를 통해 제공됩니다. 따라서 JSON을 데이터 형식으로 사용하는 대부분의 응용 프로그램은 일반적으로 날짜 또는 시간 값을 표현하기 위해 문자열 또는 숫자를 사용하는 경향이 있습니다. 문자열이 사용되는 경우 일반적으로 ISO 8601 형식 일 것으로 예상 할 수 있습니다. 대신 숫자를 사용하는 경우이 값은 일반적으로 에포크 이후의 UTC (Universal Coordinated Time)에서 밀리 초 수를 의미하는 것으로 간주되며, 여기서 에포크는 1970 년 1 월 1 일 자정 (UTC)으로 정의됩니다. 다시, 이것은 단순한 규칙이며 JSON 표준의 일부가 아닙니다. 다른 애플리케이션과 데이터를 교환하는 경우 문서를 확인하여 JSON 리터럴 내에서 날짜 및 시간 값을 인코딩하는 방법을 확인해야합니다. 예를 들어, Microsoft의 ASP.NET AJAX는 설명 된 규칙 중 어느 것도 사용하지 않습니다. 대신 .NET DateTime 값을 JSON 문자열로 인코딩합니다. 여기서 문자열의 내용은 / Date (ticks) /이고 틱은 에포크 (UTC) 이후 밀리 초를 나타냅니다. 1989 년 11 월 29 일 오전 4시 55 분 30 초 (UTC)는 “\ / Date (628318530718) \ /”로 인코딩됩니다. NET AJAX는 설명 된 규칙 중 어느 것도 사용하지 않습니다. 대신 .NET DateTime 값을 JSON 문자열로 인코딩합니다. 여기서 문자열의 내용은 / Date (ticks) /이고 틱은 에포크 (UTC) 이후 밀리 초를 나타냅니다. 1989 년 11 월 29 일 오전 4시 55 분 30 초 (UTC)는 “\ / Date (628318530718) \ /”로 인코딩됩니다. NET AJAX는 설명 된 규칙 중 어느 것도 사용하지 않습니다. 대신 .NET DateTime 값을 JSON 문자열로 인코딩합니다. 여기서 문자열의 내용은 / Date (ticks) /이고 틱은 에포크 (UTC) 이후 밀리 초를 나타냅니다. 1989 년 11 월 29 일 오전 4시 55 분 30 초 (UTC)는 “\ / Date (628318530718) \ /”로 인코딩됩니다.
해결책은 그냥 파싱하는 것입니다.
value = new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10));
그러나 serializer가 구문으로 DateTime
객체 를 출력하도록 설정하는 곳이 있다고 들었습니다 new Date(xxx)
. 나는 그것을 파 내려고 노력할 것이다.
의 두 번째 매개 변수는 반환되기 전에 값이 원래 생성 된 방식을 규정하는 함수 를 JSON.parse()
승인합니다 reviver
.
날짜의 예는 다음과 같습니다.
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의 솔루션은 다음과 같습니다.
value = new Date(parseInt(value.substr(6)));
“value.substr (6)”은 “/ Date (“부분을 가져오고 parseInt 함수는 끝에서 발생하는 숫자가 아닌 문자를 무시합니다.
편집 : 기수를 의도적으로 생략했습니다 (parseInt의 두 번째 인수). 아래 내 의견을 참조하십시오 . 또한 ISO-8601 날짜가이 이전 형식보다 선호되므로이 형식은 일반적으로 새로운 개발에 사용해서는 안됩니다. ISO-8601 형식을 사용하여 날짜를 직렬화하는 훌륭한 대안 은 훌륭한 Json.NET 라이브러리를 참조하십시오 .
ISO-8601 형식의 JSON 날짜의 경우 문자열을 Date 생성자에 전달하십시오.
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
답변
클라이언트 측을 처리하는 데 약간의 답변이 있지만 원하는 경우 출력 서버 측을 변경할 수 있습니다.
이것에 접근하는 몇 가지 방법이 있습니다. 기본부터 시작하겠습니다. JsonResult 클래스를 서브 클래 싱하고 ExecuteResult 메소드를 대체해야합니다. 거기에서 직렬화를 변경하는 몇 가지 방법을 사용할 수 있습니다.
접근법 1 :
기본 구현은 JsonScriptSerializer를 사용합니다 . 문서를 살펴보면 RegisterConverters 메소드를 사용하여 사용자 정의 JavaScriptConverters 를 추가 할 수 있습니다 . JavaScriptConverter는 사전으로 직렬화됩니다. 즉, 객체를 가져 와서 Json 사전으로 직렬화합니다. 객체를 문자열로 직렬화하려면 약간의 해커가 필요합니다 . post를 참조하십시오 . 이 특정 핵은 또한 문자열을 탈출합니다.
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));
}
}
}
접근 방식 2 (권장) :
두 번째 접근 방식은 재정의 된 JsonResult로 시작하여 다른 경우에는 Json.NET 직렬 변환기와 함께 다른 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(); } };
}
추가 크레딧 :
James Newton-King
답변
Moment.js는이를 지원하는 광범위한 날짜 / 시간 라이브러리입니다. http://momentjs.com/docs/#/parsing/asp-net-json-dates/
예 : moment ( “/ Date (1198908717056-0700) /”)
도움이 될 수 있습니다. 플 런커 출력
답변
나는 새를 만드는 것을 발견 JsonResult
하고 반환하는 것은 만족스럽지 – 모든 통화를 대체하는 데 return Json(obj)
에 return new MyJsonResult { Data = 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.Net을 대신 사용 하여 a 를 반환하는 모든 메소드에 적용될 수 있습니다 .
[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
.
답변
jQuery를 사용하여 날짜를 자동 변환 $.parseJSON
참고 :이 답변은 자동 ISO 및 .net 날짜 형식 지원을 추가하는 jQuery 확장을 제공합니다.
Asp.net MVC를 사용하고 있기 때문에 클라이언트 측에서 jQuery를 사용하고 있다고 생각합니다. 날짜를 자동으로 변환 하는 데 사용 하는 코드가있는 이 블로그 게시물 을 읽는 것이 좋습니다 $.parseJSON
.
코드는 언급 한 날짜 및 ISO 형식 날짜와 같은 Asp.net 형식 날짜를 지원합니다. 를 사용하여 모든 날짜가 자동으로 지정됩니다 $.parseJSON()
.
답변
클라이언트와 서버 간의 Ajax 통신에는 종종 JSON 형식의 데이터가 포함됩니다. JSON은 문자열, 숫자 및 부울에서 잘 작동하지만 ASP.NET에서 직렬화하는 방식으로 인해 날짜에 약간의 어려움이 발생할 수 있습니다. 날짜에 대한 특별한 표현이 없으므로 일반 문자열로 직렬화됩니다. 해결책으로 ASP.NET Web Forms 및 MVC의 기본 직렬화 메커니즘은 날짜를 특수한 형식 인 / Date (ticks) /-로 직렬화합니다. 여기서 ticks는 1970 년 1 월 1 일 이후의 밀리 초 수입니다.
이 문제는 두 가지 방법으로 해결할 수 있습니다.
고객 입장에서
수신 된 날짜 문자열을 숫자로 변환하고 눈금을 매개 변수로 사용하여 날짜 클래스의 생성자를 사용하여 날짜 오브젝트를 작성하십시오.
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