Flutter : InternalError , Filter error, bad data when upload image on server - http

I do simple upload image to server using http packages. But the problem is , when i upload it i got error Unhandled Exception: InternalError: 'Filter error, bad data'.
Upload
Future testUpload(File selfieImage, String pembertang) async {
final result = await reusableRequestServer.requestServer(() async {
//create multipart request for POST or PATCH method
var request = http.MultipartRequest('POST', Uri.parse('$baseApiUtang/addUtang'));
//add text fields
request.fields['pembertang'] = '$pembertang';
//create multipart using filepath, string or bytes
var pic = await http.MultipartFile.fromPath('selfie', selfieImage.path);
//add multipart to request
request.files.add(pic);
var response = await request.send();
//Get the response from the server
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print('responseData : $responseData');
print('responseString : $responseString');
return responseString;
});
return result;
}
With this strange problem , i try it with postman but it's work like i want.
My opinion, it's not problem in my backend code. I missed something ?
Update
Similiar problem with me on this issue
Update 2
When i look inside the code and print variable 1 by 1, i got status code 403

Hi can you pls try following code
var stream = new http.ByteStream(Stream.castFrom(imageFile.openRead()));
// get file length
var length = await imageFile.length();
// create multipart request
var request = new http.MultipartRequest("POST", uri);
var name = firstname +"."+imageFile.path.split(".").last;
// multipart that takes file
var multipartFile = new http.MultipartFile('profile', stream, length,
filename: basename(name));
In my case my can not take so much long name so i customise image name and then tried and its working .
so you can also try this.

Related

Xamarin forms: Method is left after callunt await client.GetAsync

I am getting data from a server via Rest API. But Whenever i am waiting for the client response the Methos is left by the Debugger and the Program start loading the GUI even though at this point there is no Data to Display. Im already stuck for a couple of days on it. How can i make the Code to wait for the Response? Iam already using Await
My Method to get The Data: (Client Call in Line 8)
public async Task<ObservableCollection<Datensatz>> getDataFromAzure()
{
string URL = URLForContent;
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("ApiKey", PW);
var result1 = await _client.GetAsync(URL, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
if (result1.StatusCode == System.Net.HttpStatusCode.OK)
{
var result = await result1.Content.ReadAsStringAsync();
var ContentFromJson = JsonConvert.DeserializeObject<ObservableCollection<Datensatz>>(result);
string json = JsonConvert.SerializeObject(ContentFromJson, Formatting.Indented);
var filename = #"data.json";
var destinatioPath = Path.Combine(Android.App.Application.Context.GetExternalFilesDir(null).ToString(), filename);
File.WriteAllText(destinatioPath, json);
App.Database_Main.FillMainDBWithJsonEntrys();
return ContentFromJson;
}
return null;
}
You can use the Wait method of the Task. Such as
Task result = getDataFromAzure()
result.Wait();
You can also use the Thread.sleep(1000) to make the main thread sleep for a while. But this will reduce the function of the application because we don't know how long time the async method need and if the time if more than 5 seconds will cause the ANR.

How can I get a string from FormData in asp.net, sent from Angular?

So I am trying to make a post (for example like those on Facebook) which contain a title, description and an image. I do this using Angular and ASP.NET CORE. My DB structure is that I save my image on the wwwroot server folder and want to create a Table 'posts' that contains a link to this folder for getting the image.
Creating a post and sending an image both work, but now I want to send my Object 'Post' and my image (FormData) in one HttpPost. However it doesn't seem to work.
Frontend Angular
onSubmit(Image) {
let post = new Post(this.post.value.titel, this.post.value.omschrijving, new Date(), this._userService.user$.getValue())
this._postService.voegPostToe(post, this.selectedFile).subscribe();
this.post.reset();
}
voegPostToe(post: Post, fileToUpload: File) {
const formData: FormData = new FormData();
formData.append('Image', fileToUpload, fileToUpload.name);
formData.append('ObjectData', JSON.stringify(post));
return this.http.post(`${environment.apiUrl}/posts`, formData);
}
Backend ASP.NET
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task<ActionResult<Post>> PostPost()
{
Post resource = JsonConvert.DeserializeObject<Post>(HttpContext.Request.Form["ObjectData"]);
var file = HttpContext.Request.Form.Files["Image"];
string fileName = new String(Path.GetFileNameWithoutExtension(file.FileName).Take(10).ToArray()).Replace(" ", "-");
fileName = fileName + DateTime.Now.ToString("yymmssfff") + Path.GetExtension(file.FileName);
string filePath = _env.WebRootPath + "\\Images\\" + fileName;
using (var fileSrteam = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fileSrteam);
}
resource.Fotolink = filePath;
_postRepository.Add(resource);
_postRepository.SaveChanges();
return NoContent();
}
My problem is that I don't know how to convert the stringified Object to the Object's class in ASP.NET, I always seem to get a BadRequest error.

AWS Lambda function returns no records if call from Xamarin Forms

I am having troubles trying to get information back from a Lambda Function in AWS. The Lambda function is behind API Gateway.
If I run the function straight from the Lambda console or from the API, works ok. If I call it with this code returns [].
I am not getting any problems if the token is correct and I can see inside the Lambda function the parameter 'LastUpdate'.
Here is the code:
public async Task<string> GetUpdates(long ticksLastCheck, string token)
{
string Error = "";
string response = "";
object data = new
{
LastUpdate = ticksLastCheck
};
var myContent = JsonConvert.SerializeObject(data);
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
//I have tested without ConfigureAwait and did not work either
var responseSync = await _client.PostAsync("getUpdates", byteContent).ConfigureAwait(false);
if (responseSync != null)
{
//I have tested with await and did not work either. With await ".Result" should be removed from the line below.
var response2 = responseSync.Content.ReadAsStringAsync();
response = response2.Result;
}
return response;
}
If I call it from Postman works as well. Is there any header or parameter that Postman sends and I am missing?
My bad. The field in DynamoDB is a string and I was sending it as a long and never converting to string.
So as soon as I change:
object data = new
{
LastUpdate = ticksLastCheck
};
into this
object data = new
{
LastUpdate = ticksLastCheck.ToString()
};
I am getting the expected response.
Thank you.

Delete function IRestResponse with RestSharp

I want to implement a delete function with a Restful API with RestSharp. I have implemended GET and POST function already. But with this delete function I don't get any feedback from the API only a httpresponse. My question is how do I make my code so I can excecute the delete function? I already have this:
// var url = string.Format("url");
// Construct the request.
// var request = new RestRequest(url, Method.DELETE);
// //IRestResponse<> response;
// //response = await restClient.ExecuteTaskAsync<>(request);
// //return response.Data;
try it
var client = new RestClient(url);
var request = new RestRequest(Method.DELETE);
IRestResponse response = client.Execute(request);
The important point here is to include "Accept" in header with value shown in code.
string url = "http://localhost:8080/laptop-bag/webapi/api/delete/2";
IRestRequest restRequest = new RestRequest(url);
restRequest.AddHeader("Accept", "*/*"); //Important
IRestClient restClient = new RestClient();
IRestResponse restResponse = restClient.Delete(restRequest);
//Status code will be 200 for successful execution
int statusCode = Convert.ToInt32(restResponse.StatusCode);

Apache Abdera Multipart Request throwing nullpointer Exception(IBM connection API)

I am using Apache abdera to post multipart request to IBM connection 4.0 API. I am getting nullpointer exception from Abdera API. Please let me know what's the root cause.
private void createEntryWithAttachment(){
try {
String activityId = "urn:lsid:ibm.com:oa:662d0dc7-0308-48ee-8291-d730c733d2d1";
String activityIdLocal = activityId.substring(activityId.lastIndexOf(":")+1, activityId.length());
String createEntryLocal = createEntry+activityIdLocal;
Abdera abdera = new Abdera();
AbderaClient client = new AbderaClient(abdera);
AbderaClient.registerTrustManager();
System.out.println("pd --->"+pd);
client.addCookie("poktam2cl.iespc.ibm.com", "PD-S-SESSION-ID", pd, "/", null, true);
RequestOptions requestOptions = client.getDefaultRequestOptions();
requestOptions.setUseChunked(true);
requestOptions.setHeader("Connection", "close");
requestOptions.setHeader("Content-Type", "multipart/related;type=\"application/atom+xml\"");
requestOptions.setContentType("multipart/related;type=\"application/atom+xml\"");
requestOptions.setSlug("Sample.txt");
Credentials credentials = new UsernamePasswordCredentials(username, password);
client.addCredentials(createEntryLocal, AuthScope.ANY_REALM,AuthScope.ANY_SCHEME, credentials);
Entry entry = abdera.getFactory().newEntry();
entry.setTitle("create entry with attachment title ");
entry.setContent("create entry with attachment content");
javax.xml.namespace.QName field = new QName("http://www.ibm.com/xmlns/prod/sn", "field", "snx");
org.apache.abdera.model.Element fieldElement = entry.addExtension(field);
fieldElement.setAttributeValue("type", "file");
fieldElement.setAttributeValue("name", "sampletextfile1");
fieldElement.setAttributeValue("position", "3000");
FileInputStream fis = new FileInputStream(filepath);
requestOptions.setHeader("Content-Length", "35");
entry.addCategory("http://www.ibm.com/xmlns/prod/sn/type","entry", "Entry");
ClientResponse response = client.post(createEntryLocal, entry, fis, "multipart/related;type=\"application/atom+xml\"", requestOptions );
System.out.println("Entry Created with attachment's resp: " + response.getStatus());
if(response.getStatus() == 201){
System.out.println("Entry Created with attachment successfully .....");
printIBMConnectionErrorMessage(response);
}else{
System.out.println("Entry with attachment creation failed");
printIBMConnectionErrorMessage(response);
//System.exit(0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Output
java.lang.NullPointerException
at org.apache.abdera.protocol.client.util.MultipartRelatedRequestEntity.writeInput(MultipartRelatedRequestEntity.java:74)
at org.apache.abdera.protocol.client.util.MultipartRelatedRequestEntity.writeRequest(MultipartRelatedRequestEntity.java:59)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at org.apache.abdera.protocol.client.AbderaClient.execute(AbderaClient.java:688)
at org.apache.abdera.protocol.client.AbderaClient.post(AbderaClient.java:306)
at JavaAgentEntryWithAttachment.createEntryWithAttachment(JavaAgentEntryWithAttachment.java:157)
at JavaAgentEntryWithAttachment.main(JavaAgentEntryWithAttachment.java:66)
This exception is coming from abdera API, class called MultipartRelatedRequestEntity.java, Line no 74. I have placed line no 74 source code below. So its clear that contentSrc is null & Abdera API not allowing me to set this value. Please let me know what I am missing here.
String contentId = entry.getContentSrc().toString();
I did in two steps:
Send the file
Call to update the data
Each with the good mime type. You can not send the file with XML mime type. And put the length of the file.
It is possible to avoid the nullpointer and do it in one request. I had the same issue and created another issue and managed to find a solution. You can find it here.
It comes down to the following code example where you create a HttpClient Part which can contain a StringPart and a FilePart
final Entry entry = // ... Create your Entry
final RequestOptions options = this.client.getDefaultRequestOptions();
options.setHeader("Content-Type", "multipart/related;type=\"application/atom+xml\"");
StringPart entryPart = new StringPart("entry", entry.toString());
entryPart.setContentType("application/atom+xml");
FilePart filePart = new FilePart("file", new File(resource.getFile()));
RequestEntity request = new MultipartRequestEntity(new Part[] { entryPart, filePart}, this.client.getHttpClientParams());
ClientResponse response = client.post(this.url + this.activityId, request, options);
Hope this will help people in the future if they are using Abdera.

Resources