3

today i came up with a requirement for my company website (build in ASP.NET MVC 3).

One of the static pages, a pdf file (from Content folder) from my companies website is shown up in Google searches. My company wants that pdf file to be accessible to only logged in users.

For that i created a Route and decorated it with RouteExistingFiles = true;

        routes.RouteExistingFiles = true;
        routes.MapRoute(
            "RouteForContentFolder", // Route name
            "Content/PDF/ABC.pdf", // URL with parameters
            new { controller = "User", action = "OpenContentResources", id = UrlParameter.Optional } // Parameter defaults
        );

In UserController I wrote an action method OpenContentResources which would redirect the user to the URL

    [CompanyAuthorize(AppFunction.AccessToPDFFiles)]
    public ActionResult OpenContentResources()
    {
        return Redirect("http://localhost:9000/Content/PDF/ABC.pdf");
    }

But this code goes in infinite loop and never gets executed. Can any one help me around with my concern.

Thanks ...

shakti
  • 191
  • 1
  • 8
  • 21

3 Answers3

2

I would do it this way:

Controller:

    [Authorize]
    public ActionResult GetPdf(string name)
    {
        var path = Server.MapPath("~/Content/Private/" + name);
        bool exists = System.IO.File.Exists(path);
        if (exists)
        {
            return File(path, "application/pdf");
        }
        else
        {
            // If file not found redirect to inform user for example
            return RedirectToAction("FileNotFound");
        }
    }

web.config:

  <location path="Content/Private" allowOverride="false">
    <system.web>
      <authorization>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

robots.txt (place it on the root of Your site):

User-agent: *
Disallow: /Content/Private/

This way your folder will be hidden from crawlers and protected from unauthenticated users. In this case I was using Forms Authentication so I was automatically redirected to login page if I was trying to access file before logging in. ( http://localhost:8080/Home/GetPdf?name=test.pdf ) In Your case it might be different.

References:

Robots.txt

web.config location element

lucask
  • 2,290
  • 24
  • 19
  • but if iam not using forms authentication then in web.config in place of what would come.?? – shakti May 18 '12 at 12:50
  • Leave it like that. Without forms auth server should just return HTTP 401 status code - unauthorized. – lucask May 18 '12 at 13:04
  • Quick note: you can also use , which will block only unauthorized users. It's blocking access directly to the resource (ex. http://localhost:8080/Content/Private/test.pdf), not mvc route. That is authorize attribute job. – lucask May 18 '12 at 13:09
  • hi , how to specify Route with static url having dot in it. – shakti May 21 '12 at 13:15
  • hi , how to specify Route with static url having dot in it. routes.MapRoute( "RouteForContentFolder", // Route name "Content/PDF/ABC.pdf", // URL with parameters new { controller = "User", action = "GetPdf"}// Parameter defaults ); If i specify this route, it directly opens the PDF file without going through the controller and action. I guess dot in ABC.pdf is the problem. – shakti May 21 '12 at 13:21
  • By default ASP.NET will treat such request as static content and will handle request directly to IIS, unless You have RouteExistingFiles set to true. If You have though, check first if "Content/PDF" isn't ignored with IgnoreRoute method. Btw this route would work if GetPdf action was parameterless. – lucask May 21 '12 at 17:13
  • lucask... do u have sp2 installed on your machine... i read somewhere that this was the fix for the issue.?? – shakti May 22 '12 at 06:06
  • Do you mean service pack 2? And for what exaclty? And shakti, my solution is probably the easiest and quickest fix for you. If you wish you can create custom HttpHandler to intercept requests for pdf files, but in your case it would be an overkill. Creating static route for only one file is kinda pointless as well. – lucask May 22 '12 at 07:19
  • lucask, ur correct, creating a static route for one file is pointless.. but it came to me as a requirement. a url is shown up in google search. on click of that url a pdf file opens. my task is to now allow only those users to view the pdf file who are logged in users. So of that i want to route a static url to a controller and action. And by the way after installing SP1 the .pdf issue got over. – shakti May 22 '12 at 09:02
1

You have to return the pdf file as a FileResult. See this post for more information

ASP.NET MVC - How do I code for PDF downloads?

In your case the action will looks like

public ActionResult OpenContentResources()
{
    return File("~/Content/PDF/ABC.pdf", "application/pdf");
}
Community
  • 1
  • 1
Juraj Suchár
  • 1,107
  • 6
  • 25
  • didnt satisfy my requirement. – shakti May 18 '12 at 10:42
  • have you tried this insted of your redirect? `return File("~/Content/PDF/ABC.pdf", "application/pdf");` – Juraj Suchár May 18 '12 at 10:56
  • /Content/PDF/ABC.pdf does not exist – shakti May 18 '12 at 12:04
  • Error 404 means, that the action method OpenContentResources() wasn't even fired. The problem must be within the CompanyAuthorize attribute or elsewhere. I cannot help, because when I copy your routing configuration and combine it with my action definition, it works perfectly for me. – Juraj Suchár May 18 '12 at 13:38
  • hi , how to specify Route with static url having dot in it. routes.MapRoute( "RouteForContentFolder", // Route name "Content/PDF/ABC.pdf", // URL with parameters new { controller = "User", action = "GetPdf"}// Parameter defaults ); If i specify this route, it directly opens the PDF file without going through the controller and action. I guess dot in ABC.pdf is the problem. – shakti May 21 '12 at 13:20
  • This should only happen when `RouteExistingFiles = false`. It doesn't depend on the presence of dot in the URL. – Juraj Suchár May 21 '12 at 13:45
  • it is set to true. but the ABC.pdf file is physical file on the same location Content/PDF folder – shakti May 21 '12 at 13:51
  • I also have ABC.pdf on the same location and it works. The problem must be somewhere else, maybe some special IIS or ASP.NET configuration, browser cache,... I do not know. – Juraj Suchár May 21 '12 at 15:01
  • do u have windows 7 SP 2 installed on your machine.?? can this be the fix.?? – shakti May 22 '12 at 06:05
  • the same route works at my end for a .css file but it doesnt work for .pdf... strange... – shakti May 22 '12 at 06:05
0

The problem got solved after hosting it on test server.

shakti
  • 191
  • 1
  • 8
  • 21