我正在尝试将大型文件从android上传到wcf rest服务。我能够正确上传文件。但我的问题是当从android上传文件到服务器连接失败时,我无法恢复上传过程。再次上传从头开始可以任何人告诉我写wcf休息服务的方式,我可以恢复我的上传过程。
我目前正在使用以下休息服务上传数据:
public string PostImage(Stream stream)
{
try
{
byte[] buff = new byte[50485760];
using (FileStream fs = new FileStream(System.Web.HttpContext.Current.Server.MapPath(@"~/Images/" + "filename"), FileMode.Create))
{
int bytesRead = stream.Read(buff, 0, buff.Length);
while (bytesRead > 0)
{
fs.Write(buff, 0, bytesRead);
bytesRead = stream.Read(buff, 0, buff.Length);
}
}
}
catch (Exception e)
{
}
//Class1 parser = new Class1(stream);
return "Recieved the image on server";
}
如何修改其余服务以提供上传停止文件的工具。如何添加范围和内容范围标头以向客户端提供此信息。 如果有任何恢复上传过程的示例代码,请提供代码。
答案 0 :(得分:1)
我刚刚实现了这样的东西。如果上传失败或只有一半的字节到达主机,你会怎么做?
我们的方法是创建另外两种方法,一种是客户端设备调用以检查先前上载的状态(称为“ GetStatusOfLastUpload(SessionID,DeviceID,FileID)”),另一种称为< strong> ResumeUpload(SessionID,DeviceID,FileID,MD5Hash,Bytes)。
函数 GetStatusOfLastUpload 执行名称所暗示的操作,向主机发送附加请求以检查先前上载的状态(存储在SQL数据库中)。
此过程的关键是使用计算的MD5哈希和字节计数在主机端确定是否已传递完整文件。例如,如果客户端发送1MB,但主机仅获得500KB,并且客户端发送的MD5哈希与主机根据接收的字节计算的MD5不匹配,我们将上载数据记录的状态设置为“Imcomplete” “并存储字节数。因此,当调用 GetStatusOfLastUpload 时,主机返回(如果需要)上次上载为“Imcomplete”并且收到的字节数仅为500KB。
然后,客户端应用程序从 GetStatusOfLastUpload 获取此信息并调用“ ResumeUpload ”,发送完整文件的MD5哈希以及主机所需的剩余字节。接收到主机后,主机再次组合字节并计算MD5哈希值,并将其与客户端发送的值进行比较。如果哈希值匹配,您知道您有一个完整的文件,如果没有,请重复该过程。
这里没有办法包含所有示例代码,但我会说我们的ResumeUpload函数看起来与我们的上传函数相同,但包含一些额外的检查以确保一切正确。 的 _ __ _ __ _ __ _ __ _ __ _ __ _ ___ 强> 修改的 _ __ _ __ < EM> _ __ _ __ _ __ _ __ _ __ _ __ _ _ 强>
我们在客户端使用.NET的东西,但这是一些示例Java代码(更适合Android)我为那些在非Windows设备上开发的人提供了代码。它构造了与WCF主机(也是.NET)交换的消息。
public MsgStruct CallHost(String URL, String Content, byte[] outBytes){
String textValue="";
byte[] inBytes =new byte[] {0};
try {
// Creating a new empty SOAP message object
SOAPMessage reqMsg = MessageFactory.newInstance().createMessage();
// Populating SOAP body
SOAPEnvelope envelope = reqMsg.getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
SOAPBodyElement service = body.addBodyElement(envelope.createName("HostConnect", "", WCFNameSpace)); //good here
SOAPElement paramInMsg = service.addChildElement(envelope.createName("inMsg", "", "")); //good here
//SOAPElement paramBodySection = paramInMsg.addChildElement(envelope.createName("BodySection", "", DataContractNameSpace));
SOAPElement paramTextSection = paramInMsg.addChildElement(envelope.createName("TextSection", "", DataContractNameSpace));
SOAPElement paramBodySection = paramInMsg.addChildElement(envelope.createName("BodySection", "", DataContractNameSpace));
//get the byte array to send and populate the fields
String sOut=org.apache.commons.codec.binary.Base64.encodeBase64String(outBytes);
paramBodySection.addTextNode(sOut); //adding the binary stuff here "AA=="
paramTextSection.addTextNode(Content); //adding the text content here
envelope.removeAttribute("Header");
envelope.setPrefix("s");
envelope.getBody().setPrefix("s");
// Setting SOAPAction header line
MimeHeaders headers = reqMsg.getMimeHeaders();
headers.addHeader("SOAPAction", SoapAction); //good here
headers.setHeader("Content-Type", "text/xml; charset=utf-8"); //good here
headers.setHeader("Host", "Localhost:8085"); //good here
headers.setHeader("Expect", "100-continue");
// Connecting and Calling
SOAPConnection con = SOAPConnectionFactory.newInstance().createConnection();
SOAPMessage resMsg = con.call(reqMsg, URL);
resMsg.saveChanges();
con.close();
//check the host response
if (resMsg != null){
try{
SOAPBody responseBody = resMsg.getSOAPBody();
SOAPBodyElement responseElement0= (SOAPBodyElement)responseBody.getChildElements().next();
SOAPElement responseElement1 = (SOAPElement)responseElement0.getChildElements().next();
SOAPElement TextElement = (SOAPElement)responseElement1.getFirstChild();
SOAPElement bodyElement = (SOAPElement)responseElement1.getLastChild();
Node nodeBody = (Node)bodyElement;
inBytes = getBytesFromDoc(nodeBody);
textValue = TextElement.getTextContent();
}catch (SOAPException se){
String smessage = se.getMessage();
}
return new MsgStruct(textValue,inBytes);
//no response from host
}else{
Debug.println("error","Error- nothign found");
return null;
}
} catch (Exception e) {
Debug.println("error",e.getMessage());
return null;
}
}
在主机方面,要分享的代码太多,但概念在上面的帖子中。需要记住的是,WCF(几乎)始终是客户端请求/主机响应方案,因此客户端设备需要启动所有内容,包括检查上次上载是否成功。按照我的建议去做?
这可能是您的良好信息来源:http://fszlin.dymetis.com/post/2010/05/10/Comsuming-WCF-Services-With-Android.aspx