我尝试将文件从Android上传到WCF服务。 我已经达到触发WCF上的方法并保存文件的程度。 在尝试打开文件时,我收到一条错误消息,指出它已损坏。
我认为错误可能在HttpFileUpload类中,其中一个静态变量不正确,或者我发送的内容不是流,而是服务转换为流的其他内容因此腐败。
使用的代码可以在下面找到。
Android代码:
HttpFileUpload类:
找到HttpFileUpload代码here:
private static final String LINE_FEED = "\r\n";
private String charset = "UTF-8";
public HttpFileUpload(String requestURL) throws IOException {
// creates a unique boundary based on time stamp
boundary = "===" + System.currentTimeMillis() + "===";
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
httpConn.setRequestProperty("Host", "x.x.x.x:x");
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
}
public void addFilePart(String fieldName, File uploadFile) throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED); // form-data
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED);
writer.flush();
}
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned status: " + status);
}
return response;
}
服务连接器类
String urlTo = LOCATION + "/UploadUserProfilePicture";
File file = new File(imagePath);
try {
HttpFileUpload httpFileUpload = new HttpFileUpload(urlTo);
httpFileUpload.addFilePart("image", file);
List<String> responses = httpFileUpload.finish();
for (String line : responses) {
System.out.println(line);
}
return responses.get(0);
} catch (Exception ex) {
return ex.toString();
}
WCF服务代码
IMobileService:
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
Result UploadUserProfilePicture(Stream image);
MobileService:
FileType fileType = bytes.GetFileType()
是一个返回扩展名的插件。目前,插件不起作用,因为fileType始终为null。
但是,图像变量可能已经损坏。
public Result UploadUserProfilePicture(Stream image)
{
try
{
var bytes = CommonMethods.ReadToEnd(image);
FileType fileType = bytes.GetFileType();
Guid guid = Guid.NewGuid();
string imageName = guid.ToString() + "." + fileType.Extension;
var buf = new byte[1024];
var path = Path.Combine(@"C:\fileUpload\" + imageName); //" ocd
File.WriteAllBytes(path, bytes);
return new Result
{
Success = true,
Message = imageName
};
}
catch(Exception ex)
{
return new Result
{
Success = false,
Message = ex.ToString()
};
}
}
答案 0 :(得分:1)
在Android / WCF REST组合中没有尝试过这个,我在你的代码中注意到了一些事情。
首先,您在操作合同中说您的REST方法需要JSON并返回JSON。但Android代码不是发送 JSON。它只是按原样发送输入文件的内容。这是我认为不正确的一件事。如果您想以与浏览器表单相同的方式将某些内容上传到网站,那么您使用的代码就很好。但这与使用REST请求不同。
另一件事是:您的REST方法不会采用Stream
参数,因为它不会获得流。
我要做的第一件事是设计REST POST方法,以便它接受这样的JSON对象:
{ imageBytes = "0dac...." }
,imageBytes
是要保存的图像的base64编码版本(例如:PNG文件base64编码的字节)。然后,您可以使用其他方法来测试它是否运作良好。
然后我更改Android代码以便
然后事情应该成功。正如我上面所说,我之前没有在那个组合中做过这个,所以我没有给你的示例代码。
答案 1 :(得分:0)
感谢Thorsten带领我朝着正确的方向前进。 这是一个编码示例:
Android代码:
ImageUploading活动:
File initialFile = new File(imagePath);
byte[] bytes = FileUtils.readFileToByteArray(initialFile);
final String base64 = android.util.Base64.encodeToString(bytes, android.util.Base64.DEFAULT);
Thread uploadFileThread = new Thread(new Runnable() {
@Override
public void run() {
FileToUpload fileToUpload = new FileToUpload();
fileToUpload.setFile(base64);
String[] result = ServiceConnector.UploadUserProfilePicture(fileToUpload);
}
});
ServiceConnector类:
public static String[] UploadUserProfilePicture(FileToUpload fileToUpload) {
StringBuilder sb = new StringBuilder();
String result[] = {"false", "Something went wrong"};
HttpURLConnection urlConnection = null;
try {
URL url;
DataOutputStream printout;
DataInputStream input;
url = new URL(LOCATION + "/UploadUserProfilePicture");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Host", "x.x.x.x:xxxx");
urlConnection.setConnectTimeout(1*1000*3600);
urlConnection.setReadTimeout(1*1000*3600);
urlConnection.connect();
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
// Send POST output.
printout = new DataOutputStream(urlConnection.getOutputStream());
byte[] extraInfo = gson.toJson(fileToUpload).getBytes("UTF-8");
printout.write(extraInfo);
printout.flush();
printout.close();
int HttpResult = urlConnection.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
result = CommonMethods.parseJsonToArray(sb.toString());
} else {
System.out.println("*** RESPONSE MESSAGE ***");
System.out.println(urlConnection.getResponseMessage());
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
return null;
}
C#服务代码:
服务:
public Result UploadUserProfilePicture(FileToUpload image)
{
try
{
byte[] bytes = Convert.FromBase64String(image.File);
FileType fileType = bytes.GetFileType();
Guid guid = Guid.NewGuid();
string imageName = guid.ToString() + "." + fileType.Extension;
var path = Path.Combine(@"C:\UploadedImages\" + imageName);
File.WriteAllBytes(path, bytes);
return new Result
{
Success = true,
Message = imageName
};
}
catch(Exception ex)
{
return new Result
{
Success = false,
Message = ex.ToString()
};
}
}
IService:
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
Result UploadUserProfilePicture(FileToUpload image);
Web.Config on Service:
没有以下内容我收到了400 Bad request错误。
<bindings>
<webHttpBinding>
<binding
name="binding"
openTimeout="00:10:00" closeTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647" transferMode="Streamed">
<readerQuotas maxDepth="250000000" maxStringContentLength="250000000" maxArrayLength="250000000" maxBytesPerRead="250000000" maxNameTableCharCount="250000000"/>
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>