Multiple image uploading issue in xamarin.forms app [duplicate] - xamarin

In my xamarin forms. I am trying to send multiple images and files using mulipart-formdata.The API team work on back end gave me this structure.
As you can see there is a parameter called "notification_files" which will send images and files selected using Media.Plugin and filepicker plugin in my app. I know how to send data in normal way. But how can I send these formadata using httpclient in xamarin.forms?The API team gave me their equivalent Restsharp code:
var client = new RestClient("{{api_url}}/MYData");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "bearer {{token}}");
request.AddHeader("Content-Type", "application/json");
request.AlwaysMultipartFormData = true;
request.AddParameter("ids", " [{\"id\":1,\"person_id\":5}]");
request.AddParameter("title", " Test");
request.AddParameter("description", " Test");
request.AddParameter("send_text_message", " true");
request.AddParameter("text_message", " Test");
request.AddParameter("notification_type"," global");
request.AddParameter("my_files", "[
{
\"name\": \"abc.jpg\",
\"key\": \"1583307983694\"
}
]");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
How can I write this using HttpClient?
What I have tried
try {
MultipartFormDataContent multiContent = new MultipartFormDataContent();
foreach (SelectedDocumentModel model in SelectedFileData)
{
byte[] byteArray = Encoding.UTF8.GetBytes(model.Path);
MemoryStream stream = new MemoryStream(byteArray);
HttpContent fileStreamContent1 = new StreamContent(stream);
fileStreamContent1.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{
Name = model.FileName,
FileName = model.FileName
};
fileStreamContent1.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
multiContent.Add(fileStreamContent1);
}
multiContent.Add(new StringContent(notificationdetails[0]), "title");
multiContent.Add(new StringContent(notificationdetails[1]), "description");
multiContent.Add(new StringContent(notificationdetails[3]), "type");
multiContent.Add(new StringContent(notificationdetails[7]), "send_text_message");
multiContent.Add(new StringContent(notificationdetails[2]), "text_message");
multiContent.Add(new StringContent(notificationdetails[8]), "send_email");
multiContent.Add(new StringContent(notificationdetails[9]), "notification_type");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer",Settings.AuthToken);
var response = await client.PostAsync(url, multiContent);
var responsestr = response.Content.ReadAsStringAsync().Result;
await DisplayAlert("Result", responsestr.ToString(), "ok");
}
catch (Exception ex)
{
await DisplayAlert("Result", ex.Message.ToString(), "ok");
}
DataManager is my observable collection contains images and files selected.
Selecting image using media.plugin and allocating to my observable collection
var Filename = Path.GetFileName(file.Path);
var FilePath = file.Path;
var newList = new SelectedDocumentModel()
{
FileName = Filename,
SelectedImage = imageSource,
IsLoadingVisible = false,
Path = FilePath
};
DataManager.Add(newList);
Any help is appreicted.

I done it like this
MultipartFormDataContent multiContent = new MultipartFormDataContent();
multiContent.Headers.ContentType.MediaType = "multipart/form-data";
foreach (SelectedDocumentModel model in SelectedFileData)
{
var upfilebytes = File.ReadAllBytes(model.Path);
multiContent.Add(new ByteArrayContent(upfilebytes, 0, upfilebytes.Count()), "notification_files", model.FileName);
}
multiContent.Add(new StringContent(notificationdetails[0]), "title");
multiContent.Add(new StringContent(notificationdetails[1]), "description");
multiContent.Add(new StringContent(notificationdetails[3]), "type");
multiContent.Add(new StringContent(notificationdetails[7]), "send_text_message");
multiContent.Add(new StringContent(notificationdetails[2]), "text_message");
multiContent.Add(new StringContent(notificationdetails[8]), "send_email");
multiContent.Add(new StringContent(notificationdetails[9]), "notification_type");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer",Settings.AuthToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

Related

WebAPI:How to read message from HttpResponseMessage class at client side

below is a sample action which is returning HttpResponseMessage and if any error occur then this way web api action returning error message and status code to client side return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);.
[HttpGet, Route("GetAll")]
public HttpResponseMessage GetAllCustomers()
{
IEnumerable<Customer> customers = repository.GetAll();
if (customers == null)
{
var message = string.Format("No customers found");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, customers);
}
}
when i am invoking action by http client then i am not getting message in ReasonPhrase property. just tell me what is the right way to read message at client side which is passing like this way return Request.CreateResponse(HttpStatusCode.OK, customers);
here is my client side code
private async void btnFind_Click(object sender, EventArgs e)
{
var fullAddress = baseAddress + "api/customer/GetByID/"+txtFind.Text;
Customer _Customer = null;
using (var client = new HttpClient())
{
using (var response = client.GetAsync(fullAddress).Result)
{
if (response.IsSuccessStatusCode)
{
var customerJsonString = await response.Content.ReadAsStringAsync();
_Customer = JsonConvert.DeserializeObject<Customer>(customerJsonString);
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
}
}
if (_Customer != null)
{
var _CustList = new List<Customer> { _Customer };
dgCustomers.DataSource = _CustList;
}
}
response.ReasonPhrase not holding the message which i am passing from action. so may be i am not doing things to read message. please tell me what to change in my code to read the message. thanks
i have the job this way.
private async void btnFind_Click(object sender, EventArgs e)
{
var fullAddress = baseAddress + "api/customer/GetByID/"+txtFind.Text;
Customer _Customer = null;
try
{
using (var client = new HttpClient())
{
using (var response = client.GetAsync(fullAddress).Result)
{
if (response.IsSuccessStatusCode)
{
var customerJsonString = await response.Content.ReadAsStringAsync();
_Customer = JsonConvert.DeserializeObject<Customer>(customerJsonString);
}
else
{
//Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
var ErrMsg = JsonConvert.DeserializeObject<dynamic>(response.Content.ReadAsStringAsync().Result);
MessageBox.Show(ErrMsg.Message);
}
}
}
if (_Customer != null)
{
var _CustList = new List<Customer> { _Customer };
dgCustomers.DataSource = _CustList;
}
}
catch (HttpRequestException ex)
{
// catch any exception here
}
}
read error message this way.
var ErrMsg = JsonConvert.DeserializeObject<dynamic>(response.Content.ReadAsStringAsync().Result);

Xamarin Forms - Cannot set the ContentLenght of HttpWebRequest

I tried to mke a request with GET and parameters. However, I got an exception for the WinPhone8.1 which meaned that GET was a violation protocol due to a content added in. So making a POST request is the solution.
Despite my searches, I'm still not able to set the content lenght property of my HttpWebRequest.. Why?
private static async void AsyncRequest(string url, string contentType, string methodType, int contentLenght, Action<Object, string> callback, Action<HttpStatusCode, JObject, Action<Object, string>> parserFunction)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = contentType;
request.Method = methodType;
request.Proxy = null;
if (methodType == Method.POST)
{
request.ContentLenght = "contentLenght";
request.Headers["content-length"] = "contentLenght";
request.Headers["Content-Length"] = "contentLenght";
request.Headers[HttpRequestHeader.ContentLength] = "contentLenght";
request.Headers["HttpRequestHeader.ContentLength"] = "contentLenght";
request.Content.Headers.ContentLength = "contentLenght";
...........
Nothing works ><
}
Debug.WriteLine("1");
Task<WebResponse> task = Task.Factory.FromAsync(
request.BeginGetResponse,
asyncResult => request.EndGetResponse(asyncResult),
(object)null);
Debug.WriteLine("2");
await task.ContinueWith(t => ReadStreamFromResponse(t.Result, callback, parserFunction));
}
Thank to jsonmcgraw for its answer on Xamarin Forums
If you want to make a POST request intead of GET request, then there is the two methods which can make you able to make GET/POST requests.
So, first, an async GET request.
public static async Task<string> MakeGetRequest(string url, string cookie)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
request.ContentType = "text/html";
request.Method = "GET";
request.Headers ["Cookie"] = cookie;
var response = await request.GetResponseAsync ();
var respStream = response.GetResponseStream();
respStream.Flush ();
using (StreamReader sr = new StreamReader (respStream)) {
//Need to return this response
string strContent = sr.ReadToEnd ();
respStream = null;
return strContent;
}
}
Sample usage:
public static async Task<MyModel[]> GetInfoAsync(int page, string searchString, string cookie)
{
string url = Constants.url + Constants.Path+
"page=" + page +
"&searchString=" + searchString;
string result = await WebControl.MakeGetRequest (url, cookie);
MyModel[] models = Newtonsoft.Json.JsonConvert.DeserializeObject<MyModel[]> (result);
return models;
}
Next, an async POST request
public static async Task<string> MakePostRequest (string url, string data, string cookie, bool isJson = true)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
if (isJson)
request.ContentType = "application/json";
else
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Headers ["Cookie"] = cookie;
var stream = await request.GetRequestStreamAsync ();
using (var writer = new StreamWriter (stream)) {
writer.Write (data);
writer.Flush ();
writer.Dispose ();
}
var response = await request.GetResponseAsync ();
var respStream = response.GetResponseStream();
using (StreamReader sr = new StreamReader (respStream)) {
//Need to return this response
return sr.ReadToEnd();
}
}
Sample usage:
public static async Task<ResultModel> PostInfoAsync(int id, string cookie)
{
string data = "id=" + id;
//third param means that the content type is not json
string resp = await WebControl.MakePostRequest (Constants.url + Constants.Path, data, cookie, false);
ResultModel model;
try {
model = JsonConvert.DeserializeObject<ResultModel> (resp);
}
catch (Exception) {
model = new ResultModel{ isSuccess = false, Message = resp };
}
return model;
}

Executeasync in the same method

i'm trying to call a restclient in the method including the parsing of data, her's my code which i want to make all of it in the method,any ideas please :
public void Convert(object value, Type targetType, object parameter, CultureInfo culture){RestClient client = new RestClient();
client.BaseUrl = "http://";
RestRequest request = new RestRequest();
request.Method = Method.GET;
request.AddParameter("action", "REE");
request.AddParameter("atm_longitude", location.Longitude);
client.ExecuteAsync(request, ParseFeedCallBack_ListDistance);}
public void ParseFeedCallBack_ListDistance(IRestResponse response){
if (response.StatusCode == HttpStatusCode.OK)
{
ParseXMLFeedDistance(response.Content);
}
private string ParseXMLFeedDistance(string feed)
{
.... return myvalueToBind;
}
i did somthing like this,but it don't call ParseXMLFeedDistance for every item :
foreach (var resp in xmlItems2.Descendants("result"))
{
RestClient client = new RestClient();
client.BaseUrl = "http://";
RestRequest request = new RestRequest();
request.Method = Method.GET;
request.AddParameter("action", "atms_distances");
request.AddParameter("lang", "ar");
request.AddParameter("mode", "xml");
request.AddParameter("appli", "WP");
request.AddParameter("mobile_latitude", "35.843283");
request.AddParameter("mobile_longitude", "10.61617");
request.AddParameter("atm_latitude", resp.Element("Lattitude"));
request.AddParameter("atm_longitude",resp.Element("longitude"));
// client.ExecuteAsync(request, ParseFeedCallBack_ListDistance);
client.ExecuteAsync(request, response =>
{
ParseXMLFeedDistance(response.Content);
});
}
private void ParseXMLFeedDistance(string feed)
{
if (feed == null)
return;
try
{
XElement xmlItems = XElement.Parse(feed);
XDocument xmlItems2 = XDocument.Parse(feed);
var list = new List<State>();
foreach (XElement val in xmlItems2.Descendants("result").Last().Elements())
{
// distance = val.Value;
list.Add(new State
{
TotalDistance = val.Value,
});
}
ResultSearch_ListDistance.ItemsSource = list;
}
catch
{
}
}

paypal 400 bad request error getting at WebResponse response = request.GetResponse();

i'm trying to integarte paypal api for sandbox testing account. i'm getting 400 bad request error when i try to get access token from the request code.
cshtml: Goto paypal
Js: function GetPaypal() {
window.location = "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize?client_id=clientid&response_type=code&scope=Email&redirect_uri=http://localhost:4427/";
}
C# code:
I am getting code using following code. :
public ActionResult Index(string code)
{
if (code != null)
{
string postcontents = string.Format("client_id={0}&client_secret={1}&grant_type=authorization_code&redirect_uri={2}&code={3}"
, System.Web.HttpUtility.UrlEncode("client_id")
, System.Web.HttpUtility.UrlEncode("Client Secret")
, System.Web.HttpUtility.UrlEncode("http://localhost:4427/")
, System.Web.HttpUtility.UrlEncode(code));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice");
request.Method = "POST";
byte[] postcontentsArray = System.Text.Encoding.UTF8.GetBytes(postcontents);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postcontentsArray.Length;
//OAuth.
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(postcontentsArray, 0, postcontentsArray.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
string responseFromServer = reader.ReadToEnd();
reader.Close();
responseStream.Close();
response.Close();
// return SerializeToken(responseFromServer);
dynamic dynObj = JsonConvert.DeserializeObject(responseFromServer);
string token = dynObj["access_token"];
//token = ser.Deserialize<ImportContacts._Default.GoogleOAuthToken>(responseFromServer);
}
}
}
return View();
}
Please change Your CSHTML url as below:-
<script type="text/javascript">
function GetGmailContacts() {
window.location = "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize?client_id=clientid&response_type=code+id_token&scope=openid profile email&redirect_uri=localhost_url";
}
</script>
C# code:-
public ActionResult Index(string code,string id_token)
{
if (code != null)
{
string postcontents = string.Format("client_id={0}&client_secret={1}&grant_type=authorization_code&redirect_uri={2}&code={3}"
, System.Web.HttpUtility.UrlEncode("client_id")
, System.Web.HttpUtility.UrlEncode("Client Secret")
, System.Web.HttpUtility.UrlEncode(localhost_url)
, System.Web.HttpUtility.UrlEncode(code));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice");
request.Method = "POST";
byte[] postcontentsArray = System.Text.Encoding.UTF8.GetBytes(postcontents);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postcontentsArray.Length;
//OAuth.
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(postcontentsArray, 0, postcontentsArray.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
string responseFromServer = reader.ReadToEnd();
reader.Close();
responseStream.Close();
response.Close();
// return SerializeToken(responseFromServer);
dynamic dynObj = JsonConvert.DeserializeObject(responseFromServer);
string token = dynObj["access_token"];
//token = ser.Deserialize<ImportContacts._Default.GoogleOAuthToken>(responseFromServer);
}
}
}
return View();
}
I hope it will work.

can't get parameter from XMLHttpRequest

I can see parameters from js, but I can't use getParameter to get them. what's the problem?
js code
var email = document.getElementById("email").value;
var password = document.getElementById("password").value;
var req = new XMLHttpRequest();
req.open("POST", "../PersonTest", true);
req.onreadystatechange = function(){
if (req.readyState == 4) {
if (req.status == 200) {
alert(req.responseText);
} else {
alert("HTTP error " + req.status + ": " + req.statusText);
}
}
}
req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
req.send("email=" + email + "&password=" + password);
servlet code
response.setContentType("text/xml;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
//print request content
ServletInputStream is = request.getInputStream();
...
System.out.println(new String(baos.toByteArray(), "utf-8"));
//get parameter
String email = request.getParameter("email");
String password = request.getParameter("password");
System.out.println(email + " " + password);
}
servlet output:
email=123&password=123
null null

Resources