Modifier la sérialisation de date par défaut dans WCF

y a-t-il quoi qu'il en soit pour changer la sérialisation/désérialisation JSON par défaut de DateTime dans WCF?

actuellement, DateTime sont sérialisés dans le format /Date(1372252162657+0200)/ , ce qui aurait dû être bien, mais je suis en train de rencontrer des problèmes quand mon serveur n'est pas en UTC (que je ne peux pas changer).

toutes les données de date/heure traitées par ce service sont au format UTC. Tout fonctionne lorsque le serveur est en UTC. Cependant, les environnements staging / prod sont définis à GMT+1 (Paris) et le sérialiseur suppose que les dates/heures sont en GMT+1, ignorant complètement l'attribut Kind . Comme vous vous y attendiez, appeler DateTime.SetKind() et le configurer sur UTC ne marchera pas. En effet, les temps de publication en série sont retardés d'une heure.

je peux soit faire des conversations de date bidirectionnelles (il fait aussi la même hypothèse lors de la desérialisation ainsi son toujours GMT+1) conversation de dates: UTC à/de l'heure du serveur, mais c'est trop fastidieux. J'Ai Donc j'ai pensé que je pourrais juste annuler le comportement de sérialisation par défaut.

13
demandé sur Mel 2013-08-29 16:33:42

5 réponses

Oui, cela peut être fait en utilisant le concept appelé " "151920920 le Message" Formatage "

mais le Formatteur de Message serait difficile et hors de portée pour expliquer ici sur le débordement de pile. Vous pouvez référencer WCF extensibilité : formateurs de Message

Si vous ne voulez pas gâcher, avec ce alors un hack est disponible.

définit le type de retour de chaque méthode à streamer.

par exemple

        public Stream GetStaticData()
        {
            var objTobeReturned = something;
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
            return new MemoryStream(Encoding.UTF8.GetBytes(objTobeReturned.ToJson()));
        }

ici ToJson () est ma propre méthode d'extension qui convertit l'objet en chaîne json en utilisant la bibliothèque NewtonSoft.

WCF sautera la sortie de flux pour sérialiser et le passera à votre client comme il est.

j'espère que vous avez eu votre réponse.

4
répondu Patel 2013-08-29 12:48:21

juste pour développer sur tdelepine code snippet", voici le code que j'ai utilisé:

dans mon Service WCF JSON, j'avais une valeur (nulle) DateTime, et je voulais que mon service renvoie la date dans un format plus lisible, pour que mon application iPhone puisse l'interpréter.

voici à quoi ressemblait mon JSON, après avoir appliqué quelques modifications:

enter image description here

avis le champ UpdateDateOriginal , qui est la manière par défaut que WCF écrit DateTimes, et le champ UpdateDate , plus convivial, que j'ai créé en utilisant le code ci-dessous.

mes lignes originales ressemblaient à ceci:

[DataMember]
public DateTime? UpdateDateOriginal { get; set; }

... et voici les lignes pour créer le nouveau plus convivial UpdateDate valeur JSON.

[IgnoreDataMember]
public DateTime? UpdateDate { get; set; }

[DataMember(Name = "UpdateDate")]
private string UpdateDateString { get; set; }

[OnSerializing]
void OnSerializing(StreamingContext context)
{
    if (this.UpdateDate == null)
    this.UpdateDateString = "";
    else
    this.UpdateDateString = this.UpdateDate.Value.ToString("MMM/dd/yyyy HH:mm", CultureInfo.InvariantCulture);
}

[OnDeserialized]
void OnDeserializing(StreamingContext context)
{
    if (this.UpdateDateString == null)
    this.UpdateDate = null;
    else
    this.UpdateDate = DateTime.ParseExact(this.UpdateDateString, "MMM/dd/yyyy HH:mm", CultureInfo.InvariantCulture);
}

en fait, vous pourriez trouver plus utile de retourner les valeurs DateTime au format ISO8601. Exemple:

UpdateTime: "2014-08-24T13:02:32",

pour ce faire, utilisez simplement mon code ci-dessus, mais changez la chaîne de caractères "MMM/dd/yyyy HH:mm" en "s" aux deux endroits.

et, si vos valeurs DateTime sont stockées dans UTC, mais que vous vouliez que vos services WCF retournent les valeurs dans le fuseau horaire local de l'utilisateur, vous pouvez suivre mes conseils ici:

Obtenir DateTime dans les utilisateurs de fuseau horaire local

N'est pas plus facile, avec quelques simples des exemples !

17
répondu Mike Gledhill 2017-05-23 11:54:28

vous pouvez utiliser cette solution, dans votre définition d'objet json

[IgnoreDataMember]
public DateTime dateObject;

public string dateCustomSerialize
{
 get {
//Custom get
}
set {
//Custom set
}
}

Dans évaluateur placez votre format personnalisé de la sérialisation

12
répondu tdelepine 2013-08-29 12:50:49

une façon est d'utiliser un formatteur de message pour changer le défaut DataContractSerializer comme décrit dans WCF extensibilité – Formatteurs de Message .

une autre option est d'écrire une méthode d'extension qui charge votre objet dans un flux et ensuite vous pouvez appliquer n'importe quel sérialiseur que vous voulez à l'objet. Voir la réponse acceptée pour remplacer serializer par défaut JSON dans WCF 4 à JSON.NET pour plus de détails.

0
répondu Karl Anderson 2017-05-23 12:09:56

cela ne résout pas votre problème de fuseaux horaires, mais je vais le poster ici pour les autres qui se battent avec WCF, ticks et DateTime.

si vous ne voulez pas de tiques, mais un format de temps lisible par l'homme, vous pouvez le faire en introduisant une propriété supplémentaire string . Il s'agit alors de jouer avec le DateTime avant de transformer la valeur en chaîne.

    [IgnoreDataMember]    // Ignore the original tick date.
    public DateTime LastReminderDate { get { return _lastReminderDate; } set { _lastReminderDate = value; } }
    [DataMember]          // Make sure you have a public or private setter!
    public string LastReminderDateText { get { return _lastReminderDate.ToString(); } set { _lastReminderDate = DateTime.Parse(value); } }
0
répondu Robotron 2017-12-01 17:02:31