รูปแบบวันที่ ASP.NET MVC JsonResult


248

ฉันมีแอคชั่นคอนโทรลเลอร์ที่สามารถคืน JsonResult ของโมเดลของฉันได้อย่างมีประสิทธิภาพ ดังนั้นในวิธีการของฉันฉันมีดังนี้:

return new JsonResult(myModel);

วิธีนี้ใช้งานได้ดียกเว้นปัญหาเดียว มีคุณสมบัติวันที่ในโมเดลและดูเหมือนว่าจะถูกส่งคืนในผลลัพธ์ Json ดังนี้:

"\/Date(1239018869048)\/"

ฉันควรจะจัดการกับวันที่เพื่อให้พวกเขากลับมาในรูปแบบที่ฉันต้องการ? หรือฉันจะจัดการรูปแบบนี้ด้านบนในสคริปต์ได้อย่างไร


ฉันได้โพสต์ผลลัพธ์ json net ของฉันไปที่ปัญหาเดียวกันมันแปลงวันที่เป็นรูปแบบ iso ทำให้ง่ายต่อการทำงานด้วย stackoverflow.com/questions/15778599/…
Kieran

โปรดดูลิงค์ด้านล่างนี้ ตรงไปข้างหน้า stackoverflow.com/a/60392503/5962626
Mohamedasiq

คำตอบ:


195

เพียงเพื่อขยายคำตอบของ casperOne

ข้อมูลจำเพาะ JSONไม่บัญชีสำหรับค่าวันที่ MS ต้องโทรออกและเส้นทางที่พวกเขาเลือกคือการใช้ประโยชน์จากเคล็ดลับเล็ก ๆ น้อย ๆ ในการแสดงสตริงของ javascript: สตริงตัวอักษร "/" เหมือนกับ "\ /" และสตริงตัวอักษรจะไม่ถูกทำให้เป็นอนุกรม " \ / "(แม้แต่" \ / "ต้องแมปกับ" \\ / ")

ดูhttp://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2สำหรับคำอธิบายที่ดีกว่า (เลื่อนลงไปที่ "จากตัวอักษร JavaScript เป็น JSON")

หนึ่งในจุดเจ็บของ JSON คือการขาดตัวอักษรวันที่ / เวลา หลายคนรู้สึกประหลาดใจและผิดหวังที่เรียนรู้สิ่งนี้เมื่อพวกเขาพบกับ JSON ครั้งแรก คำอธิบายง่ายๆ (การปลอบใจหรือไม่) สำหรับการไม่มีตัวอักษรวันที่ / เวลาคือ JavaScript ไม่เคยมีอย่างใดอย่างหนึ่ง: การสนับสนุนสำหรับค่าวันที่และเวลาใน JavaScript มีให้ทั้งหมดผ่านวัตถุวันที่ แอปพลิเคชันส่วนใหญ่ที่ใช้ JSON เป็นรูปแบบข้อมูลดังนั้นโดยทั่วไปมักใช้สตริงหรือตัวเลขเพื่อแสดงค่าวันที่และเวลา หากใช้สตริงคุณมักคาดหวังได้ว่าจะอยู่ในรูปแบบ ISO 8601 หากใช้ตัวเลขแทนค่าจะถูกนำมาใช้เพื่อหมายถึงจำนวนมิลลิวินาทีใน Universal Coordinated Time (UTC) นับตั้งแต่เวลายุคซึ่ง epoch ถูกกำหนดเป็นเที่ยงคืน 1 มกราคม 1970 (UTC) อีกครั้ง นี่เป็นเพียงการประชุมไม่ใช่ส่วนหนึ่งของมาตรฐาน JSON หากคุณกำลังแลกเปลี่ยนข้อมูลกับแอปพลิเคชันอื่นคุณจะต้องตรวจสอบเอกสารของมันเพื่อดูว่ามันเข้ารหัสค่าวันที่และเวลาภายในตัวอักษร JSON อย่างไร ตัวอย่างเช่น ASP.NET AJAX ของ Microsoft ไม่ใช้การประชุมที่อธิบายไว้ แต่จะเข้ารหัสค่า NET DateTime เป็นสตริง JSON โดยที่เนื้อหาของสตริงคือ / Date (ticks) / และตำแหน่งที่ ticks แสดงถึงมิลลิวินาทีนับตั้งแต่ epoch (UTC) ดังนั้น 29 พฤศจิกายน 1989, 4:55:30 น. ใน UTC จะถูกเข้ารหัสเป็น "\ / วันที่ (628318530718) \ /" NET AJAX ไม่ใช้การประชุมที่อธิบายไว้ แต่จะเข้ารหัสค่า NET DateTime เป็นสตริง JSON โดยที่เนื้อหาของสตริงคือ / Date (ticks) / และตำแหน่งที่ ticks แสดงถึงมิลลิวินาทีนับตั้งแต่ epoch (UTC) ดังนั้น 29 พฤศจิกายน 1989, 4:55:30 น. ใน UTC จะถูกเข้ารหัสเป็น "\ / วันที่ (628318530718) \ /" NET AJAX ไม่ใช้การประชุมที่อธิบายไว้ แต่จะเข้ารหัสค่า NET DateTime เป็นสตริง JSON โดยที่เนื้อหาของสตริงคือ / Date (ticks) / และตำแหน่งที่ ticks แสดงถึงมิลลิวินาทีนับตั้งแต่ epoch (UTC) ดังนั้น 29 พฤศจิกายน 1989, 4:55:30 น. ใน UTC จะถูกเข้ารหัสเป็น "\ / วันที่ (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 ()


1
ขอบคุณการแยกวิเคราะห์จะไปไหน
Jon Archway

รหัสที่ฉันโพสต์คือ JavaScript คุณจะใส่ไว้ในรหัสลูกค้าของคุณ
JPot

6
คุณสามารถย่อ js เป็น Date ใหม่ (parseInt (dateString.replace (/ \ / Date \ ((\ d +) \) \ // gi, "$ 1")))
kͩeͣmͮpͥͩ

6
ในความเป็นจริง regex นั้นถูกต้องมากขึ้นเมื่อแทนที่ (/ \ / วันที่ \ ((-? \ d +) \) \ // gi, "$ 1") เนื่องจากวันที่อาจถูกแสดงเป็นตัวเลข -ve ด้วย
Dokie

1
@HarshilShah parseInt()นั่นคืออาร์กิวเมนต์ที่สองสำหรับ มันบอกฟังก์ชั่นที่จะดึงจำนวนเต็มในระบบเลขฐาน 10 มันคือ Radix ถ้าคุณใส่8เข้าไปมันจะดึงเลขฐานแปด
AnalogWeapon

99

นี่คือโซลูชันของฉันใน Javascript - คล้ายกับ JPot แต่สั้นกว่า (และอาจเร็วกว่าเล็กน้อย):

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

"value.substr (6)" นำส่วน "/ Date (") ออกและฟังก์ชัน parseInt จะละเว้นอักขระที่ไม่ใช่ตัวเลขที่เกิดขึ้นในตอนท้าย

แก้ไข: ฉันมีความตั้งใจออก radix (อาร์กิวเมนต์ที่ 2 เพื่อแยกวิเคราะห์); ดูความคิดเห็นของฉันด้านล่าง นอกจากนี้โปรดทราบว่าวันที่ ISO-8601 เป็นที่ต้องการมากกว่ารูปแบบเก่าดังนั้นรูปแบบนี้จึงไม่ควรใช้สำหรับการพัฒนาใหม่ ดูห้องสมุดJson.NET ที่ยอดเยี่ยมสำหรับทางเลือกที่ยอดเยี่ยมที่จัดลำดับวันที่โดยใช้รูปแบบ ISO-8601

สำหรับวันที่จัดรูปแบบ JSON ของ ISO-8601 เพียงแค่ส่งสตริงไปยังตัวสร้าง Date:

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

1
+1 ฉันใช้วิธีแก้ปัญหาง่ายๆของคุณแล้วใส่มันเข้าไปในฟังก์ชันเรียกซ้ำ ดูที่นี่: danielsadventure.info/dotnetdatetime
Vivian River

7
คุณควรระบุ radix เสมอเมื่อใช้ parseInt [แหล่งที่มา]: developer.mozilla.org/en-US/docs/JavaScript/Reference/
......

6
@JohnZabroski: กฎทุกข้อมีข้อยกเว้น .NET date serializer จะไม่ส่งคืนจำนวนเต็มด้วยเลขศูนย์นำหน้าดังนั้นเราจึงสามารถปล่อยเลขฐานสิบ
Roy Tinker

4
เราเกือบจะเหมือนกัน เราใช้value.substr(6, 13)สำหรับลบอักขระอื่นที่ไม่ใช่ตัวเลข แต่ถ้าคุณทำอย่างนั้นทุกวันก่อน 04/26/1938 จะไม่ถูกต้อง! เราไม่รู้ว่าparseIntจะไม่สนใจอักขระที่ไม่ใช่ตัวเลข ขอบคุณ!
Ralph Jansen

2
@ JohnZabroski— parseIntควรละเว้นเลขศูนย์นำหน้าเป็นECMAScript ed 5 (2011)
RobG

69

มีคำตอบเล็กน้อยที่จะจัดการฝั่งไคลเอ็นต์ แต่คุณสามารถเปลี่ยนฝั่งเซิร์ฟเวอร์เอาต์พุตได้หากต้องการ

มีสองสามวิธีในการเข้าถึงสิ่งนี้ฉันจะเริ่มต้นด้วยพื้นฐาน คุณจะต้องคลาสย่อยคลาส JsonResult และแทนที่เมธอด ExecuteResult จากที่นั่นคุณสามารถใช้แนวทางที่แตกต่างกันสองสามอย่างเพื่อเปลี่ยนการทำให้เป็นอนุกรม

วิธีที่ 1: เริ่มต้นใช้งานใช้JsonScriptSerializer ถ้าคุณดูที่เอกสารที่คุณสามารถใช้ RegisterConverters วิธีการที่จะเพิ่มที่กำหนดเองJavaScriptConverters มีปัญหาเล็กน้อยเกี่ยวกับเรื่องนี้: JavaScriptConverter เป็นอนุกรมสำหรับพจนานุกรมนั่นคือการใช้วัตถุและทำให้เป็นอนุกรมกับพจนานุกรม Json ในการที่จะทำให้เป็นอันดับวัตถุสตริงมันต้องบิตของ hackery ดูโพสต์ แฮ็คนี้จะหนีจากสตริงโดยเฉพาะ

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 serializer อื่นในกรณีของฉันคือJson.NET serializer สิ่งนี้ไม่ต้องการแฮ็คของวิธีที่ 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


และรูปแบบอื่น ๆ เช่นการเงินหมายเลขประจำตัวโทรศัพท์และอื่น ๆ เป็นอย่างไรบ้าง ไม่เป็นการดีกว่าสำหรับการรับรูปแบบเหล่านี้จาก ModelMetadata และใช้มันเพื่อทำให้เป็นอนุกรมรุ่นกับ Json ได้อย่างไร
Luciano

1
นี่เป็นทางออกที่ดีที่สุด (คำตอบของ Dave ที่เน่าเสียง่าย) เซิร์ฟเวอร์รับผิดชอบการกำหนดรูปแบบวันที่ให้ถูกต้อง นอกจากนี้การมี JsonResult แบบกำหนดเองก็ให้ประโยชน์และการควบคุมมากมาย ฉันขอแนะนำให้ใช้วิธีการช่วยเหลือ "CustomJson (data)" ซึ่งจะทำให้ CustomJsonResult แสดงผลทันทีเนื่องจากมี "Json (data)" ซึ่งทำให้ JsonResult แสดงข้อมูลทันที
กีฬา

2
การแก้ไขหนึ่งรายการที่จำเป็นถ้าคุณใช้วิธีใดวิธีหนึ่งต่อไปนี้ - บรรทัดแรกควรเป็น: สตริง const ส่วนตัว _dateFormat = "yyyy-MM-ddTHH: mm: ss"; ฉันเพิ่ม "T"
Dominick

31

Moment.js เป็นไลบรารี datetime ที่กว้างขวางซึ่งรองรับสิ่งนี้ http://momentjs.com/docs/#/parsing/asp-net-json-dates/

เช่นช่วงเวลา ("/ วันที่ (1198908717056-0700) /")

มันอาจช่วยได้ เอาท์พุทพลั่ว


ดาวน์โหลดไฟล์ moment.js ครั้งแรก เพิ่มในโครงการของคุณมากกว่าการใช้moment("json_date_string_value").format('appropriate format'); คุณสามารถเห็นค่ารูปแบบที่แตกต่างกันในหน้า
momet.js

20

ฉันพบว่าการสร้างใหม่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));
            }
        }
    }
}

สามารถใช้กับวิธีใด ๆ ที่ส่งคืน a JsonResultเพื่อใช้ JSON.Net แทน:

[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แทนในตัว


นี่เป็นคำตอบเดียวที่ให้แนวทางที่มั่นคง (สามารถตั้งค่าเป็นโกลบอลหรือแบบละเอียด) โดยไม่ต้องมีจาวาสคริปต์แบบอินไลน์ ฉันสามารถโหวตสองครั้งได้ไหม?
T-moty

19

ใช้ jQuery เพื่อแปลงวันที่ด้วย $.parseJSON

หมายเหตุ : คำตอบนี้ให้ส่วนขยาย jQuery ที่เพิ่มการรองรับรูปแบบ ISO และ. net อัตโนมัติ

เนื่องจากคุณใช้ Asp.net MVC ฉันสงสัยว่าคุณใช้ jQuery ทางฝั่งไคลเอ็นต์ ฉันขอแนะนำให้คุณอ่านโพสต์บล็อกนี้ซึ่งมีรหัสวิธีใช้$.parseJSONในการแปลงวันที่ให้คุณโดยอัตโนมัติ

โค้ดรองรับวันที่จัดรูปแบบ Asp.net เช่นเดียวกับวันที่คุณกล่าวถึงและวันที่จัดรูปแบบ ISO วันที่ทั้งหมดจะถูกจัดรูปแบบให้คุณโดย$.parseJSON()อัตโนมัติ


2
ตอนแรกฉันคิดว่าวิธีนี้ใช้ได้ดีมาก (ดูความคิดเห็นที่ส่วนท้ายของบทความสำหรับวิธีการลงทะเบียนตัวแปลงใน $ .ajaxSetup ()) อย่างไรก็ตามข้อเสียอย่างใหญ่หลวงของโซลูชันนี้คือมันไม่รองรับวันที่ก่อน Epoc (1970) ..... ดังนั้นตอนนี้ฉันก็เลย ตัดสินใจเลิกใช้ไฟล์. asmx และเปลี่ยนไปใช้ WebAPI ซึ่งรูปแบบวันที่ดีกว่า (ใช้ JSON.NET) และจะหลีกเลี่ยงปัญหาทั้งหมดนี้
ClearCloud8

11

การสื่อสาร Ajax ระหว่างไคลเอ็นต์และเซิร์ฟเวอร์มักเกี่ยวข้องกับข้อมูลในรูปแบบ JSON ในขณะที่ JSON ทำงานได้ดีสำหรับสตริงตัวเลขและบูลีนมันอาจทำให้เกิดปัญหาบางอย่างสำหรับวันที่เนื่องจาก ASP.NET เป็นอนุกรม เนื่องจากไม่มีการแสดงพิเศษสำหรับวันที่จึงมีการจัดลำดับเป็นสตริงธรรมดา ในฐานะที่เป็นวิธีแก้ปัญหากลไกการทำให้เป็นอันดับเริ่มต้นของ ASP.NET Web Forms และ MVC เป็นอนุกรมวันที่ในรูปแบบพิเศษ - / Date (ticks) / - โดยที่ ticks คือจำนวนมิลลิวินาทีตั้งแต่ 1 มกราคม 1970

ปัญหานี้สามารถแก้ไขได้ 2 วิธี:

ด้านลูกค้า

แปลงสตริงวันที่ที่ได้รับเป็นตัวเลขและสร้างวัตถุวันที่โดยใช้ Constructor ของคลาสวันที่ด้วยเครื่องหมายถูกเป็นพารามิเตอร์

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 นอกจากนี้คุณยังสามารถใช้รหัสฝั่งเซิร์ฟเวอร์ที่จัดลำดับอินสแตนซ์. NET DateTime ในรูปแบบที่คุณเลือก ในการทำภารกิจนี้ให้สำเร็จคุณต้องสร้าง ActionResult ของคุณเองแล้วจัดลำดับข้อมูลตามที่คุณต้องการ

อ้างอิง: http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html


7

ฉันมีปัญหาเดียวกันและแทนที่จะคืนค่าวันที่จริงฉันเพิ่งใช้ ToString ("dd MMM yyyy") กับมัน จากนั้นในจาวาสคริปต์ของฉันฉันใช้ Date ใหม่ (datevalue) โดย datevalue อาจเป็น "01 Jan 2009"


1
นี้ควรมี upvotes มากขึ้น อย่างน้อยก็ดีเหมือน upvoted ที่สุด เล็ก ๆ น้อย ๆ ที่สง่างามกว่าการตัดสาย โดยส่วนตัวแล้วฉันใช้สิ่งนี้ แต่ไม่ได้สร้างวัตถุวันที่ที่ส่วนหน้าเนื่องจากฉันต้องการแสดงมันดังนั้นฉันจึงแสดงสตริงที่จัดรูปแบบ (แตกต่างกันเล็กน้อย) ขอบคุณสำหรับเคล็ดลับ @Joe!
vbullinger

1
มันจะแยกความกังวลออกไปเช่นวางข้อกังวลว่าวันที่จะแสดงในส่วนหน้าในส่วนหลัง แต่มันก็ยังดูดีกว่า
A. Murray

1
ทำไมไม่ใช้อะไรที่เปราะบางน้อยกว่าToString("o")ล่ะ?
binki

"dd MMM yyyy" ไม่รองรับโดย ECMA-262 ดังนั้นคุณไม่ควรคาดหวังตัวแยกวิเคราะห์ในตัวที่จะแยกวิเคราะห์
RobG

3

ดูกระทู้นี้:

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

โดยทั่วไปในขณะที่Date()รูปแบบเป็นจาวาสคริปต์ที่ถูกต้อง แต่ก็ไม่ถูกต้อง JSON (มีความแตกต่าง) หากคุณต้องการรูปแบบเก่าคุณอาจต้องสร้างส่วนหน้าและแปลงค่าด้วยตัวคุณเองหรือหาวิธีที่จะได้รับ serializer สำหรับประเภทของคุณในJsonResultและใช้รูปแบบที่กำหนดเองสำหรับวันที่


คิดว่าคุณหมายถึง "ในขณะที่รูปแบบ Date () ใหม่เป็นจาวาสคริปต์ที่ถูกต้อง" [ทราบคำหลัก "ใหม่" หรือไม่?
JPot

2

ไม่ใช่วิธีที่หรูหราที่สุด แต่สิ่งนี้ใช้ได้กับฉัน:

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

ฉันทำงานเกี่ยวกับวิธีแก้ไขปัญหานี้เนื่องจากไม่มีคำตอบใดที่ช่วยฉันได้ ฉันทำงานกับปฏิทิน jquery Week และต้องการวันที่ของฉันเพื่อให้มีข้อมูลโซนเวลาบนเซิร์ฟเวอร์และภายในเครื่องบนหน้าเว็บ หลังจากขุดไปรอบ ๆ ฉันหาวิธีแก้ปัญหาที่อาจช่วยคนอื่น

ฉันใช้ asp.net 3.5, vs 2008, asp.net MVC 2 และ jQuery week calendar

ครั้งแรกผมกำลังใช้ห้องสมุดที่เขียนโดยสตีเว่น Levithan ที่จะช่วยให้มีการจัดการกับวันที่บนฝั่งไคลเอ็นต์, สตีเว่น Levithan ห้องสมุดวัน รูปแบบ isoUtcDateTime เหมาะสำหรับสิ่งที่ฉันต้องการ ใน jquery โทร AJAX ของฉันฉันใช้ฟังก์ชั่นการจัดรูปแบบให้กับห้องสมุดที่มีรูปแบบ isoUtcDateTime และเมื่อการโทร ajax นิยมวิธีการกระทำของฉันชนิด datetime ตั้งเป็นท้องถิ่นและสะท้อนให้เห็นถึงเวลาเซิร์ฟเวอร์

เมื่อฉันส่งวันที่ไปยังหน้าของฉันผ่าน 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>

ฉันหวังว่าตัวอย่างรวดเร็วนี้จะช่วยผู้อื่นในสถานการณ์เดียวกันกับฉันในเวลานี้ดูเหมือนว่าจะทำงานได้ดีกับ Microsoft JSON Serialization


หากคุณสามารถระบุรูปแบบของวันที่ได้คุณควรใช้ ISO 8601 เพิ่มเติมเนื่องจากเป็นรูปแบบเดียวที่ ECMA-262 ต้องการการสนับสนุน
RobG

2

วิธีที่ดีกว่าในการจัดการเดทใน knockoutjs คือการใช้ไลบรารี่ช่วงเวลาและจัดการกับวันที่อย่างเจ้านาย คุณสามารถจัดการกับวันที่เช่น / Date (-62135578800000) / ไม่ต้องกังวลว่าวันที่ซีเรียลไลซ์ของคุณในคอนโทรลเลอร์

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

ใช้มันเหมือน

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

momentjsสนับสนุนรูปแบบเวลาวันที่จำนวนมากและฟังก์ชั่นยูทิลิตี้ในวันที่


1

จัดรูปแบบวันที่ภายในแบบสอบถาม

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

ปัญหาเดียวของวิธีนี้คือคุณจะไม่ได้รับผลลัพธ์ใด ๆ หากค่าวันที่ใด ๆ เป็นโมฆะ ในการหลีกเลี่ยงปัญหานี้คุณสามารถใส่คำสั่งแบบมีเงื่อนไขลงในคิวรีของคุณก่อนที่คุณจะเลือกวันที่ละเว้นโมฆะวันที่หรือคุณสามารถตั้งค่าคิวรีเพื่อรับผลลัพธ์ทั้งหมดจากนั้นวนซ้ำข้อมูลทั้งหมดโดยใช้ foreach loop และกำหนดค่า ถึงวันที่ทั้งหมดที่เป็นโมฆะก่อนที่คุณจะเลือกใหม่

ตัวอย่างของทั้งสอง:

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

แค่ความคิดที่ฉันพบได้ง่ายกว่าตัวอย่างจาวาสคริปต์ทั้งหมด


1

คุณสามารถใช้วิธีนี้:

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

1

0

ใน cshtml ของคุณ

<tr ng-repeat="value in Results">                
 <td>{{value.FileReceivedOn | mydate | date : 'dd-MM-yyyy'}} </td>
</tr>

ในไฟล์ JS ของคุณอาจจะเป็น app.js

ด้านนอกของแอพควบคุมเพิ่มตัวกรองด้านล่าง

นี่คือ "mydate" เป็นฟังก์ชั่นที่คุณใช้ในการแยกวิเคราะห์วันที่ ที่นี่ "แอพ" เป็นตัวแปรที่มี 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;
    };
});

มันมีความเฉพาะเจาะจงมากสำหรับ angularjs ไม่ใช่ทุกคนที่ใช้มัน แต่ได้ผลสำหรับฉันขอบคุณ
Lauro182

0

เพิ่มปลั๊กอิน jquery ui ในหน้าของคุณ

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

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

ฉันต้องบอกว่าขั้นตอนพิเศษน่ารำคาญ แต่ก็ใช้งานได้ดี


0

สิ่งที่ใช้ได้ผลสำหรับฉันคือการสร้างมุมมองที่มีคุณสมบัติวันที่เป็นสตริง การกำหนดคุณสมบัติ DateTime จากรูปแบบโดเมนและเรียก. ToString () บนคุณสมบัติวันที่ในขณะที่กำหนดค่าให้กับ viewmodel

ผลลัพธ์ JSON จากวิธีการดำเนินการ MVC จะส่งคืนวันที่ในรูปแบบที่เข้ากันได้กับมุมมอง

ดูแบบจำลอง

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


0

น่ารำคาญใช่มั้ย

โซลูชันของฉันคือเปลี่ยนบริการ WCF ของฉันเพื่อให้ส่งคืน DateTimes ในรูปแบบที่อ่านได้มากกว่า (ไม่ใช่ของ Microsoft) โปรดสังเกตด้านล่าง " UpdateDateOriginal" ซึ่งเป็นรูปแบบวันที่เริ่มต้นของ WCF และ " UpdateDate" ซึ่งจัดรูปแบบเป็นสิ่งที่สามารถอ่านได้มากขึ้น

ป้อนคำอธิบายรูปภาพที่นี่

นี่คือวิธีการ:

การเปลี่ยนรูปแบบวันที่ WCF

หวังว่านี่จะช่วยได้


0

ฉันพบสิ่งนี้เป็นวิธีที่ง่ายที่สุดในการเปลี่ยนฝั่งเซิร์ฟเวอร์

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

0

ฉันมีปัญหาหลายอย่างเกิดขึ้นกับวันที่ของ JSON และตัดสินใจที่จะกำจัดปัญหาโดยการแก้ไขปัญหาวันที่ใน SQL เปลี่ยนรูปแบบวันที่เป็นรูปแบบสตริง

select flddate from tblName

select flddate, convert(varchar(12), flddate, 113) as fldDateStr from tblName

โดยใช้ fldDateStr ปัญหาหายไปและฉันยังคงสามารถใช้ฟิลด์วันที่สำหรับการเรียงลำดับหรือวัตถุประสงค์อื่น ๆ


0

ส่งคืนรูปแบบวันที่ของเซิร์ฟเวอร์ คุณต้องกำหนดฟังก์ชั่นของคุณเอง

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

0

นี่คือรหัส JavaScript ที่ฉันเขียนซึ่งตั้ง<input type="date">ค่าจากวันที่ส่งผ่านจาก 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);
  }
};

คุณเรียกฟังก์ชันนี้ว่า:

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

ไหนcommissionStartDateจะวัน JSON ผ่านไป MVC


-1

หนึ่งที่ง่ายที่สุด:

var milisegundos = parseInt (data.replace ("/ วันที่ (", "") .replace (") /", ""));
Var newDate = new Date (milisegundos) toLocaleDateString ("en-UE");

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.