Jak zażądać statycznych plików html w folderze ~ / Views w ASP.NET MVC?

92

Chcę mieć możliwość żądania .htmlplików statycznych , które znajdują się w ~/Viewsfolderze. Zgodnie z dokumentacją system routingu sprawdza, czy adres URL pasuje do pliku dyskowego przed oceną tras aplikacji.

Ale kiedy żądam pliku, 404pojawia się błąd.

Mój plik znajduje się w folderze ~ / Views. Adres URL to:http://[localhost]/Views/HtmlPage1.html

Co przegapiłem?

alex.mironov
źródło

Odpowiedzi:

111

Chcę mieć możliwość zażądania statycznych plików .html, które znajdują się w folderze „~ / Views”.

Nie możesz. W tym folderze znajduje się plik web.config, który wyraźnie zabrania dostępu do jakiegokolwiek pliku z niego. Jeśli chcesz mieć dostęp do plików z klienta, te pliki nie powinny być umieszczane w Viewsfolderze, który ma specjalne znaczenie w ASP.NET MVC.

Możesz mieć ~/Staticfolder, w którym możesz umieścić pliki HTML. A następnie uzyskaj do niego dostęp w ten sposób:

http://example.com/yourapplicationname/static/foo.html
Darin Dimitrov
źródło
4
Lub zamiast nazywać folder „statyczny”, można naśladować strukturę nazwy kontrolera znajdującą się w folderze Views ... tak, aby adres URL miał taki sam „wygląd”. Np. Ponieważ nie możesz umieścić swojego plainjane Edit.html w Views / Order / Edit.html - umieszczasz go w ~ / Order / Edit.html
bkwdesign
2
Zmieniło się to teraz w najnowszym ASP.NET (vNext), w którym można zarejestrować dostawcę statycznego dla plików html, ale także nadal kierować normalnym sposobem MVC. Miałem tylko szybką zabawę, ale to właśnie zrobiłem z projektem testowym. Uruchamianie przez kestrel na Linuksie .. ale IIS powinny być takie same, jak przypuszczam.
Piotr Kula
1
@bkwdesign Jestem pewien, że jego konfiguracja kontrolowana przez naśladowanie struktury folderów zepsuła domyślny program obsługi moich kontrolerów i uniemożliwiła dostęp. Więc przetestuj tę sytuację.
Hunter-Orionnoir
78

Aby zezwolić na pliki takie jak js i html w folderze Widoki, edytuj plik web.config w folderze views-Folder:

<system.webServer>
<handlers>
  <add name="JavaScriptHandler" path="*.js" verb="*"
     preCondition="integratedMode" type="System.Web.StaticFileHandler" />      
  <add name="HtmlScriptHandler" path="*.html" verb="*"
     preCondition="integratedMode" type="System.Web.StaticFileHandler" />
  <remove name="BlockViewHandler"/>
  <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>

cs3x
źródło
1
Musiałem usunąć wiersz "tours.RouteExistingFiles = true;" w RouteConfig.RegisterRoutes, aby to zadziałało
Sam Sippe
Chociaż zaznaczona odpowiedź zawiera przydatne informacje, jest to lepsza odpowiedź. Przetestowałem i pracuję w moim obecnym projekcie.
A. Murray
1
A co z plikami CSS?
Leandro,
Odpowiedź @Darin Dimitrov daje obejście tego problemu, ale to powinno być oznaczone jako odpowiedź
Kunal
31

Chcę mieć możliwość zażądania statycznych plików .html, które znajdują się w folderze ~ / Views.

Cóż, możesz. Zaznaczona odpowiedź nie jest do końca poprawna, chociaż daje rozwiązanie.

Rozumowanie w zaznaczonej odpowiedzi jest poprawne, to web.config (konkretnie ustawienie BlockViewHandler) w folderze Widoki uniemożliwia bezpośredni dostęp do plików. Służy do zabezpieczania widoków w Asp.Net MVC. Ale jeśli zadałeś pytanie dotyczące bezpośredniego udostępniania tych plików, prawdopodobnie masz ważny powód, aby to zrobić, na przykład użycie widoków częściowych AngularJS (jak w naszym przypadku), w których nie chcemy powielać folderu widoków z dziwnymi nazwami.

Oto bardzo prosta poprawka, którą możesz wykonać w pliku web.config znajdującym się w folderze Views, bez narażania bezpieczeństwa widoków mvc asp.net. Zapewni to normalne zabezpieczenie plików .cshtml, ale pozostaw pliki .html w spokoju

Zmień to

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

--do--

<add name="BlockViewHandler" path="*.cshtml" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
Vikas
źródło
3
Może to być nadal niebezpieczne w przypadku innych plików, takich jak .aspx lub .ascx, lub tych pochodzących z mechanizmów wyświetlania innych firm. Znacznie lepiej jest dodać do białej listy zgodnie z odpowiedzią cs3x.
pwdst
1
@pwdst: Jeśli korzystasz z wielu widoków po stronie serwera, tak, białe listy poszczególnych typów mogą być lepsze. Chcemy tylko chronić pliki .cshtml, więc użyliśmy tego, ponieważ jest nieco mniej rozwlekły.
Vikas
14

Inną alternatywną opcją jest wstawienie metody akcji w dowolnym wybranym kontrolerze w celu obsługi pliku html

public ActionResult MyHtml()
{
    var result = new FilePathResult("~/Views/HtmlPage1.html", "text/html");
    return result;
}

Uzyskaj dostęp do html jako http: // twoja_witryna / kontroler / MyHtml . Możesz rozszerzyć tę metodę akcji, aby zaakceptować nazwę pliku html jako metodę / parametr querystrign i renderować plik w czasie wykonywania, np. Coś takiego.

 public ActionResult MyHtml(string htmlPageName)
 {
      var result = new FilePathResult($"~/Views/{htmlPageName}.html", "text/html");
      return result;
 }
Venkatesh Muniyandi
źródło
0

Jeśli planujesz używać folderu widoku wewnętrznego, powyższe odpowiedzi powinny być najlepsze, ale ta odpowiedź może być przydatna dla użytkowników, którzy migrują do asp.net mvc core. Umieszczenie plików w katalogu wwwroot zamiast w folderze views powinno ułatwić dostęp do stron html jako localhost / myfile.html

Kurkula
źródło