Как отправить приведенный к объекту System.IO.Stream, используя HTTP в WCF? - PullRequest
0 голосов
/ 29 марта 2011

У меня есть очень простая программа WCF, в которой у меня простой хост и клиент, работающий на одном компьютере. Существует единственный метод, который возвращает System.IO.Stream, который на самом деле является сериализованной формой простой строки. (Это может быть любое количество типов данных, но пока давайте воспримем это как строку).

Ниже приведен код, который я использую, если вы хотите взглянуть. SerializeData () и DeserializeData () являются методами, используемыми для этого, и отлично работают.

Служба хоста: </p> <pre><code>namespace HelloWCF1 { [ServiceContract(Namespace = "http://My.WCF.Samples")] public interface IService1 { [OperationContract] Stream GetString(); } public class Service1 : IService1 { //Simple String public Stream GetString() { string str = "ABC"; Stream ms = new MemoryStream(); SerializeData<string>(str, ms); return ms; } /// <summary> /// Serialize an object of the type T to a Stream /// </summary> /// <typeparam name="T"></typeparam> /// <param name="objectToSerialize"></param> /// <param name="str"></param> public void SerializeData<T>(T objectToSerialize, Stream str) { BinaryFormatter bf = new BinaryFormatter(); try { bf.Serialize(str, objectToSerialize); str.Position = 0; } catch (Exception) { } } /// <summary> /// Deserialize a Stream /// </summary> /// <param name="dataToDeserialize"></param> /// <returns></returns> public object DeserializeData(Stream dataToDeserialize) { BinaryFormatter bf = new BinaryFormatter(); object ret = null; try { ret = bf.Deserialize(dataToDeserialize); } catch (Exception) { } return ret; } } class Program { static void Main(string[] args) { Uri baseAddr = new Uri("http://localhost:8000/WCFSampleService"); //ServiceHost is created by defining Service Type and Base Address using (ServiceHost svcHost = new ServiceHost(typeof(Service1), baseAddr)) { //Trace message for service start Console.WriteLine("Service Starting..."); //Adding an end point svcHost.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "HelloWCF"); //Open service host svcHost.Open(); Console.WriteLine("Press [Enter] to terminate."); Console.ReadLine(); //Close service host svcHost.Close(); } } }

}

Клиентская программа:

namespace Client { [ServiceContract(Namespace = "http://My.WCF.Samples")] public interface IService1 { [OperationContract] Stream GetString(); }</p> <pre><code>public partial class Form1 : Form { public Form1() { InitializeComponent(); } private IService1 proxy = null; private Stream memStr = new MemoryStream(); private void button1_Click(object sender, EventArgs e) { //Create end point EndpointAddress epAddr = new EndpointAddress("http://localhost:8000/WCFSampleService/HelloWCF"); //Create proxy proxy = ChannelFactory<IService1>.CreateChannel(new BasicHttpBinding(), epAddr); //WCF Service Method is called to aquire the stream try { memStr = proxy.GetString(); string str = (string)DeserializeData(memStr); MessageBox.Show(str); } catch (CommunicationException commEx) { MessageBox.Show("Service Call Failed:" + commEx.Message); } } /// <summary> /// Serialize an object of the type T to a Stream /// </summary> /// <typeparam name="T"></typeparam> /// <param name="objectToSerialize"></param> /// <param name="str"></param> public static void SerializeData<T>(T objectToSerialize, Stream str) { BinaryFormatter bf = new BinaryFormatter(); try { bf.Serialize(str, objectToSerialize); str.Position = 0; } catch (Exception) { } } /// <summary> /// Deserialize a Stream /// </summary> /// <param name="dataToDeserialize"></param> /// <returns></returns> public static object DeserializeData(Stream dataToDeserialize) { BinaryFormatter bf = new BinaryFormatter(); object ret = null; try { ret = bf.Deserialize(dataToDeserialize); } catch (Exception) { } return ret; } }

}

Теперь это работает отлично. Он сериализует строку в поток и отправляет с использованием HTTP вполне нормально. Тем не менее, мне нужно преобразовать приведение этого потока в объект перед отправкой. Проще говоря, мне нужно, чтобы метод GetString () выглядел так:

public object GetString() { string str = "ABC";</p> <pre><code> Stream ms = new MemoryStream(); SerializeData<string>(str, ms); return (object)ms;

}

Однако, когда я делаю это внутри события Button1_Click, в строке ***memStr = proxy.GetString();*** я получаю CommunicationException. Я работаю в японской ОС, поэтому сообщение об исключении, которое я получаю, написано на японском языке, поэтому я постараюсь перевести на английский как можно лучше. Простите, если не очень понятно.

***Error occured in the reception of HTTP response concerning [url]http://localhost:8000/WCFSampleService/HelloWCF[/url]. Cause of the error could be Service End Point binding is not using an HTTP protocol. Or as a different cause, it is also possible that HTTP request context is suspended according to the server (as in the case of server being shut down). Please refer the server log for more details.***

В чем именно проблема и как я могу заставить программу работать так, как я хочу? В нем говорится, чтобы посмотреть файлы журналов, но где я могу их найти?

Заранее спасибо!

1 Ответ

0 голосов
/ 29 марта 2011

Не лучше ли вернуть строку?Конечно, строка, возвращаемая как поток через привязку Http, будет закодирована в Base64, что обычно удваивает размер возвращаемых данных!

Возможно, вы могли бы рассмотреть TcpBinding в качестве альтернативы.

...