Xamarin: Upload image to server - c#

I need upload image to server using api.
Now I'm using System.Net.Http;
byte[] lFileBytes= DependencyService.Get<IFileHelper>().ReadAllBytes(ImagePath);
ByteArrayContent lFileContent = new ByteArrayContent(lFileBytes,0,lFileBytes.Length);
lFileContent.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse("form-data");
lFileContent.Headers.ContentType=new MediaTypeHeaderValue("image/jpg");
lFileContent.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("name","file"));
lFileContent.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("filename", "9.jpg"));
lFileContent.Headers.ContentLength= lFileBytes.Length;
lContent.Add(lFileContent);
public byte[] ReadAllBytes(string path) {
using (var streamReader = new StreamReader(path))
{
using (var memoryStream = new MemoryStream())
{
streamReader.BaseStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}
After sending request i have error Type file is invalid
I'm thinking problem in byte[] ReadAllBytes(string path)
For request i can use Stream or byte[]
Please, help
UPDATE
lRequestResponse = await lHttpClient.PostAsync("URL", lContent);

In case you still need, this works for me:
var cont = new MultipartFormDataContent();
var image = new StreamContent(img.Image.GetStream());
cont.Add(image, "\"file\"", img.FileName);
var uri = App.apiurl + $"FileUpload/" + img.FileName + "/";
using (var client = new HttpClient())
{
var response = await client.PostAsync(uri, cont);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
// return error code
}
}

This help me
MultipartFormDataContent lContent=new MultipartFormDataContent();
byte[] lBytes = DependencyService.Get<IFileHelper>().ReadAllBytes(filename);
ByteArrayContent lFileContent= new ByteArrayContent(lBytes);
lFileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = filename,
Name = "imgFile"
};
lFileContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
lContent.Add(lFileContent);
HttpResponseMessage lRequestResponse=await lHttpClient.PostAsync(await url, lContent);
IFileHelper implement on IOS
namespace Client.iOS
{
public class FileHelper : IFileHelper
{
private string GetLocalFilePath(string filename)
{
string docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string libFolder = Path.Combine(docFolder, "..", "images", "Databases");
if (!Directory.Exists(libFolder))
{
Directory.CreateDirectory(libFolder);
}
return Path.Combine(libFolder, filename);
}
public byte[] ReadAllBytes(string filename)
{
string path=GetLocalFilePath(filename);
return (FileStream(path) as MemoryStream).ToArray();
}
private Stream FileStream(string path)
{
StreamReader lStreamReader = new StreamReader(path);
MemoryStream lMemoryStream = new MemoryStream();
lMemoryStream.Position = 0;
lStreamReader.BaseStream.CopyTo(lMemoryStream);
return lMemoryStream;
}
}
}

Related

My memory stream does not write to the content of the httpResponse a ZIP file

I am trying to write the stream resulting from compressing several files in a ZIP but I can't. The ZIP file does, but when I want to write the resulting stream, the copyto method does nothing and my http request never ends.
I don't know why my logic doesn't work, I hope you can help me please.
public async Task<HttpResponseMessage> downloadFile3(string filePath, System.Threading.CancellationToken token)
{
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new PushStreamContent(async (streamout, context, transportContext) =>
{
try
{
using (var ms = new MemoryStream())
{
using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
var entry = zipArchive.CreateEntry(filePath);
using (var fileStream = File.OpenRead(filePath))
{
using (var entryStream = entry.Open())
{
await fileStream.CopyToAsync(entryStream);
}
}
}
ms.Position = 0;
ms.CopyTo(streamout); //THIS LINE DOESN'T WORK
}
}
catch (Exception ex)
{
}
finally
{
streamout.Close();
}
}, "application/zip"),
};
response.Content.Headers.ContentLength = new FileInfo(filePath).Length;
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
Size = new FileInfo(filePath).Length,
FileName = Path.GetFileName(filePath)
};
return response;
}

Posting file and list of object in same request in asp.net

can I set a post method to post image and list of object in the same time I have the following code it's logically working but I'm trying to test this request with postman
private ApplicationDbContext1 db = new ApplicationDbContext1();
[Route("api/save_BUY")]
[HttpPost]
public async Task< IHttpActionResult> save_BUY(IEnumerable<BY_table> BY_table,int id)
{
var BY_API = BY_table.Select(p => new BY_API
{
ITEM_CODE = p.ITEM_CODE,
ITEM_NAME = p.ITEM_NAME,
Unit = p.Unit,
Unit_Core = Convert.ToDecimal(p.Unit_Core),
}).AsQueryable();
var ctx = HttpContext.Current;
var root = ctx.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
await Request.Content.ReadAsMultipartAsync(provider);
foreach (var file in provider.FileData)
{
var name = file.Headers
.ContentDisposition
.FileName;
var localFileName = file.LocalFileName;
var filePath = Path.Combine(
root, "files", name);
byte[] fileBytes;
using (var fs = new FileStream(
PHOTO, FileMode.Open, FileAccess.Read))
{
fileBytes = new byte[fs.Length];
fs.Read(
fileBytes, 0, Convert.ToInt32(fs.Length));
}
var MASTER_BUY = db.MASTER_BUY.Where(x => x.int==id)
{
MASTER_BUY.image= fileBytes;
};
db.SaveChanges();
return Ok(BY_API);
}
}
how can I make this request in postman to test it.
pleas help.
You Can send Image Form of base64 String And Get String value from Client(Postman)
Image to Base 64 String
This is one Of Online tools for help you get base 64 string from file!

How to encrypt string with public key and decrypt using private key using MimeKit?

I'm having a hard time looking for a solution on how to encrypt a string with public key certificate and decrypt it with private key certificate using Mimekit. This is my code for encrypting a text file with a public key certificate :
public string encryptFile(string filename)
{
var certificate2 = new X509Certificate2(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, /Sample.crt));
MimeEntity body;
using (var content = new MemoryStream(File.ReadAllBytes(filename)))
{
var part = new MimePart(MimeTypes.GetMimeType(filename))
{
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Binary,
FileName = Path.GetFileName(filename),
Content = new MimeContent(content)
};
var recipient = new CmsRecipient(certificate2)
{
EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }
};
var recipients = new CmsRecipientCollection();
recipients.Add(recipient);
using (var ctx = new TemporarySecureMimeContext())
body = ApplicationPkcs7Mime.Encrypt(ctx, recipients, part);
}
string response = body.ToString();
return response;
}
But using this way I'm writing the string I wanted to encrypt to a file before encrypting it. What I wanted to do is to directly encrypt the string using MimeKit. I'm only new to using MimeKit. If anyone knows how can I do this it will be a great help.
public string EncryptString(string value)
{
var certificate2 = new X509Certificate2(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, /Sample.crt));
MimeEntity body;
using (var content = new MemoryStream(Encoding.UTF8.GetBytes (value)))
{
var part = new MimePart(MimeTypes.GetMimeType(filename))
{
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Binary,
FileName = Path.GetFileName(filename),
Content = new MimeContent(content)
};
var recipient = new CmsRecipient(certificate2)
{
EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }
};
var recipients = new CmsRecipientCollection();
recipients.Add(recipient);
using (var ctx = new TemporarySecureMimeContext())
body = ApplicationPkcs7Mime.Encrypt(ctx, recipients, part);
}
using (var memory = new MemoryStream ()) {
body.WriteTo (memory);
string response = Encoding.UTF8.GetString (memory.ToArray ());
return response;
}
}

Download report file which is to be generated in to client side

I am using the below code to create and download a Telerik report.
var reportName = "../api/Templates/Invoice.trdp";
var reportProcessor = new Telerik.Reporting.Processing.ReportProcessor();
var reportSource = new Telerik.Reporting.UriReportSource()
{
Uri = reportName
};
reportSource.Parameters.Add("ID", 3);
reportSource.Parameters.Add("Username", "demouser");
var deviceInfo = new System.Collections.Hashtable()
{
{"DocumentTitle", "Annual Report" }
};
var result = reportProcessor.RenderReport("PDF", reportSource, deviceInfo);
if (!result.HasErrors)
{
System.IO.File.WriteAllBytes(System.IO.Path.ChangeExtension(reportName, "pdf"), result.DocumentBytes);
}
}
Once I host it in a server, it creates the file in the server side. How can I download it into the client machine without creating any files in the server.
I was able to do it by returning the file back to the client using the return type HttpResponseMessage
public HttpResponseMessage GenerateOrderReport(int orderID)
{
var reportName = ConfigurationManager.AppSettings["EmailAttachmentURLTemplate"];
string activeDir = ConfigurationManager.AppSettings["EmailAttachmentSaveLocation"];
string newPath = System.IO.Path.Combine(activeDir, ConfigurationManager.AppSettings["EmailAttachmentSaveFolder"]);
var reportProcessor = new Telerik.Reporting.Processing.ReportProcessor();
var reportSource = new Telerik.Reporting.UriReportSource()
{
Uri = reportName
};
reportSource.Parameters.Add("OrderID", 141);
reportSource.Parameters.Add("OrderMethodTypeID", 2);
var deviceInfo = new System.Collections.Hashtable()
{
{"DocumentTitle", "Order Report" }
};
var result = reportProcessor.RenderReport("PDF", reportSource, deviceInfo);
if (!result.HasErrors)
{
System.IO.Directory.CreateDirectory(newPath);
string newFileName = "OrderReport.pdf";
newPath = System.IO.Path.Combine(newPath, newFileName);
FileStream fileStream = new FileStream(newPath, FileMode.Create, FileAccess.ReadWrite);
fileStream.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
fileStream.Close();
HttpResponseMessage fileResult = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(newPath, FileMode.Open);
fileResult.Content = new StreamContent(stream);
fileResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
fileResult.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
fileResult.Content.Headers.ContentDisposition.FileName = newFileName;
return fileResult;
}
else
{
throw new Exception("Report contains errors. " + result.Errors[0].Message);
}
}

AWS S3 file has no contents when downloading

I am trying to pass a file from S3 directly into the users' download stream like this:
public HttpResponseMessage Download()
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream();
using (var client = new AmazonS3Client(RegionEndpoint.USWest2))
{
var request = new GetObjectRequest
{
BucketName = "bucket",
Key = "filename"
};
using (var response = client.GetObject(request))
{
response.ResponseStream.CopyTo(stream);
}
}
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "file.pdf"
};
return result;
}
But the file downloads as 0 bytes. I assumed that the file is completely loaded in memory on line ResponseStream.CopyTo.

Categories

Resources