QuickBlox Access direct URL of image stored in public blob — Android Content Module - quickblox

I have retrieved the Users Blob id. How do I get the public URL for that blob?
blob= user.getFileId()

You can retrieve file url only if you have blob, not just blob id
Download blob by id:
QBContent.getFile(20223, new QBCallbackImpl() {
#Override
public void onComplete(Result result) {
if (result.isSuccess()) {
QBFileResult fileResult = (QBFileResult) result;
QBFile file = fileResult.getFile();
String fileURL = file.getPublicUrl();
}
}
});
Note:
To get direct access to file you have to upload it with public=true
Boolean fileIsPublic = true;
QBContent.uploadFileTask(file1, fileIsPublic, new QBCallbackImpl() { ...

Related

How to perform POST using .NET Core 6 Minimal API in Azure Blob Storage

I am new to .NET and I have to perform this. Assuming we have the connection string and the Environment variable setup, could someone give me resources or code or guide on how to do it?
I just need to upload a pdf file in Azure Blob Storage using Minimal API
From the Minimal API document, we can see that the Minimal API does not support the binding the IFormFile.
No support for binding from forms. This includes binding IFormFile. We plan to add support for IFormFile in the future.
So, to upload file in the Minimal API, you can get the upload file from the HttpRequest Form. Refer to the following code:
app.MapPost("/upload", (HttpRequest request) =>
{
if (!request.Form.Files.Any())
return Results.BadRequest("At least one fie is need");
//Do something with the file
foreach(var item in request.Form.Files)
{
var file = item;
//insert the file into the Azure storage
}
return Results.Ok();
});
The screenshot as below:
Then, to upload the file to Azure Blob Storage, refer the following tutorial:
Upload images/files to blob azure, via web api ASP.NET framework Web application
Code like this:
CloudStorageAccount storageAccount;
Dictionary<string, object> dict = new Dictionary<string, object>();
string strorageconn = ConfigurationManager.AppSettings.Get("MyBlobStorageConnectionString");
if (CloudStorageAccount.TryParse(strorageconn, out storageAccount))
{
try
{
// Create the CloudBlobClient that represents the
// Blob storage endpoint for the storage account.
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
// Create a container called 'quickstartblobs' and
// append a GUID value to it to make the name unique.
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("images");
await cloudBlobContainer.CreateIfNotExistsAsync();
// Set the permissions so the blobs are public.
BlobContainerPermissions permissions = new BlobContainerPermissions
{
PublicAccess = BlobContainerPublicAccessType.Blob
};
await cloudBlobContainer.SetPermissionsAsync(permissions);
var httpRequest = HttpContext.Current.Request;
foreach (string file in httpRequest.Files)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);
var postedFile = httpRequest.Files[file];
string imageName = ("images" + serverTime.Year.ToString() + serverTime.Month.ToString() + serverTime.Day.ToString() +
serverTime.Hour.ToString() + serverTime.Minute.ToString() + serverTime.Second.ToString() + serverTime.Millisecond.ToString()
+ postedFile.FileName );
if (postedFile != null && postedFile.ContentLength > 0)
{
int MaxContentLength = 1024 * 1024 * 1; //Size = 1 MB
IList<string> AllowedFileExtensions = new List<string> { ".jpg", ".gif", ".png" };
var ext = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf('.'));
var extension = ext.ToLower();
if (!AllowedFileExtensions.Contains(extension))
{
var message = string.Format("Please Upload image of type .jpg,.gif,.png.");
dict.Add("error", message);
return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
}
else if (postedFile.ContentLength > MaxContentLength)
{
var message = string.Format("Please Upload a file upto 1 mb.");
dict.Add("error", message);
return Request.CreateResponse(HttpStatusCode.BadRequest, dict);
}
else
{
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(imageName);
cloudBlockBlob.Properties.ContentType = postedFile.ContentType;
await cloudBlockBlob.UploadFromStreamAsync(postedFile.InputStream);
}
}
var message1 = string.Format("Image Updated Successfully.");
return Request.CreateErrorResponse(HttpStatusCode.Created, message1);
}
var res3 = string.Format("Please Upload a image.");
dict.Add("error", res3);
return Request.CreateResponse(HttpStatusCode.NotFound, dict);
}
catch (Exception ex)
{
HttpResponseMessage response2 = Request.CreateResponse(HttpStatusCode.BadRequest, ex.InnerException.ToString());
return response2;
}
}
else
{
var res = string.Format("Did not connect successfull.");
dict.Add("error", res);
return Request.CreateResponse(HttpStatusCode.NotFound, dict);
}

ASP.NET Core MVC - Image is not getting uploaded in live website directory

I have my ASP.NET Core MVC website on production server of godaddy windows hosting. I have a "Create article" page which allows to select an image from PC and upload it in the project folder directory.
This functionality works fine on local server, but it doesn't work on production server. I have tried to change the upload path of the image multiple times, but none of them works for me. I get an error on production. If I don't upload the image and create article without it, it works fine on the production.
Paths which I have tried :
public static string ArticleImgPath = #"\images\Articles\";
public static string ArticleImgPath = "/images/Articles/";
public static string ArticleImgPath = "https://derawala.org/wwwroot/images/Articles/";
public static string ArticleImgPath = "https://derawala.org/httpdocs/wwwroot/images/Articles/";
public static string ArticleImgPath = "https://derawala.org/images/Articles/";
This is the error I got on production :
If I remove the image uploading code, I don't get any errors and the app works just fine.
I have also made sure to upload appsettings.production.json file to make sure that environment variables are set for production environment. Also, all the other functionalities of website including database operations work properly except those which have file uploading in it.
Here is my controller method for article creation:
public IActionResult ArticlePost(ParentForApply ParentVM)
{
var files = HttpContext.Request.Form.Files;
if (files.Count == 0)
{
ParentVM.ArticleModel.Img ="defltimg.png";
_db.Articles.Add(ParentVM.ArticleModel);
_db.SaveChanges();
return View(ParentVM);
}
else
{
string upload = WC.ArticleImgPath;
string fileName = Guid.NewGuid().ToString();
string extension = Path.GetExtension(files[0].FileName);
string fullpath = upload + fileName + extension;
using (var filestream = new FileStream(fullpath, FileMode.Create))
{
files[0].CopyTo(filestream);
}
ParentVM.ArticleModel.Img = fileName + extension;
_db.Articles.Add(ParentVM.ArticleModel);
_db.SaveChanges();
return View(ParentVM);
}
}
The error indicates you swap to development environment to get detailed errors,not means you are not in production enviroment
Alos,you could read this document related with uploading files:https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-6.0
you could try with the codes in this document to upload file and store the content into database:
public class AppFile
{
public int Id { get; set; }
public byte[] Content { get; set; }
}
in controller:
using (var memoryStream = new MemoryStream())
{
await FileUpload.FormFile.CopyToAsync(memoryStream);
// Upload the file if less than 2 MB
if (memoryStream.Length < 2097152)
{
var file = new AppFile()
{
Content = memoryStream.ToArray()
};
_dbContext.File.Add(file);
await _dbContext.SaveChangesAsync();
}
else
{
ModelState.AddModelError("File", "The file is too large.");
}
Update:
Could you swap to development environment to see the detailed error message?
Have you tried to write the path with WebRootPath?
public IActionResult New([FromServices]IHostingEnvironment env)
{
......
using (var stream = new FileStream(Path.Combine(env.WebRootPath, "...."), FileMode.CreateNew))
.....
}

ASP.NET Core, Azure storage controller

I have a very newbie question.
I am following this docs "Azure Blob storage client library v12 for .NET" - https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet
When I tested on my console, and my Azure storage, it works.
But I was wondering if I can make a controller out of the suggested 'Main' method?
Because I want these getting and posting to the server actions initiated when the user input changes from the front end side.
This is what the Main method inside of the Program.cs looks like based on the docs
static async Task Main()
{
Console.WriteLine("Azure Blob storage v12 - .NET quickstart sample\n");
string connectionString = Environment.GetEnvironmentVariable("My_CONNECTION_STRING");
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
string containerName = "quickstartblobs" + Guid.NewGuid().ToString();
BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName);
string localPath = "./data/";
string fileName = "quickstart" + Guid.NewGuid().ToString() + ".txt";
string localFilePath = Path.Combine(localPath, fileName);
// Write text to the file
await File.WriteAllTextAsync(localFilePath, "Hello, World!");
// Get a reference to a blob
BlobClient blobClient = containerClient.GetBlobClient(fileName);
Console.WriteLine("Uploading to Blob storage as blob:\n\t {0}\n", blobClient.Uri);
// Open the file and upload its data
using FileStream uploadFileStream = File.OpenRead(localFilePath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close();
Console.WriteLine("Listing blobs...");
// List all blobs in the container
await foreach (BlobItem blobItem in containerClient.GetBlobsAsync())
{
Console.WriteLine("\t" + blobItem.Name);
}
Console.Write("Press any key to begin clean up");
Console.ReadLine();
string downloadFilePath = localFilePath.Replace(".txt", "DOWNLOAD.txt");
Console.WriteLine("\nDownloading blob to\n\t{0}\n", downloadFilePath);
// Download the blob's contents and save it to a file
BlobDownloadInfo download = await blobClient.DownloadAsync();
using (FileStream downloadFileStream = File.OpenWrite(downloadFilePath))
{
await download.Content.CopyToAsync(downloadFileStream);
downloadFileStream.Close();
}
}
So for example, in my HomeController Can I use post related functions as
[HttpPost]
public void Post([FromBody]string value)
{
//Create a unique name for the container
string containerName = "filedata" + Guid.NewGuid().ToString();
// Create the container and return a container client object
BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName);
// Create a local file in the ./data/ directory for uploading and downloading
string localPath = "./data/";
string fileName = "textfile" + Guid.NewGuid().ToString() + ".txt";
string localFilePath = Path.Combine(localPath, fileName);
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
// Get a reference to a blob
BlobClient blobClient = containerClient.GetBlobClient(fileName);
Console.WriteLine("Uploading to Blob storage as blob:\n\t {0}\n", blobClient.Uri);
// Open the file and upload its data
using FileStream uploadFileStream = File.OpenRead(localFilePath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close();
}
Or is this a no-go?
Thanks for helping this super newbie!
So for example, in my HomeController Can I use post related functions Or is this a no-go?
Yes, you can achieve it.
You can use postman to send post request in local to test it. Remember to remove SSL for webserver setting.
Also, change public void Post to public async Task Post and remove using in code:
FileStream uploadFileStream = File.OpenRead(localFilePath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close()

Files uploaded but not appearing on server

I use the code stated here to upload files through a webapi http://bartwullems.blogspot.pe/2013/03/web-api-file-upload-set-filename.html. I also made the following api to list all the files I have :
[HttpPost]
[Route("sharepoint/imageBrowser/listFiles")]
[SharePointContextFilter]
public async Task<HttpResponseMessage> Read()
{
string pathImages = HttpContext.Current.Server.MapPath("~/Content/images");
DirectoryInfo d = new DirectoryInfo(pathImages);//Assuming Test is your Folder
FileInfo[] Files = d.GetFiles(); //Getting Text files
List<object> lst = new List<object>();
foreach (FileInfo f in Files)
{
lst.Add(new
{
name = f.Name,
type = "f",
size = f.Length
});
}
return Request.CreateResponse(HttpStatusCode.OK, lst);
}
When calling this api, all the files uploaded are listed. But when I go to azure I dont see any of them (Content.png is a file I manually uploaded to azure)
Why are the files listed if they dont appear on azure.
According to your description, I suggest you could firstly use azure kudu console to locate the right folder in the azure web portal to see the image file.
Open kudu console:
In the kudu click the debug console and locate the site\wwwroot\yourfilefolder
If you find your file is still doesn't upload successfully, I guess there maybe something wrong with your upload codes. I suggest you could try below codes.
Notice: You need add image folder in the wwwort folder.
{
public class UploadingController : 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 = Environment.GetEnvironmentVariable("HOME").ToString() + "\\site\\wwwroot\\images";
//string root = HttpContext.Current.Server.MapPath("~/images");
var provider = new FilenameMultipartFormDataStreamProvider(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);
}
}
}
public class FilenameMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public FilenameMultipartFormDataStreamProvider(string path) : base(path)
{
}
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
{
var name = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? headers.ContentDisposition.FileName : Guid.NewGuid().ToString();
return name.Replace("\"", string.Empty);
}
}
}
Result:

ASP.NET WebApi file upload using guid and file extension

I currently am able to save a file being uploaded to a WebAPI controller, but I'd like to be able to save the file as a guid with the correct file name extension so it can be viewed correctly.
Code:
[ValidationFilter]
public HttpResponseMessage UploadFile([FromUri]string AdditionalInformation)
{
var task = this.Request.Content.ReadAsStreamAsync();
task.Wait();
using (var requestStream = task.Result)
{
try
{
// how can I get the file extension of the content and append this to the file path below?
using (var fileStream = File.Create(HttpContext.Current.Server.MapPath("~/" + Guid.NewGuid().ToString())))
{
requestStream.CopyTo(fileStream);
}
}
catch (IOException)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.Created;
return response;
}
I can't seem to get a handle on the actual filename of the content. I thought headers.ContentDisposition.FileName might be a candidate but that doesn't seem to get populated.
Thanks for the comments above which pointed me in the right direction.
To clarify the final solution, I used a MultipartFormDataStreamProvider which streams the file automatically. The code is in another question I posted to a different problem here:
MultipartFormDataStreamProvider and preserving current HttpContext
My full provider code is listed below. The key to generating the guid file name is to override the GetLocalFileName function and use the headers.ContentDisposition property. The provider handles the streaming of the content to file.
public class MyFormDataStreamProvider : MultipartFormDataStreamProvider
{
public MyFormDataStreamProvider (string path)
: base(path)
{ }
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
// restrict what images can be selected
var extensions = new[] { "png", "gif", "jpg" };
var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
if (filename.IndexOf('.') < 0)
return Stream.Null;
var extension = filename.Split('.').Last();
return extensions.Any(i => i.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
? base.GetStream(parent, headers)
: Stream.Null;
}
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
{
// override the filename which is stored by the provider (by default is bodypart_x)
string oldfileName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
string newFileName = Guid.NewGuid().ToString() + Path.GetExtension(oldfileName);
return newFileName;
}
}