I'm uploading an image as a part of the user model, and I should save the image url to display the image in the REST Client (link like "localhost/Images/ImageName.png"),
so I saved the Image in the wwwroot this in the Post Api:
[HttpPost]
public async Task<String> Post([FromForm]Machine mach)
{
try
{
if (mach.Files.Length > 0)
{
{
FileInfo fi = new FileInfo(mach.Files.FileName);
var newfilename = "Image_" + DateTime.Now.TimeOfDay.Hours + fi.Extension;
var path = Path.Combine(hostingEnvironment.WebRootPath+ "\\Images\\" + newfilename);
/* var path = Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot\Images");*/
using (var stream = new FileStream(path, FileMode.Create))
{
mach.Files.CopyTo(stream);
}
Machine machine = new Machine();
mach.ImagePath = path;
_context.machines.Add(mach);
_context.SaveChangesAsync();
}
return ("saved");
}
I saved the model correctly but I got the url like this:
"imagePath": "C:\Users\amyra\source\repos\MyApi\wwwroot\Images\Image_18.png"
I tried to display the image by "localhost:port/Images/.." but I got page not found.
Check your application's startup and make sure the app.UseStaticFiles(); line is there. Typically it should come after app.UseHttpsRedirection(); and before app.UseAuthorization
The default API template doesn't have this line.
Edit:
To save the URL of the image instead of the physical file path
mach.ImagePath = new UriBuilder
{
Scheme = Request.Scheme,
Host = Request.Host.Host,
Port = Request.Host.Port ?? -1,
Path = "/Images/" + newfilename
}.ToString();
Though I wouldn't recommend saving the host/port/scheme part of the URL in the database as these may be subject to change.
Rather I recommend saving only the Path part
mach.ImagePath = "/Images/" + newfilename;
You can add the host/port/scheme part when serving the data to clients.
I am trying to upload a file onto my Drive using Google Drive .NET API v3. My code is below
static string[] Scopes = { DriveService.Scope.Drive,
DriveService.Scope.DriveAppdata,
DriveService.Scope.DriveFile,
DriveService.Scope.DriveMetadataReadonly,
DriveService.Scope.DriveReadonly,
DriveService.Scope.DriveScripts };
static string ApplicationName = "Drive API .NET Quickstart";
public ActionResult Index()
{
UserCredential credential;
using (var stream =
new FileStream("C:/Users/admin1/Documents/visual studio 2017/Projects/TryGoogleDrive/TryGoogleDrive/client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Debug.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
FilesResource.ListRequest listRequest = service.Files.List();
listRequest.PageSize = 10;
listRequest.Fields = "nextPageToken, files(id, name)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute()
.Files;
Debug.WriteLine("Files:");
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
Debug.WriteLine("{0} ({1})", file.Name, file.Id);
}
}
else
{
Debug.WriteLine("No files found.");
}
var fileMetadata = new Google.Apis.Drive.v3.Data.File()
{
Name = "report.csv",
MimeType = "text/csv",
};
FilesResource.CreateMediaUpload request;
using (var stream = new FileStream("C:/debugging/report.csv",
FileMode.Open))
{
request = service.Files.Create(
fileMetadata, stream, "text/csv");
request.Fields = "id";
request.Upload();
}
var response = request.ResponseBody;
Console.WriteLine("File ID: " + response.Id);
return View();
}
The problem I'm facing is that response is always null. I looked into it a bit further and found that the request returned a 403 resultCode. I also took a look at some other questions on SO this and this but neither were of any help.
Edit: I forgot to mention that the first part of the code is working correctly - it lists all the files in my Drive. Only the second part is not working (the upload file part)
string[] Scopes = { DriveService.Scope.Drive };
Change the Drive scope then delete the file token.json
in vs2017 you can see token.json file in token.json folder when client_secret.json file present.
Try to visit this post from ASP.NET forum.
The same idea as what you want to do in your app, since you are dealing with uploading a file in Google Drive using .net.
You may try to call rest api directly to achieve your requirement :
The quickstart from .net will help you to make requests from/to the Drive API.
Upload Files:
The Drive API allows you to upload file data when create or
updating a File resource.
You can send upload requests in any of the following ways:
Simple upload: uploadType=media. For quick transfer of a small file (5 MB or less). To perform a simple upload, refer to Performing
a Simple Upload.
Multipart upload: uploadType=multipart. For quick transfer of a small file (5 MB or less) and metadata describing the file, all in a
single request. To perform a multipart upload, refer to Performing a
Multipart Upload.
Resumable upload: uploadType=resumable. For more reliable transfer, especially important with large files. Resumable uploads are
a good choice for most applications, since they also work for small
files at the cost of one additional HTTP request per upload. To
perform a resumable upload, refer to Performing a Resumable
Upload.
You may try this code from the documentation on uploading sample file.
var fileMetadata = new File()
{
Name = "photo.jpg"
};
FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream("files/photo.jpg",
System.IO.FileMode.Open))
{
request = driveService.Files.Create(
fileMetadata, stream, "image/jpeg");
request.Fields = "id";
request.Upload();
}
var file = request.ResponseBody;
Console.WriteLine("File ID: " + file.Id);
You may check the errors you may encounter in this documentation.
Have a look at what request.Upload() returns. For me when I was having this issue it returned:
Insufficient Permission Errors [Message[Insufficient Permission] Location[ - ]
I changed my scope from DriveService.Scope.DriveReadonly to DriveService.Scope.Drive and I was in business.
Change static string[] Scopes = { DriveService.Scope.DriveReadonly }; to static string[] Scopes = { DriveService.Scope.Drive };.
After changes, take a look into token.json file and check does it change its scope from DriveReadonly to Drive.
If you are seeing DriveReadonly then delete the token.json file and run the application again.
I am currently uploading a file via the kendo fileuploader to an api controller using ASP.NET core RC-1. I am receiving a periodic error of "object reference not set to instance of object" when attempting to read the stream following opening the stream with IFormFile.OpenReadStream().
My controller is:
[HttpPost]
[Route("api/{domain}/[controller]")]
public async Task<IActionResult> Post([FromRoute]string domain, [FromForm]IFormFile file, [FromForm]WebDocument document)
{
if (ModelState.IsValid)
{
if (file.Length > 0)
{
var userName =
Request.HttpContext.User.Claims
.FirstOrDefault(c => c.Type == ClaimTypesEx.FullName)?
.Value;
var uploadedFileName =
ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
document.Domain = domain;
document.MimeType = file.ContentType;
document.SizeInBytes = file.Length;
document.ChangedBy = userName;
document.FileName = (string.IsNullOrEmpty(document.FileName)) ? uploadedFileName : document.FileName;
try
{
document = await CommandStack.For<WebDocument>()
.AddOrUpdateAsync(document, file.OpenReadStream()).ConfigureAwait(false);
}
catch (Exception e)
{
return new HttpStatusCodeResult(500);
}
return Ok(document);
}
}
return new BadRequestResult();
}
And the error is being thrown when I actually try to read the stream when it is going into blob storage:
public async Task<Uri> CreateOrUpdateBlobAsync(string containerName, string fileName, string mimeType,
Stream fileStream)
{
var container = Client.GetContainerReference(containerName);
var blob = container.GetBlockBlobReference(fileName);
//Error HERE
await blob.UploadFromStreamAsync(fileStream);
blob.Properties.ContentType = mimeType;
await blob.SetPropertiesAsync();
return blob.Uri;
}
What I am having trouble with is this is sporadic and there seems to be no defined pattern of which files are accepted and which ones generate the error. At first I thought it might be a size issue but that is not the case as I have several larger files uploaded successfully and then one small file will throw the error. Images seem to work fine and it is hit or miss on other file types with no rhyme or reason that I can figure out.
I have problem with streaming video file in my controller to eg. VLC or HTML5 video
My code
public IActionResult VideoStreamContent()
{
var path = #"C:\video1.mp4";
var stream = System.IO.File.OpenRead(path);
return new FileStreamResult(stream, "application/octet-stream");
}
Browser can download that file from this controller but when i want make it in VLC then VLC cannot open that stream
You should try getting the proper mime type for your file before sending it down. That way clients can know how to handle the file type.
public IActionResult VideoStreamContent() {
var path = #"C:\video1.mp4";
var stream = System.IO.File.OpenRead(path);
var mimeType = GetMimeType(path);
return new FileStreamResult(stream, mimeType??"application/octet-stream");
}
string GetMimeType(string fileName) {
//Insert code here to get mime type of file
}
There are many questions/answers on SO about how to get the mime types if you look for it.
I've got a working website that I can upload and download files to a folder within the project locally. However when I use IIS to host the website across LAN, I get a 404 error when trying to download files - I can upload the files fine and they appear in the correct folder.
Error:
HTTP Error 404.0 - Not Found The resource you are looking for has been
removed, had its name changed, or is temporarily unavailable.
Here are my controllers.
Download controller:
[HttpGet]
public virtual ActionResult Download(string file)
{
string fullPath = Path.Combine(Server.MapPath("~/SupportAttachments/"), file);
return File(fullPath, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", file);
}
Upload Controller:
[HttpPost]
public JsonResult UploadFiles(string id)
{
try
{
foreach (string file in Request.Files)
{
var hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
continue;
var fileContent = Request.Files[file];
if (fileContent != null && fileContent.ContentLength > 0)
{
// get a stream
var stream = fileContent.InputStream;
// and optionally write the file to disk
var fileName = id + " " + hpf.FileName;
var path = Path.Combine(Server.MapPath("~/SupportAttachments/"), Path.GetFileName(fileName));
// Save the file
hpf.SaveAs(path);
}
}
}
catch (Exception)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return this.Json("Upload failed");
}
return this.Json("File uploaded successfully");
}
Can anyone advise me as to why I can't download files when hosting via IIS?