Encrypted file download - c#

What I need to do is consume a document from an API, but this document comes encrypted and for me to be able to download it I need to decrypt it and store it in a local string. The idea is that you don't need to use a blob, just the temporary cached file. So my logic was as follows: Get the document via code (this returns me a binary) > Convert the binary into an array > Convert the array into a FileStream:
private static byte[] data;
public static byte[] Download(List<Document> documents)
{
Download download = new Download();
foreach (Document document in documents)
{
if (document.file_ != null)
{ `
using (var client = new RestClient(uri))
{
try
{
RestRequest request = new RestRequest(document.file_, Method.Get);
request.Timeout = -1;
request.AddHeader("Content-Type_", "application/json");
var body = #"{" + "\n" +
#" ""justices"": [" + "\n" +
#" { ""number"": ""24303016000131"" } " + "\n" +
#" ] " + "\n" +
#"}";
request.AddParameter("application/json", body, ParameterType.RequestBody); `
RestResponse response = client.Execute(request);
var ret = response.Content;
data = ASCIIEncoding.UTF8.GetBytes(ret);
download.binary = data;
}
catch (Exception ex)
{
throw ex; //System.ArgumentException: 'Illegal characters in path. (Parameter 'path')'`
}
}
}
}
return download.binary;
}
Here is my model:
public class Download
{
public byte[] binary { get; set; }
}
I used this method to convert the array to File. Exception: Message =Illegal characters in path. (Parameter 'path')
public static bool ByteArrayToFile(string fileName, byte[] byteArray)
{
try
{
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(byteArray, 0, byteArray.Length);
return true;
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in process: {0}", ex);
}
return false;
}
I also tried decrypting what is returned to me from the API with the following method.
Exception: System.Security.Cryptography.CryptographicException: 'Specified key is not a valid size for this algorithm.
public static void Decrypt(byte[] downloadDoc)
{
if (downloadDoc == null)
throw new ArgumentNullException(nameof(downloadDoc));
else if (downloadDoc.Length == 0)
throw new ArgumentOutOfRangeException(nameof(downloadDoc));
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
formatter.Serialize(ms, downloadDoc);
var rt = Convert.ToBase64String(ms.ToArray());
using (var rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.KeySize = (rt.Length / 8) * 2;
rijndaelManaged.Key = downloadDoc;
rijndaelManaged.BlockSize = (rt.Length / 8) * 2;
using (var decryptor = rijndaelManaged.CreateDecryptor())
using (var cryptoStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
var decrypted = new byte[downloadDoc.Length];
var bytesRead = cryptoStream.Read(decrypted, 0, downloadDoc.Length);
var ret = decrypted.Take(bytesRead).ToArray();
}
}
}

Related

Problem converting Image to Base64 in Blazor Server

So I am trying to convert an image base64 that will be uploaded to SQL Server.
Current code is:
private async Task OnInputFileChange(InputFileChangeEventArgs args)
{
var maxFiles = 1;
var maxSize = 512000000;
var format = "image/jpg";
test = "Something";
test1 = args.FileCount.ToString();
foreach (var file in args.GetMultipleFiles(maxFiles))
{
var image = await file.RequestImageFileAsync(format, 500, 500);
test = image.Size.ToString();
buffer = new byte[image.Size];
await image.OpenReadStream(maxAllowedSize: maxSize).ReadAsync(buffer);
test1 = buffer.ToString();
var imageDataUrl = $"data:{format};base64,{Convert.ToBase64String(buffer)}";
imageDataUrls.Add(imageDataUrl);
imageString = imageDataUrl;
}
}
It begins fine, however only the top portion of image is actually converted and in the string is followed by thousands of repeating "A". Reconstructing the image just shows the top portion of the image. What am I doing wrong?
Currently I had not uploaded and redownloaded the string, it is all local until I can figure out what is wrong. I am using the imageString for the image source. I am using .net 6.0.
Try this. Works for me. Files since 1 MB.
public static byte[] GetBytes(Stream stream)
{
var bytes = new byte[stream.Length];
stream.Seek(0, SeekOrigin.Begin);
stream.ReadAsync(bytes, 0, bytes.Length);
stream.Dispose();
return bytes;
}
private async Task OnInputFileChange(InputFileChangeEventArgs args)
{
string base64String = "";
try
{
var files = args.GetMultipleFiles();
foreach (var file in files)
{
await using MemoryStream fs = new MemoryStream();
await file.OpenReadStream(maxAllowedSize: 1048576).CopyToAsync(fs);
byte[] somBytes = GetBytes(fs);
base64String = Convert.ToBase64String(somBytes, 0, somBytes.Length);
System.Diagnostics.Debug.Print("Imatge 64: " + base64String + Environment.NewLine);
}
}
catch (Exception e)
{
System.Diagnostics.Debug.Print("ERROR: " + e.Message + Environment.NewLine);
}
}

RestSharp, Forge API - Getting error:overlapping ranges on file upload

I am trying to upload a file to a bucket using the forge .NET SDK. It works most of the time but gives an {error: overlapping ranges} occasionally. Here is the code snippet.
private string uploadFileToBucket(Configuration configuration, string bucketKey, string filePath)
{
ObjectsApi objectsApi = new ObjectsApi(configuration);
string fileName = Path.GetFileName(filePath);
string base64EncodedUrn, objectKey;
using (FileStream fileStream = File.Open(filePath, FileMode.Open))
{
long contentLength = fileStream.Length;
string content_range = "bytes 0-" + (contentLength - 1) + "/" + contentLength;
dynamic result = objectsApi.UploadChunk(bucketKey, fileName, (int)fileStream.Length, content_range,
"12313", fileStream);
DynamicJsonResponse dynamicJsonResponse = (DynamicJsonResponse)result;
JObject json = dynamicJsonResponse.ToJson();
JToken urn = json.GetValue("objectId");
string urnStr = urn.ToString();
base64EncodedUrn = ApiClient.encodeToSafeBase64(urnStr);
objectKey = fileName;
}
return base64EncodedUrn;
}
Before uploading, the file content must have to read to the computer memory, otherwise, the FileStream object in your code snippet is empty.
However, I would like to advise you to use PUT buckets/:bucketKey/objects/:objectName instead if you want to upload the whole file in a single chunk only. Here is my test code. Hope it helps~
private static TwoLeggedApi oauth2TwoLegged;
private static dynamic twoLeggedCredentials;
private static Random random = new Random();
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
// Initialize the 2-legged OAuth 2.0 client, and optionally set specific scopes.
private static void initializeOAuth()
{
// You must provide at least one valid scope
Scope[] scopes = new Scope[] { Scope.DataRead, Scope.DataWrite, Scope.BucketCreate, Scope.BucketRead };
oauth2TwoLegged = new TwoLeggedApi();
twoLeggedCredentials = oauth2TwoLegged.Authenticate(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, oAuthConstants.CLIENT_CREDENTIALS, scopes);
objectsApi.Configuration.AccessToken = twoLeggedCredentials.access_token;
}
private static void uploadFileToBucket(string bucketKey, string filePath)
{
Console.WriteLine("*****Start uploading file to the OSS");
string path = filePath;
//File Total size
var info = new System.IO.FileInfo(path);
long fileSize = info.Length;
using (FileStream fileStream = File.Open(filePath, FileMode.Open))
{
string sessionId = RandomString(12);
Console.WriteLine(string.Format("sessionId: {0}", sessionId));
long contentLength = fileSize;
string content_range = "bytes 0-" + (contentLength - 1) + "/" + contentLength;
Console.WriteLine("Uploading range: " + content_range);
byte[] buffer = new byte[contentLength];
MemoryStream memoryStream = new MemoryStream(buffer);
int nb = fileStream.Read(buffer, 0, (int)contentLength);
memoryStream.Write(buffer, 0, nb);
memoryStream.Position = 0;
dynamic response = objectsApi.UploadChunk(bucketKey, info.Name, (int)contentLength, content_range,
sessionId, memoryStream);
Console.WriteLine(response);
}
}
static void Main(string[] args)
{
initializeOAuth();
uploadFileToBucket(BUCKET_KEY, FILE_PATH);
}

Unable to delete some files via System.IO.File in C# console app

I am encrypting some text files. It works fine the file is encypted, however on occasion I get this error when attempting to delete the original unencrypted file:
System.IO.IOException:
The process cannot access the file 'MyFile.TXT' because it is being used by another process. at System.IO.__Error.WinIOError(Int32
errorCode, String maybeFullPath) at System.IO.File.Delete(String
path) at FileEncryption.Program.DeleteFile(String sInputFilename) in
FileEncryption\Program.cs:line 159
This seems to happen on large text files. (50MB+) but not always.
Any idea what I might be doing wrong?
Method to PROCESS the folder of txt files:
private static void BeginFileProcessing(string sSecretKey_)
{
DirectoryInfo di = new DirectoryInfo(_sourcePath);
FileInfo[] files = di.GetFiles(_fileType);
try
{
foreach (FileInfo file in files)
{
string thisFileExt = Path.GetExtension(file.Name);
string thisFileName = Path.GetFileNameWithoutExtension(file.Name);
string encFileName = String.Format("{0}-enc{1}", thisFileName, thisFileExt);
if (_TestingOnly)
{
Console.Write("Source: " + file.Name + " " +
" Encrypted File: " + encFileName + "\n");
}
EncryptFile(file.FullName, _targetPath + encFileName, sSecretKey_);
if (_DeleteOriginal)
{
Console.WriteLine("Deleteing file: " + file.FullName);
DeleteFile(file.FullName);
}
}
}
catch (Exception ex)
{
LogWriter(string.Format("\nError Decrypting file: {0}", ex), true);
}
}
Method to ENCRYPT the files
private static void EncryptFile(string sInputFilename,
string sOutputFilename, string sKey)
{
FileStream fsInput =
new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);
FileStream fsEncrypted =
new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream =
new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);
try
{
byte[] bytearrayinput = System.IO.File.ReadAllBytes(sInputFilename);
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
catch (Exception ex)
{
string error = "";
foreach (DictionaryEntry pair in ex.Data)
{
error += pair.Key + " = " + pair.Value + "\n";
Console.WriteLine(error);
}
LogWriter(error, true);
}
}
Method to DELETE the files
private static void DeleteFile(string sInputFilename)
{
try
{
if (_TestingOnly)
{
Console.WriteLine("TESTING ONLY! File: " + sInputFilename + " would have been deleted.");
}
else
{
File.Delete(sInputFilename);
}
}
catch (Exception ex)
{
Console.Write(ex.ToString());
LogWriter(ex.ToString(), true);
}
}
This may be caused by your files not being closed after the call to EncryptFile. In your original code, if you hit an exception in EncryptFile the streams would be left open if the exception happens before the call to Close. Using Using statements makes this easier but you can also put the Close in a finally block and close the streams if they're not null.
Here's an example using Using:
private static void EncryptFile(string sInputFilename,
string sOutputFilename, string sKey)
{
using(FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read),
FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write))
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
using(CryptoStream cryptostream =
new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write))
{
try
{
byte[] bytearrayinput = System.IO.File.ReadAllBytes(sInputFilename);
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
}
catch (Exception ex)
{
string error = "";
foreach (DictionaryEntry pair in ex.Data)
{
error += pair.Key + " = " + pair.Value + "\n";
Console.WriteLine(error);
}
LogWriter(error, true);
}
}
}
}
Edit
My proposed code will solve the issue of the file stream being left open. However, the root of the issue is that the system throws an OutOfMemoryException while reading the file if it's large. The original code would read all the bytes then read the bytes again into the same buffer, which is a waste of memory and a waste of time. Below is a corrected version:
private static void EncryptFile(string sInputFilename,
string sOutputFilename, string sKey)
{
using(FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read),
fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write))
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
using(CryptoStream cryptostream =
new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write))
{
byte[] buffer = new byte[2048];
int readCount = 0;
try
{
while ((readCount = fsInput.Read(buffer, 0, 2048)) > 0)
{
cryptostream.Write(buffer, 0, readCount);
}
}
catch (Exception ex)
{
string error = "";
foreach (DictionaryEntry pair in ex.Data)
{
error += pair.Key + " = " + pair.Value + "\n";
Console.WriteLine(error);
}
LogWriter(error, true);
}
}
}
}
You should consider using using statements for all objects that implement IDisposable. This will ensure that they are closed and disposed at the end of the using block:
private static void EncryptFile(string sInputFilename, string sOutputFilename,
string sKey)
{
using (var fsInput = new FileStream(sInputFilename, FileMode.Open,
FileAccess.Read))
using (var fsEncrypted = new FileStream(sOutputFilename, FileMode.Create,
FileAccess.Write))
using (var desCryptoProvider = new DESCryptoServiceProvider())
{
desCryptoProvider.Key = Encoding.ASCII.GetBytes(sKey);
desCryptoProvider.IV = Encoding.ASCII.GetBytes(sKey);
using (var encryptor = desCryptoProvider.CreateEncryptor())
using (var cryptoStream = new CryptoStream(fsEncrypted, encryptor,
CryptoStreamMode.Write))
{
try
{
var bytearrayinput = File.ReadAllBytes(sInputFilename);
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptoStream.Write(bytearrayinput, 0, bytearrayinput.Length);
}
catch (Exception ex)
{
var errors = new StringBuilder();
foreach (var pair in ex.Data)
{
errors.AppendLine(string.Format("{0} = {1}", pair.Key, pair.Value));
}
Console.WriteLine(errors.ToString());
LogWriter(errors.ToString(), true);
}
}
}
}
It's not exactly an answer, but may help; a simple method to check if a file is locked:
bool IsFileAvailable(string fileName)
{
FileStream stream = null;
try
{
FileInfo fileInfo = new FileInfo(fileName);
stream = fileInfo.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
// File is not present, or locked by another process
return false;
}
finally
{
if (stream != null)
stream.Close();
}
// File is present and not locked
return true;
}

Sending an Image in Base64 Format over to an IIS server (hosting C#.net based Web Handler)

I am trying to send an Image from my android device over to an IIS server which is hosting a C#.NET based web handler.
The root problem I am facing now is how do I send it in to the server?
I have converted the image into base64 format but the part in which I have to send it in the HTTP's POST object is where I am facing a dilema.
HttpPost httppost = new HttpPost("http://192.168.1.248/imgup/Default.aspx");
File data2send = new File(image_str);
FileEntity fEntity = new FileEntity(data2send, "binary/octet-stream");
httppost.setEntity(fEntity);
//httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
In the above snippet^ The line where I send my base64 string image_str cannot be of File type which is obvious.
So, I need something to convert this base64 string in-order to send it over to the server or better if someone can help me out here thoroughly :D
I tried the namevalue pairs way..it din't worked.
The Image I am sending is of ~3KB.
My full activity code:
public class MainActivity extends Activity {
InputStream inputStream;
private class GetRouteInfo extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params)
{
try
{
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img1);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); //compress to which format you want.
byte [] byte_arr = stream.toByteArray();
String image_str = Base64.encodeBytes(byte_arr);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
System.out.println("image_str: "+image_str);
nameValuePairs.add(new BasicNameValuePair("image",image_str));
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.1.248/imgup/Default.aspx");
//post.addHeader("zipFileName", zipFileName);
//httppost.addHeader("image",image_str);
File data2send = new File();
//File data2send = new File(image_str);
FileEntity fEntity = new FileEntity(data2send, "binary/octet-stream");
httppost.setEntity(fEntity);
//httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String the_string_response = convertResponseToString(response);
//Toast.makeText(MainActivity.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
System.out.println("Response " + the_string_response);
}catch(Exception e){
//Toast.makeText(MainActivity.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
System.out.println("ERROR " + e.getMessage());
System.out.println("Error in http connection "+e.toString());
}
}
catch (Exception e) {
Log.i("SvcMgr", "Service Execution Failed!", e);
}
finally {
Log.i("SvcMgr", "Service Execution Completed...");
}
return null;
}
#Override
protected void onCancelled() {
Log.i("SvcMgr", "Service Execution Cancelled");
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.i("SvcMgr", "Service Execution cycle completed");
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img1);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); //compress to which format you want.
byte [] byte_arr = stream.toByteArray();
String image_str = Base64.encodeBytes(byte_arr);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("image",image_str));
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.1.248/imgup/Default.aspx");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String the_string_response = convertResponseToString(response);
Toast.makeText(MainActivity.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
}catch(Exception e){
Toast.makeText(MainActivity.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
System.out.println("Error in http connection "+e.toString());
}*/
try {
new GetRouteInfo().execute().get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String convertResponseToString(HttpResponse response) throws IllegalStateException, IOException{
String res = "";
StringBuffer buffer = new StringBuffer();
inputStream = response.getEntity().getContent();
int contentLength = (int) response.getEntity().getContentLength(); //getting content length…..
System.out.println("contentLength : " + contentLength);
//Toast.makeText(MainActivity.this, "contentLength : " + contentLength, Toast.LENGTH_LONG).show();
if (contentLength < 0){
}
else{
byte[] data = new byte[512];
int len = 0;
try
{
while (-1 != (len = inputStream.read(data)) )
{
buffer.append(new String(data, 0, len)); //converting to string and appending to stringbuffer…..
}
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
inputStream.close(); // closing the stream…..
}
catch (IOException e)
{
e.printStackTrace();
}
res = buffer.toString(); // converting stringbuffer to string…..
System.out.println("Result : " + res);
//Toast.makeText(MainActivity.this, "Result : " + res, Toast.LENGTH_LONG).show();
//System.out.println("Response => " + EntityUtils.toString(response.getEntity()));
}
return res;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Server Side code (in C#.net):
protected void Page_Load(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(Server.MapPath("~/Data")))
{
}
else
{
System.IO.Directory.CreateDirectory(Server.MapPath("~/Data"));
}
if(Request.InputStream.Length !=0 && Request.InputStream.Length < 32768) {
//Request.ContentType = "binary/octet-stream";
Request.ContentType = "text/plain";
Stream myStream = Request.InputStream;
string fName = Request.Params["image"];
byte[] imageBytes = Convert.FromBase64String(myStream.ToString());
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
string fileName = Server.MapPath("~/Data/").ToString() + "try1" + ".jpeg";
image.Save(fileName);
Request.InputStream.Close();
}
else
{
}
}
One of my favourite piece of code.
Android App upload location
I compress the Image (Re size) it just to be save side (Code at the end)
Bitmap bitmap = resizeBitMapImage1(exsistingFileName, 800, 600);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,30, stream);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("image_data", Base64.encodeBytes(stream.toByteArray())));
// image_str = null;
stream.flush();
stream.close();
bitmap.recycle();
nameValuePairs.add(new BasicNameValuePair("FileName", FileName));
String url = "http://www.xyz.com/upload.aspx";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response1 = httpclient.execute(httppost);
Log.i("DataUploaderOffline_Image ","Status--> Completed");
ASPX Page Code
Response.ContentType = "text/plain";
string c = Request.Form["image_data"];
string FileName = Request.Form["FileName"];
byte[] bytes = Convert.FromBase64String(c);
System.Drawing.Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = System.Drawing.Image.FromStream(ms);
image.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone);
String Fname = FileName + ".jpeg";
image.Save(Server.MapPath("Image\\" + Fname), System.Drawing.Imaging.ImageFormat.Jpeg);
Response.End();
}
*Resize Code *
public static Bitmap resizeBitMapImage1(String filePath, int targetWidth,
int targetHeight) {
Bitmap bitMapImage = null;
try {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
double sampleSize = 0;
Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math
.abs(options.outWidth - targetWidth);
if (options.outHeight * options.outWidth * 2 >= 1638) {
sampleSize = scaleByHeight ? options.outHeight / targetHeight
: options.outWidth / targetWidth;
sampleSize = (int) Math.pow(2d,
Math.floor(Math.log(sampleSize) / Math.log(2d)));
}
options.inJustDecodeBounds = false;
options.inTempStorage = new byte[128];
while (true) {
try {
options.inSampleSize = (int) sampleSize;
bitMapImage = BitmapFactory.decodeFile(filePath, options);
break;
} catch (Exception ex) {
try {
sampleSize = sampleSize * 2;
} catch (Exception ex1) {
}
}
}
} catch (Exception ex) {
}
return bitMapImage;
}
You're not actually setting the name/value pair to the POST. You're merely sending the IMAGE as a base64 string.
Try something like this:
httpClient httpclient;
HttpPost httppost;
ArrayList<NameValuePair> parms;
httpclient = new DefaultHttpClient();
httppost = new HttpPost(Your Url Here);
params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("image", BASE_64_STRING);
httppost.setEntity(new UrlEncodedFormEntity(params);
HttpResponse resp = httpclient.execute(httppost);

HttpRequest.Files is empty when posting file through HttpClient

Server-side:
public HttpResponseMessage Post([FromUri]string machineName)
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0 && !String.IsNullOrEmpty(machineName))
...
Client-side:
public static void PostFile(string url, string filePath)
{
if (String.IsNullOrWhiteSpace(url) || String.IsNullOrWhiteSpace(filePath))
throw new ArgumentNullException();
if (!File.Exists(filePath))
throw new FileNotFoundException();
using (var handler = new HttpClientHandler { Credentials= new NetworkCredential(AppData.UserName, AppData.Password, AppCore.Domain) })
using (var client = new HttpClient(handler))
using (var content = new MultipartFormDataContent())
using (var ms = new MemoryStream(File.ReadAllBytes(filePath)))
{
var fileContent = new StreamContent(ms);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(filePath)
};
content.Add(fileContent);
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
var result = client.PostAsync(url, content).Result;
result.EnsureSuccessStatusCode();
}
}
At the server-side httpRequest.Files collection is always empty. But headers (content-length etc...) are right.
You shouldn't use HttpContext for getting the files in ASP.NET Web API. Take a look at this example written by Microsoft (http://code.msdn.microsoft.com/ASPNET-Web-API-File-Upload-a8c0fb0d/sourcecode?fileId=67087&pathId=565875642).
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
StringBuilder sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
FileInfo fileInfo = new FileInfo(file.LocalFileName);
sb.Append(string.Format("Uploaded file: {0} ({1} bytes)\n", fileInfo.Name, fileInfo.Length));
}
return new HttpResponseMessage()
{
Content = new StringContent(sb.ToString())
};
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
Everything looks good in your code except the content type which should be multipart/form-data. Please try changing your code to reflect the correct content type:
content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
You might want to refer to this post as to why setting the content type to application/octet-stream doesn't make sense from client side.
Try this method :
public void UploadFilesToRemoteUrl()
{
string[] files = { #"your file path" };
string url = "Your url";
long length = 0;
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials =
System.Net.CredentialCache.DefaultCredentials;
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
//string header = string.Format(headerTemplate, "file" + i, files[i]);
string header = string.Format(headerTemplate, "uplTheFile", files[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(files[i], FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
WebResponse webResponse2 = httpWebRequest2.GetResponse();
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
}
In case someone else has the same problem: make sure your boundary string is valid, e.g. don't do this:
using (var content =
new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
{
...
}
This failed for me due to an invalid boundary character, maybe the "/" date separator. At least this solved my problem when accessing Context.Request.Files in a Nancy controller (which was always empty).
Better to use something like DateTime.Now.Ticks.ToString("x") instead.

Categories