REST-Service Datenübergabe XML

DrMueller

Erfahrenes Mitglied
Hallo Leute,

ich habe den lustigen Auftrag erhalten, ein kleines Test-Projektes eine REST-Dienstes inkl. Client zu erstellen.
Schlussendlich sollten XML-Daten gespeichert und abgeholt werden.
Vorgängig muss ich leider sagen, dass ich von der Thematik wie so oft sträflich wenig Ahnung habe.

Mein Problem ist, dass ich einen "Bad Request" Fehler erhalte, wenn ich Daten übergeben will.

Mein Interface sieht wie folgt aus:

Code:
    [ServiceContract]
    public interface IRestServiceImpL
    {
        [OperationContract]
        [WebGet(UriTemplate = "/",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Xml)]
        string GetXmlFiles();

        [WebInvoke(Method = "POST",
            ResponseFormat=WebMessageFormat.Xml,
            RequestFormat=WebMessageFormat.Xml,
            BodyStyle=WebMessageBodyStyle.Bare,
            UriTemplate = "/save")]
        bool SaveData(string xml);

        [OperationContract]
        [WebGet(UriTemplate = "/id={id}",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Xml)]
        string GetXmlData(string id);

        [OperationContract]
        [WebGet(UriTemplate = "/test",
            BodyStyle = WebMessageBodyStyle.Wrapped,
            ResponseFormat = WebMessageFormat.Xml)]
        string GetTest();

        [OperationContract]
        [WebInvoke(UriTemplate = "/testSave/{id}",
            Method="POST")]
        bool SaveTest(string id);

        [OperationContract]
        [WebInvoke(UriTemplate = "/leer",
            Method = "POST")]
        string leer();

    }

Soweit mein Code, mit dem ich rum spiele.
Ich verstehe auch die Idee des UriTemplates, damit dynamische Pfade verwendet werden können.
Was ich nicht verstehe ist, wie per WebRequest die Funktion die Daten erhält, wenn sie nicht im UriTemplate gespeichert sind.
Konkret problematisch ist der /save Aufruf, welchem ich eigentlich gerne ein String im XML-Format mitgeben würde.

Per Client sieht dies so aus:

Code:
        private void btnGetXml_Click(object sender, RoutedEventArgs e)
        {
            _wr = WebRequest.Create(@MAIN_URL + "/" + txbXmlId.Text);
            _wr.Method = "GET";

            txbXml.Text = GetResponse();
        }

        private string GetResponse()
        {
            string result = string.Empty;
            using (HttpWebResponse resp = _wr.GetResponse() as HttpWebResponse)
            {
                StreamReader reader =
                    new StreamReader(resp.GetResponseStream());
                result = reader.ReadToEnd();
            }

            return result;
        }

        private void btnSaveXml_Click(object sender, RoutedEventArgs e)
        {
            //string url = String.Format(MAIN_URL + @"/save/id={0}", txbXmlId.Text);
            string url = String.Format(MAIN_URL + @"/save");


            byte[] data = Encoding.UTF8.GetBytes(HttpUtility.UrlEncode(txbXml.Text));

            _wr = WebRequest.Create(url);
            _wr.Method = "POST";
            _wr.ContentType = "text/xml";
            _wr.ContentLength = data.Length;

            using (Stream s = _wr.GetRequestStream())
            {
                s.Write(data, 0, data.Length);
            }

            txbXml.Text = GetResponse();
        }

        private void btnGetTest_Click(object sender, RoutedEventArgs e)
        {
            _wr = WebRequest.Create(@MAIN_URL + "/test");
            _wr.Method = "GET";

            using (HttpWebResponse resp = _wr.GetResponse() as HttpWebResponse)
            {
                StreamReader reader =
                    new StreamReader(resp.GetResponseStream());
                txbXml.Text = reader.ReadToEnd();
            }
        }

        private void btnSaveTest_Click(object sender, RoutedEventArgs e)
        {
            _wr = WebRequest.Create(@MAIN_URL + "/testSave/1");
            _wr.Method = "POST";
            _wr.ContentLength = 0;

            txbXml.Text = GetResponse();
        }

Hier ist btnSaveXml problematisch, z.B. btnSaveTest, wo auch ein POST-Request gemacht wird, klappt ohne Probleme.
Ich habe schon x Encodings, Contenttypes etc. versucht zu übergeben, daher nehme ich eher an, dass es Server-seitig ein Problem ist.

Sehr wahrscheinlich fehlt mir einfach eine Information, aber in all den gefundenen Beispielen, wird nicht viel darüber gesagt.


Ich danke schon im Voraus für alle Ideen

Matthias Müller
 

DrMueller

Erfahrenes Mitglied
Hm die einzige Möglichkeit ,welche ich gefunden habe, ist tatsächlich über Context:

Code:
var ctx = OperationContext.Current.RequestContext.RequestMessage;

Allerdings erscheint mir das eher ein Hack zu sein.
Interessanterweise findet man NICHTS darüber im Internet, entweder es wird alles über die URI gesendet (Was aber bei XML etc. merkwürdi wäre), oder es ist so klar, wie man den Body ausliest, dass es nicht erwähnt werden muss...
 

DrMueller

Erfahrenes Mitglied
Noch ein Update: Gibt wohl zwei Möglichkeiten, entweder per Context oder bei der Methode direkt als Stream, was wohl sauberer ist.