POSTing a DateTime from Android to a WCF RESTful J

2019-03-21 14:16发布

I'm trying to send a DateTime as a parameter to a method exposed over a WCF RESTful service with JSON encoding. The request looks like this:

POST http://IP:PORT/LogService/json/GetLogEntriesByModule HTTP/1.1
Content-Length: 100
Content-Type: application/json
Host: IP:PORT
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
Expect: 100-Continue

{"maxentries":10,"upperdate":"1280703601462","lowerdate":"1277938801462","module":"Windows Service"}

I tried several formats for the DateTime:

  • 2010-07-01T10:54:00 (which is send by the WCFTestClient application over NET.TCP and it gets results
  • \/Date(12345678+0100)\/
  • 01.07.2010 10:54:00

The method definition:

LogEntry[] GetLogEntriesByModule(
    string module,
    DateTime lowerDate,
    DateTime upperDate,
    int maxEntries,
    out bool maxEntriesReached
)

I always get the following response:

HTTP/1.1 200 OK
Content-Length: 60
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 02 Jul 2010 09:07:04 GMT

{"GetLogEntriesByModuleResult":[],"maxEntriesReached":false}

It seems the DateTime isn't correctly parsed, because there are several entries in the Llog for that time.

Does anyone know on how to do this?

Update: The problem was on the server side and has been resolved.

4条回答
乱世女痞
2楼-- · 2019-03-21 14:42

This is code I use to send from Android Java to .NET WebApp. Create a JSON object with a date in the W3C XML schema:

Calendar myCalendarObj = Calendar.getInstance(); // Snap a moment in time

JSONObject jObj = new JSONObject(); // Create a JSON object (org.json.JSONObject)

SimpleDateFormat jsonDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); // from java.text.SimpleDateFormat
String senddate = jsonDateFormat.format(myCalendarObj.getTime());
jObj.put("a_date_field", senddate);
查看更多
ゆ 、 Hurt°
3楼-- · 2019-03-21 14:43

The correct format for posting dates to WCF service is using: /Date(53244000000)/ where the number in brackets is the number of milliseconds since 1970 UTC Midnight.

Date dt = new Date();
long date = Date.UTC(dt.getYear(), dt.getMonth(), dt.getDay(), dt.getHours(),dt.getMinutes(), dt.getSeconds());
String senddate = "/date("+date+")/";

And then use it as below

inputparam.put("DateTime", datetime);
查看更多
\"骚年 ilove
4楼-- · 2019-03-21 14:51

I have to update the answer to this question, I needed to do the same and I used the accepted answer but the obtained Date was wrong, It was giving me a Date of a week before (Don't know why). I don't know much about the Date type of Java but I know some of their methods has been deprecated.

Being said that I think this is the most recent correct answer for this situation. Hope helps Someone else

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

.....

    final Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"));        
    cal.setTime(value); // Where Value is a Date
    final long date = cal.getTime().getTime();
    final String senddate = "/Date("+date+")/";

Note the use of Date with the Uppercase "D", this is also needed because it causes problems with the WCF (at least on my case, was stuck a lot just for the lowercase D)

I'm using it to consume a RESTful WCF with Jackson Library for JSON.

To add a complete answer it can be used this Way for a Date that you want to be serialized with jackson.

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.ser.std.SerializerBase;

/**
 * @author HECTOR
 *
 */
public class SerializeRESTDate extends SerializerBase<Date> {

    public SerializeRESTDate() {
        // TODO Auto-generated constructor stub
        this(Date.class);
    }

    @JsonCreator
    protected SerializeRESTDate(Class<Date> t) {
        super(t);
        // TODO Auto-generated constructor stub
    }



    @Override
    public void serialize(Date value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonGenerationException {


        final Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"));            
        cal.setTime(value);
        final long date = cal.getTime().getTime();
        final String senddate = "/Date("+date+")/";
        jgen.writeString(senddate);

    }



}

And use it like this in your class'property definition

@JsonSerialize(using = SerializeRESTDate.class)
    @JsonProperty("InspectionDate")
    /**
     * @return the _InspectionDate
     */
    public Date get_InspectionDate() {
        return _InspectionDate;
    }
查看更多
淡お忘
5楼-- · 2019-03-21 14:54

Just in case this helps somebody:

According to Microsoft, WCF uses a QueryStringConverter to do the url parsing. Thus, using this code (slight modification of the msdn example):

QueryStringConverter converter = new QueryStringConverter();
if (converter.CanConvert(typeof(DateTime)))
{
    string strValue = converter.ConvertValueToString(DateTime.UtcNow, typeof(DateTime));
    Console.WriteLine("the value = {0}", strValue);
}

we get the proper format for DateTime REST parameters: 2010-01-01T01:01:01Z

I did read that you tried this format, but just wanted to confirm that this is indeed the way it's supposed to work. I thought of answering since this question came up first when I searched for this.

This worked for me using .NET 4.0

查看更多
登录 后发表回答