C#& Java - 将文件从Android上传到WCF

时间:2016-03-23 12:56:45

标签: java c# android wcf

我尝试将文件从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()
            };
        }
    }

2 个答案:

答案 0 :(得分:1)

在Android / WCF REST组合中没有尝试过这个,我在你的代码中注意到了一些事情。

首先,您在操作合同中说您的REST方法需要JSON并返回JSON。但Android代码不是发送 JSON。它只是按原样发送输入文件的内容。这是我认为不正确的一件事。如果您想以与浏览器表单相同的方式将某些内容上传到网站,那么您使用的代码就很好。但这与使用REST请求不同。

另一件事是:您的REST方法不会采用Stream参数,因为它不会获得流。

我要做的第一件事是设计REST POST方法,以便它接受这样的JSON对象:

{ imageBytes = "0dac...." }

imageBytes是要保存的图像的base64编码版本(例如:PNG文件base64编码的字节)。然后,您可以使用其他方法来测试它是否运作良好。

然后我更改Android代码以便

  1. 读取要发送的文件,并创建该文件的base64编码版本。
  2. 如上所述,将该base64编码版本发送到JSON对象中。
  3. 然后事情应该成功。正如我上面所说,我之前没有在那个组合中做过这个,所以我没有给你的示例代码。

答案 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>