我正在尝试将我的Android设备录制的音频发送到MVC.NET Web Api。我通过传递简单的字符串参数来确认连接。但是,当我尝试传递音频生成的字节数组时,每次都从服务器获取500。我尝试了多种配置,但这是我目前的配置:
public class PostParms
{
public string AudioSource { get; set; }
public string ExtraInfo { get; set; }
}
public class MediaController : ApiController
{
[HttpPost]
public string Post([FromBody]PostParms parms)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(parms.AudioSource);
return "success";
}
}
public class WebServiceTask extends AsyncTask<String, Void, Long>
{
@Override
protected Long doInBackground(String... parms)
{
long totalsize = 0;
String filepath = parms[0];
byte[] fileByte = convertAudioFileToByte(new File(filepath));
//Tried base64 below with Convert.FromBase64 on the C# side
//String bytesstring = Base64.encodeToString(fileByte, Base64.DEFAULT);
String bytesstring = "";
try
{
String t = new String(fileByte,"UTF-8");
bytesstring = t;
} catch (UnsupportedEncodingException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://my.webservice.com:8185/api/media");
//setup for connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(false);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type","application/json");
urlConnection.setRequestProperty("Accept","application/json");
urlConnection.connect();
JSONObject json = new JSONObject();
json.put("AudioSource", bytesstring);
json.put("ExtraInfo", "none");
DataOutputStream output = new DataOutputStream(urlConnection.getOutputStream());
output.writeBytes(URLEncoder.encode(json.toString(),"UTF-8"));
output.flush();
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
urlConnection.disconnect();
}
return totalsize;
}
protected void onPreExecute(){
}
protected void onPostExecute(){
}
private byte[] convertAudioFileToByte(File file) {
byte[] bFile = new byte[(int) file.length()];
try {
// convert file into array of bytes
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return bFile;
}
}
我可以使用.NET应用程序来处理发送音频流的相同API,但不能使用Android。就像我说的,我已经尝试了在互联网上找到的一些配置,包括编码和输出流,但是继续得到500.我需要帮助,因为我不知所措。
提前致谢
答案 0 :(得分:4)
我使用了ByteArrayEntity而不是StringEntity
//ByteArrayEntity
HttpPost request = new HttpPost(getString(R.string.server_url)+ "SendMessage");
ByteArrayEntity be = new ByteArrayEntity(msg);
be.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded"));
request.setEntity(be);
HttpResponse response = client.execute(request);
在服务器端,我使用这个web api代码来获取字节数组
[HttpPost]
public async Task<string> SendMessage()
{
byte[] arrBytes = await Request.Content.ReadAsByteArrayAsync();
return "";
}
希望这有帮助
答案 1 :(得分:1)
我刚刚在Uploading/Downloading Byte Arrays with AngularJS and ASP.NET Web API发布了一个关于Stack Overflow的问题,这个问题与您的问题相关(部分)。您可能希望阅读该帖子以设置我的回复的上下文。它是关于通过Web API发送和接收byte []的。我对该方法有一个问题,但它与JavaScript客户端错误地处理服务器响应有关。
我会对您的服务器端代码进行如下更改,如下所示:
public class PostParms
{
public string ExtraInfo { get; set; }
}
public class MediaController : ApiController
{
[HttpPost]// byte[] is sent in body and parms sent in url
public string Post([FromBody] byte[] audioSource, PostParms parms)
{
byte[] bytes = audioSource;
return "success";
}
}
阅读http://byterot.blogspot.com/2012/04/aspnet-web-api-series-part-5.html
上的帖子使用/添加Byte Rot的Media Formatter异步版本的byte []。
我必须调整格式化程序,如下所示,以获得更新版本的ASP.NET。
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace YOUR_NAMESPACE
{
public class BinaryMediaTypeFormatter : MediaTypeFormatter
{
/****************** Asynchronous Version ************************/
private static Type _supportedType = typeof(byte[]);
private bool _isAsync = true;
public BinaryMediaTypeFormatter() : this(false){
}
public BinaryMediaTypeFormatter(bool isAsync) {
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
IsAsync = isAsync;
}
public bool IsAsync {
get { return _isAsync; }
set { _isAsync = value; }
}
public override bool CanReadType(Type type){
return type == _supportedType;
}
public override bool CanWriteType(Type type){
return type == _supportedType;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream stream,
HttpContent contentHeaders, IFormatterLogger formatterLogger){// Changed to HttpContent
Task<object> readTask = GetReadTask(stream);
if (_isAsync){
readTask.Start();
}
else{
readTask.RunSynchronously();
}
return readTask;
}
private Task<object> GetReadTask(Stream stream){
return new Task<object>(() =>{
var ms = new MemoryStream();
stream.CopyTo(ms);
return ms.ToArray();
});
}
private Task GetWriteTask(Stream stream, byte[] data){
return new Task(() => {
var ms = new MemoryStream(data);
ms.CopyTo(stream);
});
}
public override Task WriteToStreamAsync(Type type, object value, Stream stream,
HttpContent contentHeaders, TransportContext transportContext){ // Changed to HttpContent
if (value == null)
value = new byte[0];
Task writeTask = GetWriteTask(stream, (byte[])value);
if (_isAsync){
writeTask.Start();
}
else{
writeTask.RunSynchronously();
}
return writeTask;
}
}
}
我还必须在配置文件中添加以下行。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// This line added to activate your binary formatter.
config.Formatters.Add(new BinaryMediaTypeFormatter());
/ ***********************************客户代码******** ******** /
您需要使用&#39; Content-Type&#39;:&#39; application / octet-stream&#39;在客户端。
您可以将byte []作为二进制文件发送,但由于我在客户端上使用C#进行编码,所以它已经太长了。
我认为行:output.writeBytes(URLEncoder.encode(json.toString(),&#34; UTF-8&#34;));必须至少改变。
我将查看是否可以找到一些可能相关的C#客户端代码段。
编辑您可能会看一下以下帖子的C#客户端代码。它可以帮助您调整代码以使用我建议的方法。
How to Get byte array properly from an Web Api Method in C#?