Send image to WebApi service - c#

I'm making a project on Windows Phone where user can take a photo, save it on phone and next upload on my server. So there are two projects, WP8.1 and ASP.NET WEB API.
Currently I don't know how to upload photo to my server(from phone), I even don't know how to catch it in API. What's the best way to make it?
Here is my method to show on the screen(phone), picture which was taken by user.
private async void LoadCapturedphoto(string filename)
{
//load saved image
StorageFolder pictureLibrary = KnownFolders.SavedPictures;
StorageFile savedPicture = await pictureLibrary.GetFileAsync(filename);
ImageProperties imgProp = await savedPicture.Properties.GetImagePropertiesAsync();
var savedPictureStream = await savedPicture.OpenAsync(FileAccessMode.Read);
//set image properties and show the taken photo
bitmap = new WriteableBitmap((int)imgProp.Width, (int)imgProp.Height);
await bitmap.SetSourceAsync(savedPictureStream);
takenImage.Source = bitmap;
takenImage.Visibility = Visibility.Visible;
}
I think that I should convert WriteableBitmap to Byte[], send these Byte[] by API to server and on server convert Byte[] to JPG/PNG/etc.
private byte[] ConvertBitmapToByteArray(WriteableBitmap bitmap)
{
WriteableBitmap bmp = bitmap;
using (Stream stream = bmp.PixelBuffer.AsStream())
{
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
Any ideas? Do you think it's good idea to make it like that? WriteableBitmap -> Byte[] and next on server Byte[] -> JPG/PNG etc. Is it even possible?
If it can be done much more easier please write some samples.
it's my method for calling api methods
public string apiCommand(string api, string json)
{
using (var httpClient = new HttpClient())
{
HttpContent content = new StringContent(json, Encoding.UTF8);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = httpClient.PostAsync(Variables.apiURL + api, content).Result;
response.EnsureSuccessStatusCode();
Task<string> responseBody = response.Content.ReadAsStringAsync();
//var msg = new MessageDialog(responseBody.Result.ToString());
if (response.StatusCode.ToString() != "OK")
{
return "ERROR: " + response.StatusCode.ToString();
}
else
{
return "SUCCES: " + responseBody.Result.ToString();
}
}
}

You need to use multipart/form-data request to the server. You can send the json to the web api using payload field (another alternative is send every field separately, but you need reflection to do that.)
This maybe can help you:
public string UploadUserPictureApiCommand(string api, string json, byte[] picture)
{
using (var httpClient = new HttpClient())
{
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent(json), "payload");
form.Add(new ByteArrayContent(picture, 0, picture.Count()), "user_picture", "user_picture.jpg");
HttpResponseMessage response = await httpClient.PostAsync(api, form);
response.EnsureSuccessStatusCode();
Task<string> responseBody = response.Content.ReadAsStringAsync();
if (response.StatusCode.ToString() != "OK")
{
return "ERROR: " + response.StatusCode.ToString();
}
else
{
return "SUCCES: " + responseBody.Result.ToString();
}
}
}

I handle image and word files in my project by this way, hope it helps.
1) Server side, I have a generic api method to process Json requests.
[HttpPost]
public HttpResponseMessage ProcessRequest([FromBody] string sJsonRequest)
{
ResponseMsg rspMsg = null;
RequestMsg oRequestMsg = null;
string sDeteializeMsg = "";
try
{
string sUnescapeJsonData = System.Uri.UnescapeDataString(sJsonRequest);
sJsonRequest = sUnescapeJsonData;
oRequestMsg = (RequestMsg)JsonHelper.Deserialize(typeof(RequestMsg), sJsonRequest);
}
catch (Exception ex)
{
...
}
if (oRequestMsg == null)
{
return AppHelper.GetUTF8PlainTextHttpResponse(#"Invalid request message.");
}
rspMsg = new ResponseMsg(oRequestMsg);
string sJsonRet = "";
try
{
if(oRequestMsg.RequestType==SavingFile)
{
byte[] bytes = System.Convert.FromBase64String(oRequestMsg.Base64Data);
System.IO.File.WriteAllBytes(sFileName, bytes);
....
}
//update rspMsg ....
}
catch (Exception ex)
{
...
}
finally
{
sJsonRet = JsonHelper.Serialize(rspMsg);
}
return AppHelper.GetUTF8PlainTextHttpResponse(sJsonRet);
}
Client side,
1) call through .net code, I use system.Net.webclient,
system.Net.webclient cli=new system.Net.webclient();
cli.Credentials = Credentials;
cli.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
//http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx
sJsonRequest = "=" + EscapeDataStringBig(sJsonRequest);
response = cli.UploadString(sRemoteUrl, "POST", sJsonRequest);
ResponseMsg rsp = (ResponseMsg)JsonHelper.Deserialize(typeof(ResponseMsg), response);
return rsp;
2) call it through JavaScript, usually I will create a method in website controller and forward the json request to the method defined as above. if your javascript code and api code share same json objects, it is quite easy.
2.1) web site controller code,
[HttpPost]
public ActionResult AjaxRequest(int nPostType = -1, string sJsonObject = "")
{
try
{
WebModelAjaxRequestTypes nReqType = (WebModelAjaxRequestTypes)nPostType;
bool bIsBase64Data = IsBase64Request(nReqType);
string sJsonRet = "";
if (!bIsBase64Data)
{
....
}
else
{
//base64 content requests
string sBase64Data = sJsonObject;
//put the string into a json request and send it to api call. and get the return => sJsonRet
}
return Content(sJsonRet); }
catch (Exception ex)
{
....
}
}
2.2) JavaScript ajax call sample code:
var type = "POST";
var sContentType = "";
var sData = ""
if (bIsBase64) {
//sJsonParas is base64 string. don't use encodeURI to encode it.!!!
sContentType = 'application/json; charset=utf-8';
sData = '{ "nPostType" :' + nPostType.toString() + ',"sJsonObject" : "' + sJsonParas + '" }';
}
else {
sContentType = "application/x-www-form-urlencoded; charset=UTF-8";
sData = "nPostType=" + nPostType.toString() + "&sJsonObject=" + encodeURIComponent(sJsonParas);
}
jQuery.ajax({
url: sUrl,
type: type,
data: sData,
contentType: sContentType,
success: function (result) {
....
},
error: function (jqXHR, textStatus, errorThrown) {
....
},
complete: function (jqXHR, textStatus) {
....
} //end complete
});

Related

How to download the file using ASP.NET MVC Rest API call and jQuery Ajax

I am using ASP.NET MVC calling REST API to download the file (any type). I am not sure how do i show in browser download the file directly.
The file might be any format either pdf/image/excel/word/ etc.
Here is my code from jQuery, controller and REST API call.
Please help me how do I send back file data from REST API --> controller --> jQuery?
jQuery Ajax Call. This is onclick event on a table
//JQuery Ajax call to 'GetDocument'
$("#DivAttachmentDetails td ").click(function () {
var DocumentumId = $('#hdnDocumentumId').val();
$.ajax({
type: 'POST',
url: getExactPath('/Supplier/GetDocument'),
data: {
documetObj: DocumentumId
},
dataType: 'json',
async: false,
success: function (jsonData) {
//alert('Hello');
},
error: function () {
alert("Unable to fetch the Document.");
}
});
});
Controller method called from jQuery:
//Method in the Controller called from jQuery Ajax.
public JsonResult GetDocument(string documetObj)
{
DocumentumUtil dUtil = new DocumentumUtil();
String dId;String fileName;String fileExt;String doc = "";
String applicationType = "";
String[] docum;
docum = documetObj.Split(':');
dId = docum[0];
fileName = docum[1].Substring(0, docum[1].LastIndexOf('.'));
fileExt = docum[2];
try
{
String contenType = dUtil.getFileContentType(dId); // Fetch the file content type based on DocumentumId
doc = dUtil.getDocument(dId, fileName, contenType);
}
catch(System.Exception ex) {}
return this.Json("", JsonRequestBehavior.AllowGet);
}
This the REST API call:
// This is the method i am calling from Controller -GetDocument()
public String getDocument(String documentId, String fileName, String contenType)
{
_httpClient = new HttpClient();
D2Document newDocument = new D2Document();
newDocument.SetPropertyValue("object_name", fileName);
newDocument.SetPropertyValue("a_content_type", contenType);
String documentURL = ConfigurationManager.AppSettings["DOCUMENTUM_URL"] + "objects/"+ documentId + "/content-media?format=" + contenType + "&modifier=&page=0";
JSON_GENERIC_MEDIA_TYPE = new MediaTypeWithQualityHeaderValue("application/json");
JSON_VND_MEDIA_TYPE = new MediaTypeWithQualityHeaderValue("application/vnd.emc.documentum+json");
try
{
using (var multiPartStream = new MultipartFormDataContent())
{
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + encoded);
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", username, password)));
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
using (HttpResponseMessage response = _httpClient.GetAsync(documentURL).Result)
{
if (response != null)
{
var responsestream = response.Content;
}
}
}
}
}
How do I convert the content to stream/bytes?
Here is the code i have converted to file stream.
using (HttpResponseMessage response = _httpClient.GetAsync(documentURL).Result)
{
if (response != null)
{
HttpContent content = response.Content;
//Get the actual content stream
Stream contentStream = content.ReadAsStreamAsyn().Result;
//copy the stream to File Stream. "file" is the variable have the physical path location.
contentStream.CopyTo(file);
}
}

Ajax call web API successful but C# call web API 404 not found

I have these web API methods:
[System.Web.Http.RoutePrefix("api/PurchaseOrder")]
public class PurchaseOrderController : ApiController
{
private static ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[System.Web.Http.Route("PagingCriticalPart")]
[System.Web.Http.HttpPost]
public JsonResult PagingCriticalPart([FromBody] Helper.DataTablesBase model)
{
logger.Info("PagingCriticalPart");
JsonResult jsonResult = new JsonResult();
try
{
if (model == null) { logger.Info("model is null."); }
int filteredResultsCount;
int totalResultsCount;
var res = BLL.PurchaseOrderHandler.PagingCriticalPart(model, out filteredResultsCount, out totalResultsCount);
var result = new List<Models.T_CT2_CriticalPart>(res.Count);
foreach (var s in res)
{
// simple remapping adding extra info to found dataset
result.Add(new Models.T_CT2_CriticalPart
{
active = s.active,
createBy = s.createBy,
createdDate = s.createdDate,
id = s.id,
modifiedBy = s.modifiedBy,
modifiedDate = s.modifiedDate,
partDescription = s.partDescription,
partNumber = s.partNumber
});
};
jsonResult.Data = new
{
draw = model.draw,
recordsTotal = totalResultsCount,
recordsFiltered = filteredResultsCount,
data = result
};
return jsonResult;
}
catch (Exception exception)
{
logger.Error("PagingCriticalPart", exception);
string exceptionMessage = ((string.IsNullOrEmpty(exception.Message)) ? "" : Environment.NewLine + Environment.NewLine + exception.Message);
string innerExceptionMessage = ((exception.InnerException == null) ? "" : ((string.IsNullOrEmpty(exception.InnerException.Message)) ? "" : Environment.NewLine + Environment.NewLine + exception.InnerException.Message));
jsonResult.Data = new
{
draw = model.draw,
recordsTotal = 0,
recordsFiltered = 0,
data = new { },
error = exception.Message
};
return jsonResult;
}
}
[System.Web.Http.Route("UploadRawMaterialData")]
[System.Web.Http.HttpPost]
public JsonResult UploadRawMaterialData(string rawMaterialSupplierData)
{
JsonResult jsonResult = new JsonResult();
jsonResult.Data = new
{
uploadSuccess = true
};
return jsonResult;
}
}
When use ajax to call PagingCriticalPart, no issue.
"ajax": {
url: 'http://localhost/ControlTower2WebAPI/api/PurchaseOrder/PagingCriticalPart',
type: 'POST',
contentType: "application/json",
data: function (data) {
//debugger;
var model = {
draw: data.draw,
start: data.start,
length: data.length,
columns: data.columns,
search: data.search,
order: data.order
};
return JSON.stringify(model);
},
failure: function (result) {
debugger;
alert("Error occurred while trying to get data from server: " + result.sEcho);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
debugger;
alert("Error occurred while trying to get data from server!");
},
dataSrc: function (json) {
//debugger;
for (key in json.Data) { json[key] = json.Data[key]; }
delete json['Data'];
return json.data;
}
}
But when call UploadRawMaterialData from c#, it get error: 404 not found.
var data = Newtonsoft.Json.JsonConvert.SerializeObject(rawMaterialVendorUploads);
string apiURL = #"http://localhost/ControlTower2WebAPI/api/PurchaseOrder/UploadRawMaterialData";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiURL);
request.UseDefaultCredentials = true;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = data.Length;
using (Stream webStream = request.GetRequestStream())
using (StreamWriter requestWriter = new StreamWriter(webStream, System.Text.Encoding.ASCII))
{
requestWriter.Write(data);
}
try
{
WebResponse webResponse = request.GetResponse();
using (Stream webStream = webResponse.GetResponseStream() ?? Stream.Null)
using (StreamReader responseReader = new StreamReader(webStream))
{
string response = responseReader.ReadToEnd();
}
}
catch (Exception exception)
{
}
using postman return similar error:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost/ControlTower2WebAPI/api/PurchaseOrder/UploadRawMaterialData'.",
"MessageDetail": "No action was found on the controller 'PurchaseOrder' that matches the request."
}
But if I use postman to call it like this, no issue:
http://localhost/ControlTower2WebAPI/api/PurchaseOrder/UploadRawMaterialData?rawMaterialSupplierData=test
What am I missing?
In your method signature for the UploadRawMaterialData method you are missing the [FromBody] attribute. All POST requests with data in the body need this
You have two options,
Use [FromBody] as suggested in other answer,
Make your Url like this.
string queryData="test"
string apiUrl="http://localhost/ControlTower2WebAPI/api/PurchaseOrder/UploadRawMaterialData?rawMaterialSupplierData="+test;
Basically,
The way you are sending your query data is all that matters, If you don't specify [FromBody] attribute, the data is passed in the URI and URI has to be modified.

C# Xamarin Android Rest call in PCL error "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."

I have used SO to help with several issues in the past. However, I cannot find a solution to something I have been struggling with for 2 days now.
I am a noob, please be kind :)
I have an app that I created using Xamarin Studio, targeted for Android. It is a basic GET request from a Rest Api. It was working perfectly until I realized I was not helping myself when it came time to create the same app in IOS and Windows. Once I changed my project to utilize a PCL I started getting errors, primarily around my RestClient class (originally got from http://www.codeproject.com/Tips/497123/How-to-make-REST-requests-with-Csharp)
From my droid app class:
var apiUser = GetString(Resource.String.apiUser);
var apiPass = GetString(Resource.String.apiPass);
//Get token from API
string token = authenticate(apiUser,apiPass);
public static string authenticate(string apiUser, string apiPass)
{
Authentication Auth = new Authentication ();
try
{
// set json by passing AuthenticationUrl as endpoint, returns json data
var o = JObject.Parse(EntryRepository.getJson(PJTApiUrls.getAuthenticationUrl(apiUser,apiPass)));
Auth.Token = (string)o["Token"];
return Auth.Token;
}
catch (Exception e)
{
// Couldn't do stuff. Log the exception.
// TODO possible timeout, try again, if fails again then return error message
if (e.Message.Contains("400") || e.Message.Contains("401"))
{
string error = string.Format("Invalid credentials, please try again");
return error;
} else {
string error = string.Format ("An error occurred: \r\n{0}", e.Message);
return error;
}
}
}
getAuthenticationUrl gets the api URL.
Here is getJson (in PCL):
public static string getJson(string endpoint)
{
string apiurl = endpoint;
var client = new _RestClient();
client.EndPoint = apiurl;
client.ContentType = "application/json";
client.Method = HttpVerb.GET;
//client.Method = HttpVerb.POST;
client.PostData = "";
//client.PostData = "{postData: value}";
//client.PostData = "{'someValueToPost': 'The Value being Posted'}";
var json = client._MakeRequestAsync();
// to append parameters, pass them into make request:
//var json = client.MakeRequest("?param=0");
return json.ToString();
}
And for the _RestClient class (in PCL):
public async Task<string> _MakeRequestAsync()
{
try {
var request = _MakeRequestAsync ("");
return await request;
}
catch (Exception e){
return e.Message;
}
}
public async Task<string> _MakeRequestAsync(string parameters)
{
var uri = new Uri(EndPoint + parameters);
var request = WebRequest.Create(uri) as HttpWebRequest;
using (var response = await request.GetResponseAsync () as HttpWebResponse) {
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK) {
var message = String.Format ("Request failed. Received HTTP {0}", response.StatusCode);
throw new Exception (message);
}
// grab the response
using (var responseStream = await Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null)) {
//using (var responseStream = response.GetResponseStream ()) {
if (responseStream != null)
using (var reader = new StreamReader (responseStream)) {
responseValue = reader.ReadToEnd ();
}
}
return responseValue;
}
}
responseValue is returning null
return await request is saying "Status = Waiting for activation"
I have also had the error: "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."
But this works if the RestClient class is within Droid (Instead of the shared PCL) and contains the following:
public string MakeRequest ()
{
return MakeRequest ("");
}
public string MakeRequest (string parameters)
{
var request = (HttpWebRequest)WebRequest.Create (EndPoint + parameters);
request.Method = Method.ToString ();
request.ContentLength = 0;
request.ContentType = ContentType;
if (!string.IsNullOrEmpty (PostData) && Method == HttpVerb.POST) {
var bytes = Encoding.GetEncoding ("iso-8859-1").GetBytes (PostData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream ()) {
writeStream.Write (bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse)request.GetResponse ()) {
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK) {
var message = String.Format ("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException (message);
}
// grab the response
using (var responseStream = response.GetResponseStream ()) {
if (responseStream != null)
using (var reader = new StreamReader (responseStream)) {
responseValue = reader.ReadToEnd ();
}
}
return responseValue;
}
}
I cannot figure this out, any help/guidance is appreciated. Let me know if I can clarify anything.
***** UPDATE ***** Thanks to #milen-pavlov help thus far, here is where I am currently at:
in Android project:
var apiUser = GetString(Resource.String.apiUser);
var apiPass = GetString(Resource.String.apiPass);
//Get token from API
var token = await authenticate(apiUser,apiPass);
lblOutput.Text = token;
calls (also in Android project):
public static async Task<string> authenticate(string apiUser, string apiPass)
{
Authentication Auth = new Authentication ();
try
{
// set json by passing AuthenticationUrl as endpoint, returns json data
var o = JObject.Parse(await EntryRepository.getJson(PJTApiUrls.getAuthenticationUrl(apiUser,apiPass)));
Auth.Token = (string)o["Token"];
return Auth.Token;
}
catch (Exception e)
{
if (e.Message.Contains("400") || e.Message.Contains("401"))
{
string error = string.Format("Invalid credentials, please try again");
return error;
} else {
string error = string.Format ("An error occurred: \r\n{0}", e.Message);
return error;
}
}
}
Calls json class in PCL project:
public static async Task<string> getJson(string endpoint)
{
string apiurl = endpoint;
var client = new _RestClient();
client.EndPoint = apiurl;
client.ContentType = "application/json";
client.Method = HttpVerb.GET;
client.PostData = "";
var json = await client._MakeRequestAsync();
return json;
}
which then calls restclient class in PCL project:
public async Task<string> _MakeRequestAsync()
{
var request = _MakeRequestAsync ("");
return await request;
}
public async Task<string> _MakeRequestAsync(string parameters)
{
var uri = new Uri(EndPoint + parameters);
using (var client = new HttpClient())
{
var response = await client.GetAsync(uri);
return await response.Content.ReadAsAsync<string>();
};
}
End result/error:
Any guidance is appreciated!
Can you use HttpClient instead?
Sample Get request will look similar to this:
public async Task<string> _MakeRequestAsync(string parameters)
{
var uri = new Uri(EndPoint + parameters);
using (var client = new HttpClient())
{
var response = await client.GetAsync(uri);
return await result.Content.ReadAsStringAsync();
};
}

How to Send POST Request in windows Phone 8 and get its Response in json

I am trying to call a web service
which returns a JSON response. So far my code is working fine for GET Request but now services on server are POST and I have no idea how to do that! Below is the code for GET Request:
private void callSigninWebservice()
{
setProgressIndicator(true);
SystemTray.ProgressIndicator.Text = "Signing in please wait";
try
{
WebClient webClient = new WebClient();
Uri uri = new Uri(GlobalVariables.URL_USER +
GlobalVariables.URL_STUDENT_SIGNIN_MODE_LOGIN +
GlobalVariables.URL_EMAIL + tbUsername.Text +
GlobalVariables.URL_PASSWORD + tbPassword.Password);
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(uri);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "error came here 1");
}
}
For Response
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
JObject parentObj = JObject.Parse(e.Result);
String strResult = (String)parentObj[SigninData.JSON_result];
bool bolresult = strResult.Equals(SigninData.JSON_result_success, StringComparison.Ordinal);
if (bolresult)
{
JObject dataObj = (JObject)parentObj[SigninData.JSON_data];
setUserData(dataObj);
NavigationService.Navigate(new Uri("/BasePage.xaml", UriKind.RelativeOrAbsolute));
}
else
{
String error = (String)parentObj[SigninData.JSON_data];
MessageBox.Show("Error : " + error);
}
setProgressIndicator(false);
}
catch (Exception)
{
setProgressIndicator(false);
}
}
This is a simple way of making a post request and receiving a response in JSON for future parse:
internal static async Task<String> GetHttpPostResponse(HttpWebRequest request, string postData)
{
String received = null;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] requestBody = Encoding.UTF8.GetBytes(postData);
// ASYNC: using awaitable wrapper to get request stream
using (var postStream = await request.GetRequestStreamAsync())
{
// Write to the request stream.
// ASYNC: writing to the POST stream can be slow
await postStream.WriteAsync(requestBody, 0, requestBody.Length);
}
try
{
// ASYNC: using awaitable wrapper to get response
var response = (HttpWebResponse)await request.GetResponseAsync();
if (response != null)
{
var reader = new StreamReader(response.GetResponseStream());
// ASYNC: using StreamReader's async method to read to end, in case
// the stream i slarge.
received = await reader.ReadToEndAsync();
}
}
catch (WebException we)
{
var reader = new StreamReader(we.Response.GetResponseStream());
string responseString = reader.ReadToEnd();
Debug.WriteLine(responseString);
return responseString;
}
return received;
}

Post string and bytearray to server

I have done POSTING and GETing from server using string post data, but now i have the next WebService:
submitFeedback(String token, String subject, String body, byte[] photo, byte[] video);
private void PostFeedbackData()
{
if (GS.online != true)
{
MessageBox.Show(GS.translations["ErrorMsg0"]);
}
else
{
HttpWebRequest request = HttpWebRequest.CreateHttp("https://****/feedback");
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
}
}
void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
// End the stream request operation
Stream postStream = myRequest.EndGetRequestStream(callbackResult);
// Create the post data
string postData = "";
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
postData = "{\"jsonrpc\": \"2.0\", \"method\": \"getUserSchedule\", \"params\":[" + "\"" + (App.Current as App).UserToken + "\",\"" + FeedbackTitle.Text + "\",\"" + FeedbackContent.Text + "\",\"" + imageBytes + "\"], \"id\": 1}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
});
}
Look at post data - it is a string, i can't place there imageBytes array. How to do it?
Is there any reason for using HttpWebRequest ?
I am asking that because i think that the correct way of sending files to a service is by multipartform data. With HttpWebRequest you have to manually implement that.
Here is an example that is using Microsoft's HttpClient that might work for you:
public async Task<string> submitFeedback(String token, String subject, String body, byte[] photo, byte[] video) {
var client = new HttpClient();
var content = new MultipartFormDataContent();
// Some APIs do not support quotes in boundary field
foreach (var param in content.Headers.ContentType.Parameters.Where(param => param.Name.Equals("boundary")))
param.Value = param.Value.Replace("\"", String.Empty);
var tok = new StringContent(token);
content.Add(tok, "\"token\"");
var sub = new StringContent(subject);
content.Add(tok, "\"subject\"");
// Add the Photo
var photoContent = new StreamContent(new MemoryStream(photo));
photoContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"photo\"",
FileName = "\"photoname.jpg\""
};
photoContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(photoContent);
// Add the video
var videoContent = new StreamContent(new MemoryStream(video));
videoContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"video\"",
FileName = "\"videoname.jpg\""
};
videoContent.Headers.ContentType = MediaTypeHeaderValue.Parse("video/mp4");
content.Add(videoContent);
HttpResponseMessage resp;
try {
resp = await client.PostAsync("SERVER_URL_GOES_HERE", content);
}
catch (Exception e)
{
return "EXCEPTION ERROR";
}
if (resp.StatusCode != HttpStatusCode.OK)
{
return resp.StatusCode.ToString();
}
var reponse = await resp.Content.ReadAsStringAsync();
return reponse;
}
Change accordingly.
Note: HttpClient is also using HttpWebRequest under the hood.
Also I don't think its a good idea to have the UI thread making the request. That makes no sense since you are blocking the interface and making the async theory useless.

Categories

Resources