简体   繁体   中英

Path.GetFullPath — Return only the last folder, file name and extension

I am trying to get the path for files within the web app, but it returns the path within my computer.

I am using mvc 5 and ef 6, basically users can upload pictures, all uploaded pictures goes into ~/Upload_Files/"username of current user"/

The upload method will get the username of the current user and if if that folder exist, if not it creates one and upload all pics into that folder.

The main action method is to display all pictures within /Upload_Files folder included the ones inside sub folders.

This is within that action method:

var imagesModel = new ImageGallery();
var imageFiles = Directory.GetFiles(
    Server.MapPath("~/Upload_Files/"), "*.*", SearchOption.AllDirectories);

foreach (var item in imageFiles)
{
    // imagesModel.ImageList.Add(Path.GetFileName(item));
    imagesModel.ImageList.Add(Path.GetFullPath(item));
}
return View(imagesModel);`

Inside cshtml to display the pictures

<img src="@Url.Content(image)" width="150" height="150"/>

If I use GetFullPath, it will return the location within my computer so pictures wont show.

I tried it with GetFileName and create the rest of the string as ("~/Upload_Files" + item) which would work if the pictures are stored only within Upload_Files folder and not in sub folders. Also tried user ("~/Upload_Files/" + User.Identity etc + "/" + item) and so on. Anyone could give me an idea on this please? Just started mvc recently.

Also my main goals are to display all images within sub folders, if user click on picture it will pull up all pictures only for that user (which is just to reference his/her username somehow) and lastly to allow users to delete their own pictures. Any more convenient way of doing it?

Any help much appreciated!

New Method

Upload Image Method

if (Request.Files.Count != 0)
        {
            for (int i = 0; i < Request.Files.Count; i++)
            {
                HttpPostedFileBase file = Request.Files[i];
                int fileSize = file.ContentLength;
                string fileName = file.FileName;
                string user = User.Identity.GetUserName();
                string path = Server.MapPath("~/Upload_Files/" + user + "/");
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                file.SaveAs(Server.MapPath("~/Upload_Files/" + user + "/" + fileName));
                ImageGallery imageGallery = new ImageGallery();
                imageGallery.ID = Guid.NewGuid();
                imageGallery.Name = fileName;
                imageGallery.ImagePath = "~/Upload_Files/" + user + fileName;
                imageGallery.UserId = user;
                db.ImageGallery.Add(imageGallery);
                db.SaveChanges();
            }
            return Content("Success");
        }
        return Content("failed");

Index action method

public ActionResult Indexnew()
    {
        var imagesModel = new ImageGallery
        {
            ImagePath = Datalayer.GetImagePaths()
        };
        return View("Indexnew", imagesModel);
    }

ImageGallery class

public class ImageGallery
{
    public ImageGallery()
    {
        ImageList = new List<string>();
    }
    [Key]
    public Guid ID { get; set; }
    public string UserId { get; set; }
    public string Name { get; set; }
    public IEnumerable<string> ImagePath { get; set; }
    public List<string> ImageList { get; set; }

}

Indexnew View

@model MM5.Models.ImageGallery
@foreach (var image in Model)
            {
                <p>@image</p>
                <a id="ShowImage" title="Photo" href="@Url.Action("Details","ImageGallery", User.Identity.Name)">

                    @*<img src="@Url.Content("~/Upload_Files/" + image. + "/" + image)" width="150" height="150" />*@
                    <img src="@Url.Content(image)" width="150" height="150" />

                </a>
            }

I think my view is completely wrong.

If you need to map images which are in target directory or it's sub-directories, then I would suggest this:

public string ReverseMapPath(string path)
{
    string appPath = Server.MapPath("~");
    return string.Format("~{0}", path.Replace(appPath, "").Replace("\\", "/"));
}

...

imagesModel.ImageList.Add(ReverseMapPath(item));

Basically, the ReverseMapPath function translates given file system path into application virtual path. For example:

D:\\Web\\MyApp\\Upload_Files\\User123\\Holiday\\Italy.jpg

is translated into

~/Upload_Files/User123/Holiday/Italy.jpg

Just wondering why such function does not already exist inside framework.

I would suggest not calling methods from inside your view. You can get path mapping however by using

var path = Server.MapPath("~/Upload_Files");

You should pass a ViewModel to your view with all of the paths of your images

You should have a relative mapping, or have setup a virtual directory hosted on IIS, and then take the relative paths and append them. You should store your image directory in your

Web.config

<add key="ImageUrl" value="/Upload_Files/" />

Controller

    public ActionResult Index()
    {
        var homeVm = new HomeVM
        {
            ImagePaths = DataLayer.GetImagePaths()
        };
        return View("Index", homeVm);
    }

ViewModel

    class HomeVM
    {
            public IEnumerable<string> ImagePaths { get; set; }
    }

DataLayer

I would suggest not enumerating the files each time as this will severely hinder performance of your application. You should store the urls of the images in a database and perform something like

    public static IEnumerable<string> GetImagePaths()
    {
        var imageUrl = ConfigurationManager.AppSettings["ImageUrl"];
        var db = new MyDataClassDataContext();
        var value = (from im in db.Images select imageUrl + im.Path).ToList();
        db.Dispose();
        return value;
    }

So, whenever an image is uploaded or changed, you should modify the value in your table. This will greatly increase performance of your application

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM