I know that are a lot of posts about consuming a WCF REST through JQuery/JSON, but I can't get it to work. I'm currently stuck at a date parameter. Below is my C# method:
[OperationContract]
[WebInvoke]
[TransactionFlow(TransactionFlowOption.Allowed)]
string GoodRegister(DateTime pDtTimeStampTransac, Int32 pIDResource, Decimal pQty, enQtyLogType pQtyGoodLogType);
Below is my JavaScript code:
/// <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);
}
My first problem is that I keep getting a date serialization 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
It says it doesn't start/end the way it's starting and ending.
My second question is: Will I have to get ride of the enumerator, or is there a way to send it?
I pulled out a lot of hair and shed plenty a tear over this but this worked. I modified the date formatting in your toMSJSON function. WCF accepts this format which I realised thanks to Rick Strahl.
Date.prototype.toMSJSON = function () {
var date = '/Date(' + this.getTime() + ')/'; //CHANGED LINE
return date;
};
You also need to convert the dates to UTC time or you get all kinds of funny stuff, so:
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();
Hope this helps.
According to: http://msdn.microsoft.com/en-us/library/bb412170.aspx
DateTime Wire Format
DateTime values appear as JSON strings in the form of "/Date(700000+0500)/", where the first number (700000 in the example provided) is the number of milliseconds in the GMT time zone, regular (non-daylight savings) time since midnight, January 1, 1970. The number may be negative to represent earlier times. The part that consists of "+0500" in the example is optional and indicates that the time is of the Local kind - that is, should be converted to the local time zone on deserialization. If it is absent, the time is deserialized as Utc. The actual number ("0500" in this example) and its sign (+ or -) are ignored.
When serializing DateTime, Local and Unspecified times are written with an offset, and Utc is written without.
The ASP.NET AJAX client JavaScript code automatically converts such strings into JavaScript DateTime instances. If there are other strings that have a similar form that are not of type DateTime in .NET, they are converted as well.
The conversion only takes place if the "/" characters are escaped (that is, the JSON looks like "\/Date(700000+0500)\/"), and for this reason WCF's JSON encoder (enabled by the WebHttpBinding) always escapes the "/" character.
Your enumerator should be fine.
Here's a mostly seemless solution from This post (modified) which you'd put on the client with JSON.stringify():
jsonData = JSON.stringify([new Date()],
function (k, v) { return this[k] instanceof Date ? '/Date(' + v + ')/' : v; });
Which works in the latest IE, Chrome, and Firefox for me.
Check out JSON.stringify (a native method) and the replacer parameter for hints on converting your enum.
Alsalaam Aleykum.
All you have to do is to respond to the error. I mean change the date format so the json can parse it to the web service.
your code should look like this:
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);
}
There should be a generic method to format the date properly before passing to the wcf.
The method could look like this:
var dateToWcf = function(input)
{
var d = new Date(input);
if (isNaN(d)) return null;
var formattedDate = { date : "/Date(" + d.getTime() + ")/" };
return formattedDate;
}
However now if you post it would append the offset value based on the actual timezone from where you are posting.So in order to avert this you could then adjust the offset accordingly.
var formattedDate = { date: "/Date(" + d.getTime() + d.getGMTOffset() + ")/" };
Building over the answer by @vas above:-
// 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 receives the date in proper format. Important addition is how we passed the date in JSON as a string. Can be further simplified as follows by combining the key and start of /Date string
var paramRequest = '{ "request": { "StartDate":"\/Date(' + startTicks + ')\/" } }';