La pubblicazione di un DateTime da Android ad un RESTful JSON servizio WCF
-
02-10-2019 - |
Domanda
Sto cercando di inviare un DateTime
come parametro a un metodo esposto nel corso di un servizio WCF RESTful con la codifica JSON. Gli sguardi di richiesta come questo:
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"}
Ho provato diversi formati per la DateTime
:
-
2010-07-01T10:54:00
(che è inviare dall'applicazioneWCFTestClient
sopra net.tcp e ottiene risultati -
\/Date(12345678+0100)\/
-
01.07.2010 10:54:00
La definizione di metodo:
LogEntry[] GetLogEntriesByModule(
string module,
DateTime lowerDate,
DateTime upperDate,
int maxEntries,
out bool maxEntriesReached
)
Ho sempre trovato la seguente risposta:
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}
Sembra che il DateTime
non viene analizzato correttamente, perché ci sono diverse voci nel Llog per quel tempo.
Qualcuno sa su come fare questo?
Aggiorna :. Il problema era sul lato server ed è stato risolto
Soluzione
Il formato corretto per le date di pubblicazione di servizio WCF è utilizzando:
/Date(53244000000)/
dove il numero tra parentesi è il numero di millisecondi dal 1970 UTC di mezzanotte.
Date dt = new Date();
long date = Date.UTC(dt.getYear(), dt.getMonth(), dt.getDay(), dt.getHours(),dt.getMinutes(), dt.getSeconds());
String senddate = "/date("+date+")/";
E poi usarlo come di seguito
inputparam.put("DateTime", datetime);
Altri suggerimenti
Nel caso in cui questo aiuta qualcuno:
Secondo Microsoft, WCF utilizza un QueryStringConverter per fare il parsing di URL. Pertanto, utilizzando il codice (leggera modifica dell'esempio MSDN):
QueryStringConverter converter = new QueryStringConverter();
if (converter.CanConvert(typeof(DateTime)))
{
string strValue = converter.ConvertValueToString(DateTime.UtcNow, typeof(DateTime));
Console.WriteLine("the value = {0}", strValue);
}
si ottiene il formato corretto per i parametri DateTime REST: 2010-01-01T01: 01: 01Z
ho letto che si è tentato questo formato, ma ha voluto solo per confermare che questo è davvero il modo in cui dovrebbe funzionare. Ho pensato di rispondere a questa domanda in quanto è venuto prima, quando ho cercato per questo.
Questo ha funzionato per me usando .NET 4.0
Devo aggiornare la risposta a questa domanda, ho bisogno di fare lo stesso e ho usato la risposta accettata ma la data ottenuto era sbagliato, Mi stava dando una data di una settimana prima (non so perché). Non so molto circa il tipo Data di Java, ma so che alcuni dei loro metodi è stato sconsigliato.
Detto questo che penso che questa è la recente risposta più corretta per questa situazione. La speranza aiuta a qualcun altro
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+")/";
Si noti l'uso di Data con il maiuscolo "D" , questo è anche necessario perché provoca problemi con WCF (almeno sul mio caso, è stato bloccato un sacco solo per il minuscolo D)
Lo sto usando per consumare un RESTful WCF con Jackson Libreria per JSON.
Per aggiungere una risposta completa può essere utilizzato in questo modo per una data che si desidera essere serializzato con 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);
}
}
E usarlo come questo nella tua definizione class'property
@JsonSerialize(using = SerializeRESTDate.class)
@JsonProperty("InspectionDate")
/**
* @return the _InspectionDate
*/
public Date get_InspectionDate() {
return _InspectionDate;
}
Questo è il codice che uso per inviare da Android Java a .NET WebApp. Creare un oggetto JSON con una data nello schema W3C XML:
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);