Vorgehensweise: Erstellen eines Diensts, der beliebige Daten mithilfe des WCF REST-Programmiermodells akzeptiert

Unter bestimmten Voraussetzungen benötigen Entwickler umfassende Steuerungsmöglichkeiten für die Rückgabe der Daten durch einen Dienstvorgang. Dies ist der Fall, wenn ein Dienstvorgang Daten in einem Format zurückgeben muss, das von WCF nicht unterstützt wird. In diesem Thema wird die Verwendung des WCF REST-Programmiermodells zum Erstellen eines Diensts erläutert, der beliebige Daten empfängt.

So implementieren Sie den Dienstvertrag

  1. Definieren Sie den Dienstvertrag. Der Vorgang, der die beliebigen Daten empfängt, muss über einen Parameter des Typs Stream verfügen. Außerdem muss es sich bei diesem Parameter um den einzigen Parameter handeln, der im Text der Anforderung übergeben wird. Der in diesem Beispiel beschriebene Vorgang nimmt auch einen Dateinamenparameter an. Dieser Parameter wird innerhalb der URL der Anforderung übergeben. Geben Sie zum Festlegen, dass ein Parameter innerhalb der URL übergeben wird, im UriTemplate eine WebInvokeAttribute an. In diesem Fall endet der zum Aufrufen dieser Methode verwendete URI in „UploadFile/Some-Filename“. Der Teil „{filename}“ der URI-Vorlage gibt an, dass der Dateinamensparameter für den Vorgang innerhalb des URI übergeben wird, der zum Aufrufen des Vorgangs verwendet wird.

     [ServiceContract]  
    public interface IReceiveData  
    {  
        [WebInvoke(UriTemplate = "UploadFile/{fileName}")]  
        void UploadFile(string fileName, Stream fileContents);  
    }  
    
  2. Implementieren Sie den Dienstvertrag. Der Vertrag verfügt über nur eine Methode (UploadFile), die in einem Stream eine Datei mit beliebigen Daten empfängt. Der Vorgang liest den Stream, erfasst die Menge der gelesenen Bytes und zeigt anschließend den Dateinamen und die Menge der gelesenen Bytes an.

    public class RawDataService : IReceiveData  
    {  
        public void UploadFile(string fileName, Stream fileContents)  
        {  
            byte[] buffer = new byte[10000];  
            int bytesRead, totalBytesRead = 0;  
            do  
            {  
                bytesRead = fileContents.Read(buffer, 0, buffer.Length);  
                totalBytesRead += bytesRead;  
            } while (bytesRead > 0);  
            Console.WriteLine("Service: Received file {0} with {1} bytes", fileName, totalBytesRead);  
        }  
    }  
    

So hosten Sie den Dienst

  1. Erstellen Sie eine Konsolenanwendung, um den Dienst zu hosten.

    class Program  
    {  
       static void Main(string[] args)  
       {  
       }  
    }  
    
  2. Erstellen Sie eine Variable, um die Basisadresse für den Dienst innerhalb der Main-Methode zu speichern.

    string baseAddress = "http://" + Environment.MachineName + ":8000/Service";  
    
  3. Erstellen Sie eine ServiceHost-Instanz für den Dienst, um die Dienstklasse und die Basisadresse anzugeben.

    ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));  
    
  4. Fügen Sie einen Endpunkt hinzu, durch den der Vertrag, die WebHttpBinding sowie das WebHttpBehavior angegeben werden.

    host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());  
    
  5. Öffnen des Diensthosts Der Dienst ist nun zum Empfangen von Anforderungen bereit.

    host.Open();  
    Console.WriteLine("Host opened");  
    

So rufen Sie den Dienst programmgesteuert auf

  1. Erstellen Sie eine HttpWebRequest mit dem URI, mit dem der Dienst aufgerufen wird. In diesem Code wird die Basisadresse mit "/UploadFile/Text" kombiniert. Der "UploadFile"-Teil des URI gibt den aufzurufenden Vorgang an. Der "Test.txt"-Teil des URI gibt den Dateinamenparameter an, der an den UploadFile-Vorgang übergeben werden soll. Beide Elemente werden der UriTemplate zugeordnet, die auf den Vorgangsvertrag angewendet wurde.

    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");  
    
  2. Legen Sie die Method-Eigenschaft der HttpWebRequest auf POST und die ContentType-Eigenschaft auf "text/plain" fest. Dadurch wird dem Dienst mitgeteilt, dass der Code Daten sendet und diese Daten im Nur-Text-Format vorliegen.

    req.Method = "POST";  
    req.ContentType = "text/plain";  
    
  3. Rufen Sie GetRequestStream auf, um den Anforderungsstream abzurufen, erstellen Sie die zu sendenden Daten, schreiben Sie die Daten in den Anforderungsstream, und schließen Sie anschließend den Stream.

    Stream reqStream = req.GetRequestStream();  
    byte[] fileToSend = new byte[12345];  
    for (int i = 0; i < fileToSend.Length; i++)  
       {  
           fileToSend[i] = (byte)('a' + (i % 26));  
       }  
    reqStream.Write(fileToSend, 0, fileToSend.Length);  
    reqStream.Close();  
    
  4. Rufen Sie die Antwort des Diensts ab, indem Sie GetResponse aufrufen, und zeigen Sie die Antwortdaten an die Konsole an.

    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();  
    Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);  
    
  5. Schließen Sie den Diensthost.

    host.Close();  
    

Beispiel

Im Folgenden finden Sie eine vollständige Liste des Codes für dieses Beispiel:

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.ServiceModel;  
using System.ServiceModel.Web;  
using System.ServiceModel.Description;  
using System.IO;  
using System.Net;  
  
namespace ReceiveRawData  
{  
    [ServiceContract]  
    public interface IReceiveData  
    {  
        [WebInvoke(UriTemplate = "UploadFile/{fileName}")]  
        void UploadFile(string fileName, Stream fileContents);  
    }  
    public class RawDataService : IReceiveData  
    {  
        public void UploadFile(string fileName, Stream fileContents)  
        {  
            byte[] buffer = new byte[10000];  
            int bytesRead, totalBytesRead = 0;  
            do  
            {  
                bytesRead = fileContents.Read(buffer, 0, buffer.Length);  
                totalBytesRead += bytesRead;  
            } while (bytesRead > 0);  
            Console.WriteLine("Service: Received file {0} with {1} bytes", fileName, totalBytesRead);  
        }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";  
            ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));  
            host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());  
            host.Open();  
            Console.WriteLine("Host opened");  
  
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");  
            req.Method = "POST";  
            req.ContentType = "text/plain";  
            Stream reqStream = req.GetRequestStream();  
            byte[] fileToSend = new byte[12345];  
            for (int i = 0; i < fileToSend.Length; i++)  
            {  
                fileToSend[i] = (byte)('a' + (i % 26));  
            }  
            reqStream.Write(fileToSend, 0, fileToSend.Length);  
            reqStream.Close();  
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();  
            Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);  
            host.Close();  
  
        }  
    }  
}  

Kompilieren des Codes

  • Verweisen Sie beim Kompilieren des Codes auf "System.ServiceModel.dll" und "System.ServiceModel.Web.dll".

Siehe auch