I am trying to write an action to upload a file and when I try to call GetFileName() method I get this error:
'IFormFile' does not contain a definition for 'GetFileName' and no accessible extension method 'GetFileName' accepting a first argument of type 'IFormFile' could be found (are you missing a using directive or an assembly reference?)
my controller uses the following namespaces:
using Microsoft.Extensions.FileProviders;
using System.IO;
using Microsoft.AspNetCore.Http;
and the action is:
[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile file)
{
if (file == null || file.Length == 0)
return Content("file not selected");
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot", file.GetFileName());
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return RedirectToAction("Files");
}
To get the filename of the uploaded file using IFormFile we can get it using file.FileName.
Try this:
[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile file)
{
if (file == null || file.Length == 0)
return Content("file not selected");
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot", file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return RedirectToAction("Files");
}
Related
Whenever I upload a file I want to have it automatically converted into .pdf (I am doing that using NuGet). The thing is the upload scheme is done using relative paths. I do not know what to put into these parentheses:
var wordDocument = appWord.Documents.Open(uploadedFile);
What should I replace uploadedFile with in order to work? I will leave my relative path mapping code below:
public IActionResult Index1()
{
// Get files from the server
var model = new FilesViewModel();
foreach (var item in Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "upload")))
{
model.Files.Add(
new FileDetails { Name = System.IO.Path.GetFileName(item), Path = item });
}
return View(model);
}
[HttpPost]
public IActionResult Index1(IFormFile[] files)
{
// Iterate each files
foreach (var file in files)
{
// Get the file name from the browser
var fileName = System.IO.Path.GetFileName(file.FileName);
// Get file path to be uploaded
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "upload", fileName);
// Check If file with same name exists and delete it
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
// Create a new local file and copy contents of uploaded file
using (var localFile = System.IO.File.OpenWrite(filePath))
using (var uploadedFile = file.OpenReadStream())
{
var appWord = new Application();
if (appWord.Documents != null)
{
//yourDoc is your word document
var wordDocument = appWord.Documents.Open(uploadedFile);
string pdfDocName = "pdfDocument.pdf";
if (wordDocument != null)
{
wordDocument.ExportAsFixedFormat(pdfDocName,
WdExportFormat.wdExportFormatPDF);
wordDocument.Close();
}
appWord.Quit();
}
uploadedFile.CopyTo(localFile);
}
}
ViewBag.Message = "Files are successfully uploaded";
// Get files from the server
var model = new FilesViewModel();
foreach (var item in Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "upload")))
{
model.Files.Add(
new FileDetails { Name = System.IO.Path.GetFileName(item), Path = item });
}
return View(model);
}
public async Task<IActionResult> Download(string filename)
{
if (filename == null)
return Content("filename is not availble");
var path = Path.Combine(Directory.GetCurrentDirectory(), "upload", filename);
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
private string GetContentType(string path)
{
var types = GetMimeTypes();
var ext = Path.GetExtension(path).ToLowerInvariant();
return types[ext];
}
private Dictionary<string, string> GetMimeTypes()
{
return new Dictionary<string, string>
{
{".txt", "text/plain"},
{".pdf", "application/pdf"},
{".doc", "application/vnd.ms-word"},
{".docx", "application/vnd.ms-word"},
{".xls", "application/vnd.ms-excel"},
{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"},
{".csv", "text/csv"}
};
}
I want to create an extension method of #Html.Action But Showing Error for IActionSelectorDecisionTreeProvider could not load namespace
var actionSelector = GetServiceOrFail<IActionSelectorDecisionTreeProvider>(currentHttpContext);
Error Screen Short
I have installed all dependencies of dot.net 5 like
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Routing;
But No Luck.
Working Code In Dot Net 5
public static class HtmlHelperViewExtensions
{
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, object parameters = null)
{
var controller = (string)helper.ViewContext.RouteData.Values["controller"];
return RenderAction(helper, action, controller, parameters);
}
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, object parameters = null)
{
var area = (string)helper.ViewContext.RouteData.Values["area"];
return RenderAction(helper, action, controller, area, parameters);
}
public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
{
if (action == null)
throw new ArgumentNullException("action");
if (controller == null)
throw new ArgumentNullException("controller");
//if (area == null)
// throw new ArgumentNullException("area");
var task = RenderActionAsync(helper, action, controller, area, parameters);
return task.Result;
}
private static async Task<IHtmlContent> RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
{
// fetching required services for invocation
var currentHttpContext = helper.ViewContext?.HttpContext;
var httpContextFactory = GetServiceOrFail<IHttpContextFactory>(currentHttpContext);
var actionInvokerFactory = GetServiceOrFail<IActionInvokerFactory>(currentHttpContext);
var actionSelector = GetServiceOrFail<IActionDescriptorCollectionProvider>(currentHttpContext);
// creating new action invocation context
var routeData = new RouteData();
var routeParams = new RouteValueDictionary(parameters ?? new { });
var routeValues = new RouteValueDictionary(new { area = area, controller = controller, action = action });
var newHttpContext = httpContextFactory.Create(currentHttpContext.Features);
newHttpContext.Response.Body = new MemoryStream();
foreach (var router in helper.ViewContext.RouteData.Routers)
routeData.PushState(router, null, null);
routeData.PushState(null, routeValues, null);
routeData.PushState(null, routeParams, null);
var actionDescriptor = actionSelector.ActionDescriptors.Items.Where(i => i.RouteValues["controller"] == controller && i.RouteValues["action"] == action).First();
var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);
// invoke action and retreive the response body
var invoker = actionInvokerFactory.CreateInvoker(actionContext);
string content = null;
await invoker.InvokeAsync().ContinueWith(task => {
if (task.IsFaulted)
{
content = task.Exception.Message;
}
else if (task.IsCompleted)
{
newHttpContext.Response.Body.Position = 0;
using (var reader = new StreamReader(newHttpContext.Response.Body))
content = reader.ReadToEnd();
}
});
return new HtmlString(content);
}
private static TService GetServiceOrFail<TService>(HttpContext httpContext)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
var service = httpContext.RequestServices.GetService(typeof(TService));
if (service == null)
throw new InvalidOperationException($"Could not locate service: {nameof(TService)}");
return (TService)service;
}
}
I want fill form which have upload profile image and other controls like Name,address
I am using angular 8 for client side and asp.net core for backend..
I want viewmodel which contains all properties.
I have used angular8 for uploading image in formdata.I have gone through https://www.techiediaries.com/angular-formdata/.My main question is how to receive uploaded file in ViewModel not in httpRequest.Form.Files["ImageFile"]
[HttpPost("Create")]
public IActionResult CreateApplication(ApplicationModel model)
{
//want to capture uploaded image
return Ok();
}
See this tutorial, can be very helpful: Click
Here is way how i`d do it:
[HttpPost]
public async Task<IActionResult> AddBodyType([FromForm]ApplicationModel model)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest();
}
else
{
var file = Request.Form.Files[0];
var folderName = Path.Combine("Resources", "Images");
var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);
if (file.Length > 0)
{
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
var fullPath = Path.Combine(pathToSave, fileName);
var dbPath = Path.Combine(folderName, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
await stream.FlushAsync();
}
model.ImagePath = dbPath;
await _context.Add(model);
return Ok();
}
else
{
return BadRequest();
}
}
}
catch (Exception ex)
{
return StatusCode(500, $"Internal server error: {ex}");
}
}
Ok got it, the problem was that the directory names were not fixed, they were created by the newly created Id of the product, so the solution was to carry out a check for the directory and if it's not there, create it.
For example
if (!Directory.Exists(folderName))
{
Directory.CreateDirectory(folderName);
}
Once it's created with the new Id it can be used/found.
I am passing Json Data from Angular JS Controller. The Json Data contains two strings called name attribute and comment attribute and a list of files. The controller code for angular is given below:
app.controller("demoController", function ($scope, $http) {
//1. Used to list all selected files
$scope.files = [];
//2. a simple model that want to pass to Web API along with selected files
$scope.jsonData = {
name: "Sibnz",
comments: "This is a comment"
};
//3. listen for the file selected event which is raised from directive
$scope.$on("seletedFile", function (event, args) {
$scope.$apply(function () {
//add the file object to the scope's files collection
$scope.files.push(args.file);
});
});
//4. Post data and selected files.
$scope.save = function () {
$http({
method: 'POST',
url: "http://localhost:51739/PostFileWithData",
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append("model", angular.toJson(data.model));
for (var i = 0; i < data.files.length; i++) {
formData.append("file" + i, data.files[i]);
}
return formData;
},
data: { model: $scope.jsonData, files: $scope.files }
}).
success(function (data, status, headers, config) {
alert("success!");
}).
error(function (data, status, headers, config) {
alert("failed!");
});
};
});
In the Web API, controller I am receiving the JSON data by using the following code:
[HttpPost]
[Route("PostFileWithData")]
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploadfiles");
Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
var result = await Request.Content.ReadAsMultipartAsync(provider);
var model = result.FormData["jsonData"];
var g = result.FileData;
if (model == null)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
//TODO: Do something with the JSON data.
//get the posted files
foreach (var file in result.FileData)
{
//TODO: Do something with uploaded file.
var f = file;
}
return Request.CreateResponse(HttpStatusCode.OK, "success!");
}
When I debug the code, I find that the JSON data is populating the var model and var g variables. I want to extract the name and comment attributes from the Json Data and store them in the Database. And also want to copy the file into /App_Data/Uploadfiles directory and store the file location in the database.
You need to create a model in your Web API and deserialize JSON data to this model, you can use Newtonsoft.Json NuGet package for that
Install-Package Newtonsoft.Json
class DataModel
{
public string name { get; set; }
public string comments { get; set; }
}
In Web API controller
using Newtonsoft.Json;
HttpRequest request = HttpContext.Current.Request;
var model = JsonConvert.DeserializeObject<DataModel>(request.Form["jsonData"]);
// work with JSON data
model.name
model.comments
To work with files
// Get the posted files
if (request.Files.Count > 0)
{
for (int i = 0; i < request.Files.Count; i++)
{
Stream fileStream = request.Files[i].InputStream;
Byte[] fileBytes = new Byte[stampStream.Length];
// Do something with uploaded file
var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploadfiles/");
string fileName = "image.jpg";
File.WriteAllBytes(root + fileName, stampBytes);
// Save only file name to your database
}
}
I have created a blog with ASP.NET MVC 4.
The problem is when my url is not localhost I cannot see any pictures inside my Posts, because they get wrong url. The url of the post can be:
1.localhost/post/2015/4/name_of_post or
2.localhost/archive/name_of_post or
3.localhost/name_of_category/name_of_post ,
and inside the post is the picture.
The picture must have this
url:localhost/App_Files/Upload/name_of_image.jpg
but gets instead this
url:localhost/post/2015/4/App_Files/Upload/name_of_image.jpg or
localhost/archive/name_of_post or
localhost/name_of_category/App_Files/Upload/name_of_image.jpg.
If you use the right url you will see the picture in browser.
I use tinymce to add pictures inside the the post when i create it. The picture is saved as file in the App_Files/Upload folder. The post is inserted in a row as html in sql database. I use this routeConfig
routes.MapRoute(
"Post",
"Archive/{year}/{month}/{title}",
new { controller = "Blog", action = "Post" }
);
and the uploadController is this:
using HotNews.ViewModels;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace HotNews.Controllers
{
public class UploadController : Controller
{
//
// GET: /Upload/
public ActionResult Index(string id)
{
//var url = HttpRuntime.AppDomainAppVirtualPath;
var url = ConfigurationManager.AppSettings["BlogUrl"];
return View(new UploadViewModel
{
baseUrl = url,
track = id
});
}
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Files/Upload"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
public ActionResult ListFiles()
{
var fileData = new List<ViewDataUploadFileResults>();
DirectoryInfo dir = new DirectoryInfo(Server.MapPath("~/App_Files/Upload"));
if (dir.Exists)
{
string[] extensions = MimeTypes.ImageMimeTypes.Keys.ToArray();
FileInfo[] files = dir.EnumerateFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
if (files.Length > 0)
{
foreach (FileInfo file in files)
{
// var baseurl = ConfigurationManager.AppSettings["BlogUrl"];
var relativePath = VirtualPathUtility.ToAbsolute("~/App_Files/Upload") + "/" + file.Name;
fileData.Add(new ViewDataUploadFileResults()
{
// url = baseurl+relativePath,
url = relativePath,
name = file.Name,
type = MimeTypes.ImageMimeTypes[file.Extension],
size = Convert.ToInt32(file.Length)
});
}
}
}
return Json(fileData, JsonRequestBehavior.AllowGet);
}
}
}
Must I create an image hanndler?? Must I create a new routeconfig?? And what kind??