tags:

views:

336

answers:

2
+2  Q: 

WCF- Large Data

I have a WCF Web Service with basicHTTPBinding , the server side the transfer mode is streamedRequest as the client will be sending us large file in the form of memory stream.

But on client side when i use transfer mode as streamedRequest its giving me a this errro "The remote server returned an error: (400) Bad Request" And when i look in to trace information , i see this as the error message Exception: There is a problem with the XML that was received from the network. See inner exception for more details.

InnerException: The body of the message cannot be read because it is empty.

I am able to send up to 5MB of data using trasfermode as buffered , but it will effect the performance of my web service in the long run , if there are many clients who are trying to access the service in buffered transfer mode.

SmartConnect.Service1Client Serv = new SmartConnectClient.SmartConnect.Service1Client();
SmartConnect.OrderCertMailResponse OrderCert = new SmartConnectClient.SmartConnect.OrderCertMailResponse();
OrderCert.UserID = "abcd";
OrderCert.Password = "7a80f6623";
OrderCert.SoftwareKey = "90af1";  
string applicationDirectory = @"\\inid\utty\Bran";
byte[] CertMail = File.ReadAllBytes(applicationDirectory + @"\5mb_test.zip");
MemoryStream str = new MemoryStream(CertMail);

//OrderCert.Color = true;
//OrderCert.Duplex = false;        
//OrderCert.FirstClass = true;
//OrderCert.File = str;
//OrderCert.ReturnAddress1 = "Test123";
//OrderCert.ReturnAddress2 = "Test123";
//OrderCert.ReturnAddress3 = "Test123";
//OrderCert.ReturnAddress4 = "Test123";
OrderCert.File = str;

//string OrderNumber = "";
//string Password = OrderCert.Password;
//int ReturnCode = 0;
//string ReturnMessage = "";
//string SoftwareKey = OrderCert.SoftwareKey;
//string UserID = OrderCert.UserID;
//OrderCert.File = str;

MemoryStream FileStr = str;
Serv.OrderCertMail(OrderCert);

// Serv.OrderCertMail(ref  OrderNumber, ref Password, ref ReturnCode, ref ReturnMessage, ref SoftwareKey, ref  UserID, ref FileStr );
lblON.Text = OrderCert.OrderNumber;

Serv.Close();


// My Web Service - Service Contract
[OperationContract]
OrderCertMailResponse OrderCertMail(OrderCertMailResponse OrderCertMail);

[MessageContract]
public class OrderCertMailResponse
{
   string userID = "";
   string password = "";
   string softwareID = "";
   MemoryStream file = null;
   //MemoryStream str = null; 

   [MessageHeader]
   //[DataMember]
   public string UserID
   {
      get { return  userID; }
      set { userID = value; }
   }

   [MessageHeader]
   //[DataMember]
   public string Password
   {
      get { return  password; }
      set { password = value; }
   }

   [MessageHeader]
   //[DataMember]
   public string SoftwareKey
   {
      get { return softwareID; }
      set { softwareID = value; }
   }

   [MessageBodyMember]
   // [DataMember]
   public MemoryStream File
   {
      get { return file; }
      set { file = value; }
   }

   [MessageHeader]
   //[DataMember]
   public string ReturnMessage;

   [MessageHeader]
   //[DataMember]
   public int ReturnCode;

   [MessageHeader]
   public string OrderNumber;
}


[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Service1 : IService1
{
   public OrderCertMailResponse OrderCertMail(OrderCertMailResponse OrderCertMail)
   {
      OrderService CertOrder = new OrderService();
      ClientUserInfo Info = new ClientUserInfo();
      ControlFileInfo Control = new ControlFileInfo();

      //Info.Password = "f2496623";  // hard coded password for development testing purposes
      //Info.SoftwareKey = "6dbb71";       // hard coded  software key this is a developement software key
      //Info.UserName = "sdfs";      // hard coded UserID - for testing
      Info.UserName = OrderCertMail.UserID.ToString();
      Info.Password = OrderCertMail.Password.ToString();
      Info.SoftwareKey = OrderCertMail.SoftwareKey.ToString();

      //Control.ReturnAddress1 = OrderCertMail.ReturnAddress1;
      //Control.ReturnAddress2 = OrderCertMail.ReturnAddress2;
      //Control.ReturnAddress3 = OrderCertMail.ReturnAddress3;
      //Control.ReturnAddress4 = OrderCertMail.ReturnAddress4;
      //Control.CertMailFirstClass = OrderCertMail.FirstClass;
      //Control.CertMailColor = OrderCertMail.Color;
      //Control.CertMailDuplex = OrderCertMail.Duplex;

      //byte[] CertFile = new byte[0];
      //byte[] CertFile = null;

      //string applicationDirectory = @"\\inid\utility\Bryan";
      // byte[] CertMailFile = File.ReadAllBytes(applicationDirectory + @"\3mb_test.zip"); 
      //MemoryStream str = new MemoryStream(CertMailFile);
      OrderCertMailResponseClass OrderCertResponse = CertOrder.OrderCertmail(Info,Control,OrderCertMail.File);
      OrderCertMail.ReturnMessage = OrderCertResponse.ReturnMessage.ToString();
      OrderCertMail.ReturnCode = Convert.ToInt32(OrderCertResponse.ReturnCode.ToString());
      OrderCertMail.OrderNumber = OrderCertResponse.OrderNumber;            

      return OrderCertMail;
  }

Below are my new operation contract which takes only datastream as a parameter

[OperationContract]
SmartStream SendStream(MemoryStream DataStream);

public SmartStream SendStream(MemoryStream DataStream)
{
   OrderService CertOrder = new OrderService();
   ClientUserInfo Info = new ClientUserInfo();
   ControlFileInfo Control = new ControlFileInfo();
   MemoryStream serverStream = null;

   Info.Password = "78f24dsfsdf96623";              
   Info.SoftwareKey = "dfs6dbb71";       
   Info.UserName = "ssfsdf";      

   using (serverStream = new MemoryStream(100))
   {
      int count = 0;
      const int buffLen = 4096;
      byte[] buf = new byte[buffLen];

      while ((count = CertFile.Read(buf, 0, buffLen)) > 0)
      {
          serverStream.Write(buf, 0, count);
      }

      CertFile.Close();
      serverStream.Close();
      return null;
   }

My client method to access

protected void Page_Load(object sender, EventArgs e)
{
    SmartConnect.Service1Client Serv = new 
               SmartConnectClient.SmartConnect.Service1Client();
    string applicationDirectory = @"\\intrepid\utility\Bryan";
    byte[] CertMail = File.ReadAllBytes(applicationDirectory + @"\100mb_test.zip");
    MemoryStream str = new MemoryStream(CertMail);

    SmartConnectClient.SmartConnect.SendStreamRequest request = 
         new SmartConnectClient.SmartConnect.SendStreamRequest();
    SmartConnectClient.SmartConnect.SmartStream  SmartStr = 
         new SmartConnectClient.SmartConnect.SmartStream();
    request.DataStream = str;

    SmartConnectClient.SmartConnect.SendStreamResponse response = Serv.SendStream(request);
 }
+3  A: 

Pinu, I still think you're probably not doing the service contract right for WCF streaming. See the MSDN docs on WCF Streaming - especially this section on restrictions:

Restrictions on Streamed Transfers

Using the streamed transfer mode causes the run time to enforce additional restrictions.

Operations that occur across a streamed transport can have a contract with at most one input or output parameter. That parameter corresponds to the entire body of the message and must be a Message, a derived type of Stream, or an IXmlSerializable implementation. Having a return value for an operation is equivalent to having an output parameter.

From your code posted, I'm still under the impression you're trying to mix both buffered and streamed transfers.

If you want to have real streaming, your service contract must look something like:

[ServiceContract(Namespace=".....")]
interface IUploadFileService
{
   [OperationContract] 
   UploadResponse UploadFile(Stream file);
}

That's about all you can have in your service contract for that service method.

Also have a look at some really good blog posts on streaming here and here.

marc_s
A: 

@Marc - Thank you so much for all the your help. It helped me fix many of the problems of my service.

The web service started working when I ran it on local IIS on my machine , it was throwing all those errors when I was running on the Visual Studio development server. I could not figure why it is so , why it did not run on Visual studio development server.

Pinu