Can upload image using ASP.NET WEB API but not when deployed - asp.net-web-api

I am using ASP.NET WEB API to upload image to server. But when i upload the source code of my web api to gearhost.com and make a post request. I am unable to post the image. This is my web api controller code:
[Route("upload")]
[HttpPost]
public async Task<string> Upload()
{
var ctx = HttpContext.Current;
var root = ctx.Server.MapPath("/uploads/");
var provider = new MultipartFormDataStreamProvider(root);
try
{
await Request.Content
.ReadAsMultipartAsync(provider);
foreach (var file in provider.FileData)
{
var name = file.Headers
.ContentDisposition
.FileName;
// remove double quotes from string.
name = name.Trim('"');
var localFileName = file.LocalFileName;
var filePath = Path.Combine(root, "files", name);
// File.Move(localFileName, filePath);
// SaveFilePathSQLServerADO(localFileName, filePath);
// SaveFileBinarySQLServerADO(localFileName, name);
// SaveFilePathSQLServerEF(localFileName, filePath);
SaveFileBinarySQLServerEF(localFileName, name, filePath);
if (File.Exists(localFileName))
File.Delete(localFileName);
}
}
catch
{
return "Error";
}
return "File uploaded successfully!";
}
public void SaveFileBinarySQLServerEF(string localFile, string fileName, string filePath)
{
// 1) Get file binary
byte[] fileBytes;
using (var fs = new FileStream(localFile, FileMode.Open, FileAccess.Read))
{
fileBytes = new byte[fs.Length];
fs.Read(fileBytes, 0, Convert.ToInt32(fs.Length));
}
// 2) Create a Files object
var file = new tblimage()
{
Data = fileBytes,
Names = fileName,
ContentType = filePath
};
// 3) Add and save it in database
using (var ctx = new coachEntities())
{
ctx.tblimages.Add(file);
ctx.SaveChanges();
}
}
Here is the successful call from localhost:
Image posted through localhost
However when deployed the same code and make request through postman then I get this error:
Image posted through live server

Maybe, "uploads" doesn't have write permission
Check the permission in your uploads folder.
Go to properties-- security
Give the read write permission.

Though it is not good idea to return the exception details in live code. As you are not maintaining log. For testing, Please return the exception details. Also, how are you getting the response like "unable to upload, try again" because it is not there in your code

Related

Download and open picture from url/http [Android Xamarin App]

Hello, would any of you send a working code to download a photo from a given http address on android Xamarin c #?
First, I need to create a new folder for my application files.
My goal is to download the file from the internet to my Android folder (saving this file with its original name is best).
The next step is to display the image from that folder in "ImageView". It is also important that there are permissions in android and I do not fully understand it.
Could any of you send it to me or help me understand it and explain the topic?
*Actually i have this code:
string address = "https://i.stack.imgur.com/X3V3w.png";
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted;
webClient.DownloadFile(address, Path.Combine(pathDire, "MyNewImage1.png"));
//System.Net.WebException: 'An exception occurred during a WebClient request.'
}
Loading image from url and display in imageview.
private void Btn1_Click(object sender, System.EventArgs e)
{
var imageBitmap = GetImageBitmapFromUrl("http://xamarin.com/resources/design/home/devices.png");
imagen.SetImageBitmap(imageBitmap);
}
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
SavePicture("ImageName.jpg", imageBytes, "imagesFolder");
imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
return imageBitmap;
}
download image and save it in local storage.
private void SavePicture(string name, byte[] data, string location = "temp")
{
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
documentsPath = System.IO.Path.Combine(documentsPath, "Orders", location);
Directory.CreateDirectory(documentsPath);
string filePath = System.IO.Path.Combine(documentsPath, name);
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
int length = data.Length;
fs.Write(data, 0, length);
}
}
you need to add permission WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE in AndroidMainfeast.xml, then you also need to Runtime Permission Checks in Android 6.0.
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the writeexternalstorage.
}
else
{
// writeexternalstorage permission is not granted. If necessary display rationale & request.
}
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the ReadExternalStorage.
}
else
{
// ReadExternalStorage permission is not granted. If necessary display rationale & request.
}
}

authorization required when create pdf file

I am trying to generate pdf file using c# web api using the following code :
i have tried to change in the web.config but it didn't help.
[HttpGet]
public HttpResponseMessage Generate()
{
var stream = new MemoryStream();
// processing the stream.
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream.ToArray())
};
result.Content.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "CertificationCard.pdf"
};
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
I expected download pdf directly to my local disk but non worked.

Why base64 image is big ? xamarin forms

I am facing one error sometimes, when I try get a picture from user gallery.
I get the picture in a Stream object, convert it to a base64 and I send it using a post function.
Sometimes The program says that the image path is big and, because of that, its not possible send the url.
I heard that its cause the image size but I am not sure about it...
Does someone know what really causes a Big base64 string? How can I solve that?
You could follow something similar to this:
http://jamessdixon.wordpress.com/2013/10/01/handling-images-in-webapi/
Maybe you need make some change in your web api like this:
[HttpPost]
public HttpResponseMessage UploadImage(int ID)
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
Request.Content.LoadIntoBufferAsync().Wait();
Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
{
MultipartMemoryStreamProvider provider = task.Result;
foreach (HttpContent content in provider.Contents)
{
Stream stream = content.ReadAsStreamAsync().Result;
Image image = Image.FromStream(stream);
var testName = content.Headers.ContentDisposition.Name;
String filePath = HostingEnvironment.MapPath("~/Content/");
String fullPath = Path.Combine(filePath, ID.ToString()+".jpg");
image.Save(fullPath);
}
});
return result;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}
After making sure your api web works well you should change from Stream to byte[]
In your Xamarin code try this:
public async Task PostItem(String Controller, String Method, int ID, byte[] item)
{
using (var client = CreateClient ()) {
var da = new ByteArrayContent(item);
try{
var multi = new MultipartContent();
multi.Add(da);
var response = await client.PostAsync (Controller + "/" +Method + "/?ID=" +ID, multi);
}catch(Exception ex)
{
Console.Write(ex.Message);
}
}
}
For more infomation see MultipartContent class documentation

Error "Must set UnitOfWorkManager before use it"

I'm developing the service within ASP.NET Boilerplate engine and getting the error from the subject. The nature of the error is not clear, as I inheriting from ApplicationService, as documentation suggests. The code:
namespace MyAbilities.Api.Blob
{
public class BlobService : ApplicationService, IBlobService
{
public readonly IRepository<UserMedia, int> _blobRepository;
public BlobService(IRepository<UserMedia, int> blobRepository)
{
_blobRepository = blobRepository;
}
public async Task<List<BlobDto>> UploadBlobs(HttpContent httpContent)
{
var blobUploadProvider = new BlobStorageUploadProvider();
var list = await httpContent.ReadAsMultipartAsync(blobUploadProvider)
.ContinueWith(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
if (task.Exception != null) throw task.Exception;
}
var provider = task.Result;
return provider.Uploads.ToList();
});
// store blob info in the database
foreach (var blobDto in list)
{
SaveBlobData(blobDto);
}
return list;
}
public void SaveBlobData(BlobDto blobData)
{
UserMedia um = blobData.MapTo<UserMedia>();
_blobRepository.InsertOrUpdateAndGetId(um);
CurrentUnitOfWork.SaveChanges();
}
public async Task<BlobDto> DownloadBlob(int blobId)
{
// TODO: Implement this helper method. It should retrieve blob info
// from the database, based on the blobId. The record should contain the
// blobName, which should be returned as the result of this helper method.
var blobName = GetBlobName(blobId);
if (!String.IsNullOrEmpty(blobName))
{
var container = BlobHelper.GetBlobContainer();
var blob = container.GetBlockBlobReference(blobName);
// Download the blob into a memory stream. Notice that we're not putting the memory
// stream in a using statement. This is because we need the stream to be open for the
// API controller in order for the file to actually be downloadable. The closing and
// disposing of the stream is handled by the Web API framework.
var ms = new MemoryStream();
await blob.DownloadToStreamAsync(ms);
// Strip off any folder structure so the file name is just the file name
var lastPos = blob.Name.LastIndexOf('/');
var fileName = blob.Name.Substring(lastPos + 1, blob.Name.Length - lastPos - 1);
// Build and return the download model with the blob stream and its relevant info
var download = new BlobDto
{
FileName = fileName,
FileUrl = Convert.ToString(blob.Uri),
FileSizeInBytes = blob.Properties.Length,
ContentType = blob.Properties.ContentType
};
return download;
}
// Otherwise
return null;
}
//Retrieve blob info from the database
private string GetBlobName(int blobId)
{
throw new NotImplementedException();
}
}
}
The error appears even before the app flow jumps to 'SaveBlobData' method. Am I missed something?
Hate to answer my own questions, but here it is... after a while, I found out that if UnitOfWorkManager is not available for some reason, I can instantiate it in the code, by initializing IUnitOfWorkManager in the constructor. Then, you can simply use the following construction in your Save method:
using (var unitOfWork = _unitOfWorkManager.Begin())
{
//Save logic...
unitOfWork.Complete();
}

Change Content Type for files in Azure Storage Blob

I use only Microsoft Azure Storage and no other Azure products/services. I upload files to my storage blob via ftp type client (GoodSync), and I need to change the content type of all the files based on their file extension after they are already in the Blob. I have looked around and have not found out how to do this without having one of their VPS with PowerShell. What are my options and how do I accomplish this? I really need step by step here.
I recently had the same issue so I created a simple utility class in order to "fix" content type based on file's extension. You can read details here
What you need to do is parse each file in your Azure Storage Containers and update ContentType based on a dictionary that defines which MIME type is appropriate for each file extension.
// Connect to your storage account
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);
// Load Container with the specified name
private CloudBlobContainer GetCloudBlobContainer(string name)
{
CloudBlobClient cloudBlobClient = _storageAccount.CreateCloudBlobClient();
return cloudBlobClient.GetContainerReference(name.ToLowerInvariant());
}
// Parse all files in your container and apply proper ContentType
private void ResetContainer(CloudBlobContainer container)
{
if (!container.Exists()) return;
Trace.WriteLine($"Ready to parse {container.Name} container");
Trace.WriteLine("------------------------------------------------");
var blobs = container.ListBlobs().ToList();
var total = blobs.Count;
var counter = 1;
foreach (var blob in blobs)
{
if (blob is CloudBlobDirectory) continue;
var cloudBlob = (CloudBlob)blob;
var extension = Path.GetExtension(cloudBlob.Uri.AbsoluteUri);
string contentType;
_contentTypes.TryGetValue(extension, out contentType);
if (string.IsNullOrEmpty(contentType)) continue;
Trace.Write($"{counter++} of {total} : {cloudBlob.Name}");
if (cloudBlob.Properties.ContentType == contentType)
{
Trace.WriteLine($" ({cloudBlob.Properties.ContentType}) (skipped)");
continue;
}
cloudBlob.Properties.ContentType = contentType;
cloudBlob.SetProperties();
Trace.WriteLine($" ({cloudBlob.Properties.ContentType}) (reset)");
}
}
_contentTypes is a dictionary that contains the appropriate MIME type for each file extension:
private readonly Dictionary _contentTypes = new Dictionary()
{
{".jpeg", "image/jpeg"},
{".jpg", "image/jpeg" }
};
Full list of content types and source code can be found here.
Here you are a refreshed version for latest Azure.Storage.Blobs SDK. I'm using .Net 5 and console app.
using Azure.Storage.Blobs.Models;
using System;
using System.Collections.Generic;
using System.IO;
var contentTypes = new Dictionary<string, string>()
{
{".woff", "font/woff"},
{".woff2", "font/woff2" }
};
var cloudBlobClient = new BlobServiceClient("connectionstring");
var cloudBlobContainerClient = cloudBlobClient.GetBlobContainerClient("fonts");
await cloudBlobContainerClient.CreateIfNotExistsAsync();
var blobs = cloudBlobContainerClient.GetBlobsAsync();
await foreach (var blob in blobs)
{
var extension = Path.GetExtension(blob.Name);
contentTypes.TryGetValue(extension, out var contentType);
if (string.IsNullOrEmpty(contentType)) continue;
if (blob.Properties.ContentType == contentType)
{
continue;
}
try
{
// Get the existing properties
var blobClient = cloudBlobContainerClient.GetBlobClient(blob.Name);
var properties = await blobClient.GetPropertiesAsync();
var headers = new BlobHttpHeaders
{
ContentType = contentType,
CacheControl = properties.CacheControl,
ContentDisposition = properties.ContentDisposition,
ContentEncoding = properties.ContentEncoding,
ContentHash = properties.ContentHash,
ContentLanguage = properties.ContentLanguage
};
// Set the blob's properties.
await blobClient.SetHttpHeadersAsync(headers);
}
catch (RequestFailedException e)
{
Console.WriteLine($"HTTP error code {e.Status}: {e.ErrorCode}");
Console.WriteLine(e.Message);
Console.ReadLine();
}
}

Resources