使用日期向WCF REST发送JQuery JSON

18

我知道有很多关于如何通过JQuery/JSON使用WCF REST的帖子,但我无法让它正常工作。我目前遇到了一个日期参数问题。以下是我的C#方法:

[OperationContract]
[WebInvoke]
[TransactionFlow(TransactionFlowOption.Allowed)]
string GoodRegister(DateTime pDtTimeStampTransac, Int32 pIDResource, Decimal pQty, enQtyLogType pQtyGoodLogType);

以下是我的JavaScript代码:

/// <reference path="../Scripts/jquery-1.4.1-vsdoc.js" />
/// <reference path="json.js" />

Date.prototype.toMSJSON = function () {
  var date = '\\\/Date(' + this.getTime() + ')\\\/';
  return date;
};

function botaoclick() {
  var date = new Date().toMSJSON();
  var datavar = {
    'pDtTimeStampTransac': date,
    'pIDResource': 1,
    'pQty': 1
  };
  $.ajax(
  {
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "http://desk01:9876/ShopFloorService/script/GoodRegister",
    dataType: "json",
    data: JSON.stringify(datavar),
    //data: '{"pDtTimeStampTransac":date, "pIDResource":"teste", "pQty":"3"}',
    error: jqueryError,
    success: function (msg) {
      alert("back");
      var divForResult = document.getElementById("test");
      divForResult.innerHTML = "Result: <b>" + msg.d + "</b>";
    }
  }
  )
}

function jqueryError(request, status, error) {
  alert(request.responseText + " " + status + " " + error);
}

我的第一个问题是我一直收到日期序列化错误:

{"ExceptionDetail":{"HelpLink":null,"InnerException":{"HelpLink":null,"InnerException":{"HelpLink":null,"InnerException":null,"Message":"DateTime content '\\\/Date(1292616078638)\\\/' does not start with '\\\/Date(' and end with ')\\\/' as required for JSON.","StackTrace":"   at System.Runtime.Serialization.Json.JsonReaderDelegator.ParseJsonDate(String originalDateTimeValue)\u000d\u000a   at 

它说它的开头和结尾并不像它现在的样子。

我的第二个问题是:我是否必须放弃枚举器,还是有一种方法可以发送它?

6个回答

45

这让我抓狂了,我不停地调试但都无济于事。最后,我在你的toMSJSON函数中修改了日期格式,WCF接受了这种格式,感谢Rick Strahl的帮助。

Date.prototype.toMSJSON = function () {
    var date = '/Date(' + this.getTime() + ')/'; //CHANGED LINE
    return date;
};

您还需要将日期转换为UTC时间,否则可能会出现各种有趣的问题,因此:

  var dt = ...;
  var dt1 = new Date(Date.UTC(dt.getFullYear(), dt.getMonth(), dt.getDate(),   dt.getHours(), dt.getMinutes(), dt.getSeconds(), dt.getMilliseconds()));
  var wcfDateStr = dt1.toMSJSON();

希望这个能帮到你。


匿名用户建议将 this.getUTCOffset() 添加到原型代码中。 - mplungjan

2
根据:http://msdn.microsoft.com/en-us/library/bb412170.aspx 日期时间线格式
日期时间值以JSON字符串形式出现,格式为“/Date(700000+0500)/”,其中第一个数字(示例中的700000)是自1970年1月1日午夜以来的GMT时区标准(非夏令时)毫秒数。该数字可以为负数以表示更早的时间。在示例中,“+0500”部分是可选的,并且表示该时间是本地类型 - 即应在反序列化时转换为本地时区。如果不存在,则将时间反序列化为UTC。实际数字(此示例中的“0500”)及其符号(+或-)将被忽略。
在序列化DateTime时,本地和未指定时间带有偏移量,而UTC则没有。
ASP.NET AJAX客户端JavaScript代码会自动将这些字符串转换为JavaScript DateTime实例。如果有其他具有类似形式但不属于.NET中DateTime类型的字符串,则也会进行转换。
只有在转义“/”字符时(即JSON看起来像“\/Date(700000+0500)\/”),才会进行转换,因此WCF的JSON编码器(由WebHttpBinding启用)始终转义“/”字符。
你的枚举器应该没问题。

我同意...但它没有起作用...最终我放弃了,并将我的接口更改为字符串。奇怪的是,它似乎是正确的,一切都好,但我仍然有一个错误。 - Pascal

0

在 @vas 的回答基础上进行构建:

// OrderRecievedDateTime is a proper date string
var tStart = new Date(OrderRecievedDateTime);
// Get date in UTC (required for WCF) as morning
var start = new Date(Date.UTC(tStart.getFullYear(), tStart.getMonth(), tStart.getDate(), 0, 0, 0));
// Get the ticks
var startTicks = start.getTime();

// Now build the JSON param (**notice I am passing the date value as a string, by including within quotes. Without this it doesn't takes it**).
var paramRequest = '{ "request": { "StartDate":"' + '\/Date(' + startTicks  + ')\/"'  + ' } }';

// Hit ajax, no need of any JSON.parse or stringify
$.ajax({ ..., data = paramRequest ..});

WCF以正确的格式接收日期。重要的补充是我们如何将日期作为字符串在JSON中传递。可以通过将键和/Date字符串的开头组合来进一步简化。

var paramRequest = '{ "request": { "StartDate":"\/Date(' + startTicks  + ')\/" } }';

0

这里有一个基本上无缝的解决方案来自这篇帖子(经过修改),你可以在客户端使用JSON.stringify()来实现:

jsonData = JSON.stringify([new Date()], 
    function (k, v) { return this[k] instanceof Date ? '/Date(' + v + ')/' : v; });

对于我来说,它可以在最新的IE、Chrome和Firefox中运行。

请查看JSON.stringify(一种本地方法)和replacer参数,以获取有关如何转换枚举的提示。


0

你好。

你需要做的就是响应错误。我指的是更改日期格式,以便json可以将其解析为Web服务。

你的代码应该是这样的:

       function botaoclick() {

         var date = new Date();
         date = "\/Date(" + date.valueOf() + ")\/";
         // valueOf() method Returns the primitive value of a Date object.

         var datavar = {
           'pDtTimeStampTransac': date,
           'pIDResource': 1,
           'pQty': 1
         };

         $.ajax({
           type: "POST",
           contentType: "application/json; charset=utf-8",
           url: "YOUR URL",
           dataType: "json",
           data: JSON.stringify(datavar),
           error: jqueryError,
           success: function(msg) {
             alert("back");
             var divForResult = document.getElementById("test");
             divForResult.innerHTML = "Result: <b>" + msg.d + "</b>";
           }
         })
       }

       function jqueryError(request, status, error) {
         alert(request.responseText + " " + status + " " + error);
       }


0

在传递给wcf之前,应该有一种通用的方法来正确格式化日期。

该方法可能如下所示:

var dateToWcf = function(input)
{
    var d = new Date(input); 
    if (isNaN(d)) return null;     
    var formattedDate = { date : "/Date(" + d.getTime() + ")/" };
    return formattedDate;
}

然而,现在如果您发布它,它将根据您发布的实际时区附加偏移值。因此,为了避免这种情况,您可以相应地调整偏移量。

var formattedDate = { date: "/Date(" + d.getTime() + d.getGMTOffset() + ")/" };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接