0

The View:

<div class="project" style="background-image: url('@project.ProjectLogoPath')">

The Model:

public List<Projects> GetProjects() {
            DataContext dbContext = new DataContext();
            List<Projects> projects_list = new List<Projects>();
            foreach (Project p in dbContext.Projects) {
                Projects c = new Projects();
                c.ProjectName = p.p_name;
                c.ProjectNumber = p.p_num;
                c.CompanyName = p.co_name;
                c.ClientName = p.cl_name;
                c.ProjectLogoPath = "../../Storage/" + p.co_name + "/Clients/" + p.cl_name + "/" + p.p_num + "_" + p.p_name + "/99_Other/project_logo.png";
                projects_list.Add(c);
            }
            return projects_list;
        }

The Controller:

public ActionResult Index() {
            ProjectsBAL b = new ProjectsBAL();
            List<Projects> c = b.GetProjects();
            ViewBag.ProjectsData = c;

            UserBAL u = new UserBAL();
            Users use = u.GetUser();
            ViewBag.Username = use.Username;
            ViewBag.Domain = use.Domain;
            ViewBag.Company = use.Company;

            return View("Index");
        }

This works perfectly well. The problem is that all my 1000 Terabytes of content data cannot be stored in the subfolder, the content will be stored on a remote server and the drive will be mounted to the IIS server, drive letter M. My question is how do I make the path correctly? The line of concern is this:

c.ProjectLogoPath = "../../Storage/" + p.co_name + "/Clients/" + p.cl_name + "/" + p.p_num + "_" + p.p_name + "/99_Other/project_logo.png";

I've already tried:

c.ProjectLogoPath = "M:/Storage/" + p.co_name + "/Clients/" + p.cl_name + "/" + p.p_num + "_" + p.p_name + "/99_Other/project_logo.png";

I've also tried replacing all "/" with "\". Also tried using "file://///" at the start which seemed to work only sporadically (e.g. wouldn't work when I refreshed the page but would work if I pressed the Home button).

Basically, just imagine that the standard content folder for your website is so immensely large that it is no longer appropriate to store it on the web server, but rather on another data server. That is the problem I am trying to solve.

gunslingor
  • 1,358
  • 12
  • 34

2 Answers2

1

By definition if the server you are storing the images on is not a web server, then people browsing your web site will not be able to access them, this is indeed correct as you don't want EVERYTHING available on the web, only the things you want to serve with a web server!!!

So the solutions are;

1.) Install a web server on your 'data/image' server, but make sure it ONLY serves the images.

2.) Create an Action on your actual web server, maybe GetImage(String name) which then does a return File("M:/Storage/" + name), you then use this url in the image source

This is obviously simplified but hopefully gives you the idea? You cannot set the source of an image to a local path because it is the browser that is requesting the image not the server. Thus you need to use option 1 to enable the browser to get at the images, or option 2 to 'pass' the images through to the web. Makes sense?

Milney
  • 6,253
  • 2
  • 19
  • 33
  • P.S. you don't really have 1000 TB of images do you? :P – Milney Dec 12 '16 at 16:38
  • Well... we could have 1000TB of content that the user must be able to access from our GUI. Basically we are making a project manager for media workflows. I'm not sure if installing the web server is an option, this is a LAN and we need to keep restrictions in place, but will consider it. Basically, the media could be 4K video, 3D models, whatever... so the storage must be fast and tightly controlled. In reality, I'm starting to fear that a client side application would have been far more appropriate than a website. – gunslingor Dec 12 '16 at 16:43
  • That would have the exact same problem though... a client application still wouldn't be able to access the data server without mounting it on each client... Option 2 seems to be the only possible solution then - it keeps control as only the one web server has access to the images, but serves them up to the browser. Have a look at serving images using mvc: http://stackoverflow.com/questions/186062/can-an-asp-net-mvc-controller-return-an-image and then set the image source to the action you create which serves the images – Milney Dec 12 '16 at 16:46
  • Yeah... and we are fine with mounting it on each client, only about 30 clients. I mean, our specs even call for the ability to mount one of these project folders on the users client and that could be a real problem for a browser. A lot seems to be pointing me to WPF but alas, it must run on Mac too!!! Option 2 I am not yet familiar with but will study; I suspect it involves downloading the file to the web server from the mounted drive and sending to the client... suspect it wont work for css bk-img but I can find a way around that. Also, makes it silly to use fast storage if IIS is weak link – gunslingor Dec 12 '16 at 16:52
1

You can create an action method which returns the image. You may call th

[OutputCache(Duration = 600)]
public ActionResult GetImg(string companyName,string clientName,
                            string projectName,string projectNumber)
{
    var networkPath = @"M:/Storage/";
    var fileName = Path.Combine(networkPath, companyName);
    //Fix here as needed. I just glanced at your path :(
    fileName = Path.Combine(fileName, "/Clients");
    fileName = Path.Combine(fileName, clientName);
    fileName = Path.Combine(fileName, projectNumber+"_"+projectName);
    fileName = Path.Combine(fileName, "/99_Other/project_logo.png");
    return File(fileName, "image/png");
}

now from your view, call this method by passing the parameter values.

<div class="project" style="background-image: url('@Url.Action("GetImg",
      new { companyName=project.CompanyName,clientName=project.ClientName,
      projectNumber = project.ProjectNumber,projectName=project.ProjectName})')"></div>
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Thank you... great info, you pretty much provided the example for option two in Milney's answer. I had concerns about this working with a background image, but I think your saying it wouldn't be an issue. I'm excited to see what Mozilla inspector shows when the page actually loads. I may go this route, only problem is the fast storage will be slowed by IIS serving up some large files if I take this approach throughout the project, but it may be the only other option. – gunslingor Dec 12 '16 at 17:03
  • as long as the action method returns the image, it should work for background image. browser does not know whether the image is served by your mvc action method or a static file by IIS/ any web server. I added the output cache attribute to cache the image as well. – Shyju Dec 12 '16 at 17:04
  • I'm also wondering where you think this function should be put; is it better in it's own Directly.cs model file where I can put other operations?... never mind... I think it should go in it's own MediaController... that makes sense. – gunslingor Dec 12 '16 at 17:06
  • I always have issues with path combine. This way finally works! string project_path = @"M:/" + companyName + "/Clients/" + clientName + "/" + projectNumber.ToString() + "_" + projectName + "/99_Other/project_logo.png"; return File(project_path, "image/png"); – gunslingor Dec 12 '16 at 17:57
  • If the user can enter the companyName or clientName or projectName then I would strongly suggest escaping your input because for example if someone entered 'This/That' as a projectName it would fall down? – Milney Dec 13 '16 at 09:22