2012-03-08 12 views
10

Próbuję umieścić moje pliki javascript z moimi widokami.Umieszczanie plików js w folderze widoków

Mam następujące położenie pliku js. /Views/Home/Home.js

Jednak w przypadku odwołania się do tagu script powoduje błąd 404.

zgodnie z poniższym SO pytanie: ASP.NET MVC - Where do you put your .js files if you dont want to store them in /Scripts?

dodałem file.js do moich tras zarejestrować. (Nie udało się rozwiązać problemu)

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{file}.js"); 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
    } 

Jak mogę przechowywać i odwoływać się do moich plików js obok moich widoków?

Odpowiedz

24

Problem polega na tym, że ze względów bezpieczeństwa plik web.config znajdujący się w folderze Widoki blokuje wszystkie żądania dotyczące plików w tym folderze. To jest to, co można znaleźć w pliku konfiguracyjnym:

<httpHandlers> 
    <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/> 
</httpHandlers> 

I IIS7:

<handlers> 
    <remove name="BlockViewHandler"/> 
    <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> 
</handlers> 

Rozwiązanie

Można zmienić wieloznacznego złapać tylko t on pliki .cshtml.

<httpHandlers> 
    <add path="*.cshtml" verb="*" type="System.Web.HttpNotFoundHandler"/> 
</httpHandlers> 

<handlers> 
    <remove name="BlockViewHandler"/> 
    <add name="BlockViewHandler" path="*.cshtml" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> 
</handlers> 

Z tego zamiennika, że ​​.js nie będą blokowane.

+1

To działa, ale myślę, że jest to lepszy pomysł, aby nie umieścić pliki w folderze js widoków. – ErikE

+2

Niewątpliwie bezpieczniejsze jest dodawanie do białej listy plików, na które wyraźnie chcesz zezwolić, zgodnie z odpowiedzią pod adresem http://stackoverflow.com/questions/604883/where-to-put-view-specific-javascript-files-in-an-asp -net-mvc-application zamiast samych tylko żądań filtrowania dla plików cshtml. – pwdst

+1

U mnie zbudowałem układ MVC, który intensywnie wykorzystuje kątowe. Mam również AMD wszystko, co wymaga js, więc tylko widoki korzystające z niektórych fragmentów javascript powodują ładowanie tych skryptów java. W związku z tym podzieliłem wszystko na mniejsze części i było sensowne umieszczenie kontrolera kątowego skojarzonego z folderem mvc w folderze z widokiem. Mam coś takiego jak widoki \ ControllerName \ ControllerName.cshtml i views \ Controller \ ControllerName-controller.js. –

2

Ja osobiście nie lubię grać z httpHandlers ze względów bezpieczeństwa. Chciałem zrobić dokładnie to samo, aby zapobiec dwukrotnemu zachowaniu tej samej struktury folderów (w widoku iw folderze skryptów). Tak więc celem jest przechowywanie .js w tym samym folderze co mój .cshtml i nie ma już błędu 404.

Rozwiązanie

Aby osiągnąć ten cel, używam niestandardowej HtmlHelper i sterownik dla JavaScript wywołuje.

HtmlHelper

public static MvcHtmlString JScriptBlock<TModel>(
     this HtmlHelper<TModel> html 
    ) 
    { 
     // Get the physical path of the .js file we are looking for. 
     string path = ((System.Web.Mvc.RazorView)html.ViewContext.View).ViewPath.Replace(".cshtml", ".js"); 
     path = HostingEnvironment.MapPath(path); 

     if (!File.Exists(path)) 
      return null; 

     // We store the physical path in a session variable with GUID as the key 
     string guid = Guid.NewGuid().ToString(); 
     HttpContext.Current.Session[guid] = path; 

     // Create the script block where the src points to the JScript controller. We give the GUID as parameter. 
     return MvcHtmlString.Create("<script src='/JScript/?id=" + guid + "'/>"); 

    } 

JScript Controller

public ActionResult Index(string id) 
    { 
     // id correspond to the guid generated by the MSRJScript helper 

     // We look if the physical path of the .js is available in the session variables 
     if(Session[id] == null) 
      return new HttpStatusCodeResult(HttpStatusCode.Forbidden); 

     // If the physical path was found, we simply send the file back to the browser. 
     string path = Session[id].ToString(); 
     Session.Remove(id); 

     return File(path, "application/javascript"); 
    } 

Gdy to zrobisz, po prostu trzeba dodać następujący kod w widoku/PartialView

@Html.JScriptBlock() 
+0

Tak naprawdę to podoba mi się to, ale czy nie jest to wolniejsze, aby uzyskać te pliki statyczne, ponieważ przechodzą one przez wiele invokerów i metod mvc aż do osiągnięcia rzeczywistego pliku? –

1

W moim opinia, to to dobry sposób: utrzymuje kod prosty i nie dotyka problemu bezpieczeństwa z innymi typami zasobów.

Wystarczy dodać następujące w koparki rozdział:

<add name="JavaScriptHandler" path="*.js" verb="*" preCondition="integratedMode" type="System.Web.StaticFileHandler" /> 
Powiązane problemy