IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

CalDAV : Erreur au moment de créer un événement


Sujet :

C#

  1. #1
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut CalDAV : Erreur au moment de créer un événement
    Bonjour,

    Je cherche à créer des événements dans un calendrier géré sous Zimbra depuis une application écrite en C#.

    J'utilise pour se faire le protocole CalDAV (RFC 4791).

    Pour le moment, j'arrive sans problème à interroger le serveur pour trouver l'URI du calendrier de l'utilisateur courant, à lister les événements du calendrier pour un intervalle de dates données.

    En revanche, lorsque je tente de créer un événement, ça marche plus : erreur 401.

    Voici l'exemple de la RFC :

    [fixed]
    PUT /home/lisa/calendars/events/qwue23489.ics HTTP/1.1
    If-None-Match: *
    Host: cal.example.com
    Content-Type: text/calendar
    Content-Length: xxxx

    BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//Example Corp.//CalDAV Client//EN
    BEGIN:VEVENT
    UID:20010712T182145Z-123401@example.com
    DTSTAMP:20060712T182145Z
    DTSTART:20060714T170000Z
    DTEND:20060715T040000Z
    SUMMARY:Bastille Day Party
    END:VEVENT
    END:VCALENDAR
    [/fixed]

    Donc moi j'ai un peu adapté, en modifiant notamment l'URI du fichier ICS à créer, de façon à ce qu'il corresponde au même pattern que ceux déjà existants (que je récupère en chargement les événements).

    [fixed]
    PUT /dav/<user>/Calendar/test1.ics HTTP/1.1
    If-None-Match: *
    Host: <host>
    Content-Type: text/calendar
    Content-Length: <length>

    BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//Example Corp.//CalDAV Client//EN
    BEGIN:VEVENT
    UID:20010712T182145Z-123401@example.com
    DTSTAMP:20140712T182145Z
    DTSTART:20140714T170000Z
    DTEND:20140715T040000Z
    SUMMARY:Bastille Day Party
    END:VEVENT
    END:VCALENDAR
    [/fixed]

    Mais l'erreur subsiste.

    Voici mon code :

    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
            public string CreateEvent(CalDAVEvent evt)
            {
                List<KeyValuePair<string, string>> headers = new List<KeyValuePair<string, string>>();
                headers.Add(new KeyValuePair<string, string>("If-None-Match", "*"));
                return SendQuery("PUT", evt.Serialize(), new Uri(string.Format("{0}test{1}.ics", CalendarAddress.ToString(), evt.ETAG)), headers, "text/calendar");
            }
     
            private string SendQuery(string method, string query, Uri address, List<KeyValuePair<string, string>> headers, string contenttype)
            {
                HttpWebRequest hr = HttpWebRequest.Create(address) as HttpWebRequest;
                hr.Credentials = Credentials;
                hr.Method = method;
                hr.Host = address.Host;
                hr.ContentType = contenttype;
                foreach (KeyValuePair<string, string> kvp in headers)
                {
                    hr.Headers.Add(kvp.Key, kvp.Value);
                }
                byte[] bytes = Encoding.UTF8.GetBytes((string)query);
                hr.ContentLength = bytes.Length;
                Stream RequestStream = hr.GetRequestStream();
                RequestStream.Write(bytes, 0, bytes.Length);
                RequestStream.Close();
                HttpWebResponse Response = (HttpWebResponse)hr.GetResponse(); // Ça pète ici
                Stream ResponseStream = Response.GetResponseStream();
     
                byte[] buffer = new byte[4096];
                StringBuilder sb = new StringBuilder();
                int r = 0;
                while ((r = ResponseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    sb.Append(Encoding.UTF8.GetString(buffer, 0, r));
                }
                ResponseStream.Close();
     
                return sb.ToString();
            }

    Pourtant, quand j'appelle SendQuery() pour charger les événements, j'ai pas de souci :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
            public List<CalDAVEvent> GetEventsFromLastModified(DateTime from)
            {
                List<CalDAVEvent> ret = new List<CalDAVEvent>();
     
                string range = string.Format("<C:prop-filter name=\"DTSTAMP\"><C:time-range start=\"{0}\" end=\"{1}\"/></C:prop-filter>", ISO8601DateTime.ToString(from), ISO8601DateTime.ToString(DateTime.Now.AddDays(1)));
                List<KeyValuePair<string, string>> headers = new List<KeyValuePair<string, string>>();
                headers.Add(new KeyValuePair<string, string>("Depth", "1"));
                string res = SendQuery("REPORT", string.Format("<?xml version=\"1.0\" encoding=\"utf-8\" ?><C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\"><D:prop xmlns:D=\"DAV:\"><D:getetag/><C:calendar-data/></D:prop><C:filter><C:comp-filter name=\"VCALENDAR\"><C:comp-filter name=\"VEVENT\">{0}</C:comp-filter></C:comp-filter></C:filter></C:calendar-query>", range), CalendarAddress, headers, "application/xml; charset=\"utf-8\"");
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(res);
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("D", "DAV:");
                nsmgr.AddNamespace("C", "urn:ietf:params:xml:ns:caldav");
                foreach (XmlNode el in doc.SelectNodes("/D:multistatus/D:response/D:propstat/D:prop", nsmgr))
                {
                    ret.Add(new CalDAVEvent(el.SelectSingleNode("C:calendar-data", nsmgr).InnerText, el.SelectSingleNode("D:getetag", nsmgr).InnerText));
                }
                return ret;
            }

    C'est donc bien le PUT ou l'adresse qui lui plaît pas.

    J'ai raté un truc dans la RFC ? Notamment en ce qui concerne l'adresse... L'exemple d'ajout a une adresse complètement différente des autres exemple. Donc pas évident de trouver une logique de nommage.
    Quand j'essaie de faire Calendar/events/test1.ics j'ai doit à un 404, signe que "events" n'existe pas, et que j'ai bel et bien pas le droit de créer test1.ics dans Calendar.

    Si je vire le "If-Not-Match" en header, j'ai toujours l'erreur : d'après la RFC, dans ce cas, je devrais écraser un événement déjà existant sans erreur. Donc c'est pas à cause d'un événement déjà existant...

    If the client intends to create a new
    non-collection resource, such as a new VEVENT, the client SHOULD use
    the HTTP request header "If-None-Match: *" on the PUT request. The
    Request-URI on the PUT request MUST include the target collection,
    where the resource is to be created, plus the name of the resource in
    the last path segment. The "If-None-Match: *" request header ensures
    that the client will not inadvertently overwrite an existing resource
    if the last path segment turned out to already be used.
    J'ai installé sur mon PC le client CalDav "eM Client" et lui il arrive très bien à créer des événements. C'est donc pas une configuration qui bloque sur Zimbra, mais visiblement une subtilité qui m'échappe...
    On ne jouit bien que de ce qu’on partage.

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Bon, visiblement, ça intéresse personne, mais je vais quand même dire ce qui n'allait pas :
    - UID et ETAG doivent être égaux.

    ETAG = le nom du "fichier" ics (toto.ics)
    UID = identifiant de l'événement (toto)

    Dès que les deux diffèrent, sous Zimbra tout du moins, on se tape une erreur 401.
    On ne jouit bien que de ce qu’on partage.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Message d'erreur au moment de traiter le formulaire
    Par leloup84 dans le forum Langage
    Réponses: 1
    Dernier message: 15/03/2006, 13h01
  2. Créer un événement
    Par Blo0d4x3 dans le forum Langage
    Réponses: 9
    Dernier message: 03/03/2006, 16h52
  3. Créer un événement à mon composant
    Par natie_49 dans le forum Composants VCL
    Réponses: 12
    Dernier message: 22/06/2005, 11h01
  4. [SYBASE] erreur au moment de creer une database
    Par arioule dans le forum Sybase
    Réponses: 1
    Dernier message: 01/03/2005, 10h51
  5. Créer des événements
    Par thebeb dans le forum MFC
    Réponses: 8
    Dernier message: 04/02/2005, 16h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo