WCF-大数据

时间:2010-03-17 13:35:55

标签: wcf

我有一个带有basicHTTPBinding的WCF Web服务,服务器端传输模式是streamedRequest,因为客户端将以内存流的形式向我们发送大文件。

但是在客户端,当我使用传输模式作为streamedRequest它给我一个这个错误 “远程服务器返回错误:(400)错误请求” 当我查看跟踪信息时,我将此视为错误消息 例外:从网络收到的XML存在问题。有关详细信息,请参阅内部异常。

InnerException:无法读取消息正文,因为它是空的。

我可以使用trasfermode作为缓冲来发送最多5MB的数据,但如果有许多客户试图以缓冲传输模式访问服务,那么从长远来看它会影响我的Web服务的性能。

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;
  }

以下是我的新操作合约,它只将datastream作为参数

[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;
   }

我的客户端访问方法

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);
 }

2 个答案:

答案 0 :(得分:3)

Pinu,我仍然认为你可能没有为WCF流媒体做正确的服务合同。请参阅MSDN docs on WCF Streaming - 特别是有关限制的此部分:

  

流式传输的限制

     

使用流式传输模式   导致运行时间强制执行   其他限制。

     

跨越的操作   流式运输可以签订合同   最多只有一个输入或输出   参数。该参数对应   对整个信息和   必须是Message,派生类型   流,或IXmlSerializable   实施。有一个返回值   对于一个操作相当于   有一个输出参数。

从您发布的代码中,我仍然认为您正试图混合缓冲和流式传输。

如果您想拥有真正的流式传输,您的服务合同必须类似于:

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

这就是您在该服务方法的服务合同中所拥有的一切。

另请查看有关流媒体herehere的一些非常好的博客文章。

答案 1 :(得分:1)

@Marc - 非常感谢你的帮助。它帮助我修复了我服务的许多问题。

当我在我的机器上的本地IIS上运行时,Web服务开始工作,当我在Visual Studio开发服务器上运行时,它抛出了所有这些错误。我无法理解为什么会这样,为什么它不能在Visual Studio开发服务器上运行。