web-dev-qa-db-fra.com

Répertoire virtuel à l'intérieur de l'application ASP.NET Core dans IIS

Nous avons une application utilisant ASP.NET Core 1.0 RC1 et hébergée sur IIS. Ça fonctionne bien. Nous avons maintenant un contenu statique, disponible sur un partage de fichiers et qui devrait être accessible à partir de l'application.

Avant ASP.NET 5, nous avions ajouté un répertoire virtuel dans IIS et pouvions accéder facilement au contenu partagé. Avec notre application hébergée ASP.NET 5, cela ne semble malheureusement pas fonctionner. Nous venons de recevoir un 404 lorsque nous essayons d'accéder au contenu statique.

Notre application utilise app.UseIISPlatformHandler() et app.UseStaticFiles(), mais cela ne fonctionne pas. Nous avons découvert que nous pouvions utiliser app.UseFileServer() avec custom FileServerOptions pour obtenir le comportement souhaité, mais nous sommes curieux de savoir si cela est également possible avec la "vieille" méthode normale d'ajout d'un répertoire virtuel dans IIS.

15
Matthias

J'ai rencontré ce problème aujourd'hui et j'ai finalement réussi à le résoudre. L'astuce (pour moi, probablement pas pour tout le monde) est de s'assurer que le gestionnaire aspNetCore est désactivé dans la sous-application et activé dans l'application principale (ASP.NET Core).

Mon application ASP.NET Core possède un fichier Web.config de base. 

<configuration>
  <system.webServer>
    <handlers>
        <add name="aspNetCore" path="*" verb="*" type="" modules="AspNetCoreModule" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\bin\Debug\netcoreapp2.0\myapp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

et l'application ajoutée en tant que sous-application dans IIS a

<configuration>
  <!-- removed -->
  <system.webServer>
      <handlers>
          <remove name="aspNetCore" />
       </handlers>
  </system.webServer>
</configuration>
16
PerfectlyNormal

J'ai trouvé un blog qui, je pense, doit avoir été écrit par l'OP.

Le résultat est de ne pas utiliser du tout un répertoire virtuel dans IIS, mais plutôt de mapper votre chemin dans Startup.cs vers le répertoire du serveur physique. J'espère que le PO ne me dérange pas d'avoir collé le blog ci-dessous, mais cela m'a aidé lorsque j'ai rencontré ce problème pour la première fois aujourd'hui. 

Source: https://www.jauernig-it.de/asp-net-coreiis-serving-content-from-a-file-share/

Dans certains cas, lorsque vous souhaitez diffuser du contenu statique dans votre application, cela ne fait pas partie de celle-ci, par exemple. car il existe sur un partage de fichiers commun. Le contenu d'un site Web, géré par une division commerciale, pourrait constituer un tel cas d'utilisation. Dans ASP.NET avant Core, le problème ne se posait pas dans IIS: créez simplement un répertoire virtuel sur votre site Web IIS et pointez-le vers le partage de fichiers.

Malheureusement, avec ASP.NET Core, cette approche ne fonctionne plus. Si vous ajoutez un répertoire virtuel à votre application ASP.NET Core dans IIS, celui-ci n’est pas reconnu et un fichier 404 est renvoyé. Cela est dû à DNX/Kestrel, qui s'exécute sous IIS (à l’aide du module HttpPlatformHandler) et auquel IIS ne traite que les demandes. Kestrel ne connaît rien des répertoires virtuels d’IIS. Et comme les applications ASP.NET Core sont indépendantes de IIS et peuvent également être exécutées sans ce dernier (par exemple, exécuter Kestrel en mode autonome), cela devrait être considéré comme une bonne chose.

Mais nous avons maintenant besoin d’une autre solution à notre problème… Heureusement, ASP.NET Core nous offre une interface de programmation permettant de servir des fichiers de n’importe où. Ajoutez simplement le code suivant à votre méthode Startup.cs Configure ():

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(@"\\server\path"),
    RequestPath = new PathString("/MyPath"),
    EnableDirectoryBrowsing = false
});

Cela consiste essentiellement à ajouter un serveur de fichiers à un chemin de serveur physique, qui est ensuite disponible sur un chemin de demande donné, dans ce cas, la navigation dans les répertoires étant désactivée. Vous pouvez également servir à partir d'un chemin relatif à votre application, en utilisant le nouveau PhysicalFileProvider (env.WebRootPath + "\ path") (env donné est de type IHostingEnvironment comme paramètre de Configure ()). Voilà, c’est tout. Il n'est pas nécessaire d'ajouter un "répertoire virtuel" dans IIS, ce matériel est obsolète et appartient au passé. Pour moi, c’est une bonne chose, car nous sommes plus indépendants de l’ensemble de IIS…

10
pook

Pas directement. 

Vous voyez, le problème est que, lorsque vous avez une application .NET-Core, l'application est exécutée dans Kestrell, pas dans IIS. 

Maintenant, pour héberger votre application .NET-Core dans IIS, AspNetCoreModule démarre votre application .NET-Core avec Kestrell sur le port X de 127.0.0.1, puis inverse le trafic de votre répertoire iis-domain + virtual vers le port X. sur 127.0.0.1 (il pourrait utiliser autre chose que TCP). 

Le problème 1 est que Kestrell a une fonctionnalité assez limitée, ce qui signifie qu'aucun répertoire virtuel. 
Le problème 2 est que, contrairement à nginx, IIS n’effectue pas correctement la procuration inversée, ou devrions-nous dire «complètement». 

IIS peut transférer domainxy: 80 à 127.0.0.1:randrand bien. Mais ce qu’il ne fait pas correctement, c’est de réécrire domainxy: 80/foo en 127.0.0.1:random (images, en-tête, résultats json-ajax, urls, URL-retours, cookies, etc., et inversement) . Au lieu de cela, il réécrit le domaine: 80/foo en 127.0.0.1:random/foo, ce qui pose un problème si le serveur sur 127.0.0.1:random (Kestrell) ne prend pas en charge les répertoires virtuels. 

Donc, si vous voulez exécuter votre application dans votre répertoire virtuel, vous avez deux options (toutes deux impliquent de modifier "votre" application - si vous pouvez le faire):
1) Mettez toutes vos données dans le répertoire "foo" (y compris la route du contrôleur MVC), si votre application ne sera déployée qu'une seule fois. 

2) Comme suggéré dans https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552 vous pouvez faire en sorte que l’application-framework simule ce dossier pour vous, un peu comme dans RoR:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    string virtual_directory = "/Virt_DIR";
    // virtual_directory = "/";

    if (virtual_directory.EndsWith("/"))
        virtual_directory = virtual_directory.Substring(0, virtual_directory.Length - 1);

    if (string.IsNullOrWhiteSpace(virtual_directory))
        Configure1(app, env, loggerFactory); // Don't map if you don't have to 
        // (wonder what the framework does or does not  do for that case)
    else 
        app.Map(virtual_directory, delegate(IApplicationBuilder mappedApp) 
            {
                Configure1(mappedApp, env, loggerFactory);
            }
        );
}

// Configure is called after ConfigureServices is called.
public void Configure1(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
       [...]  (here comes what used to be in your old Configure method)

Vous devrez configurer le nom du répertoire virtuel quelque part . Attention, si vous avez/retournez des URL dans JavaScript/ajax-request, elles ne seront pas automatiquement mappées. Vous devez le faire vous-même, mais c'était également le cas avec l'ancien ASP.NET. 

Vraiment, comme RoR: 

map Rails.application.config.relative_url_root || "/" faire
lancez RedmineApp :: Application 
fin

En ce qui concerne un répertoire virtuel dans l'application: Non, ce n'est pas si simple. 
IIS est un serveur Web complet, qui servira le contenu de ce répertoire mappé comme il était là (s'il peut lire le contenu). 

Si vous transférez l'intégralité du répertoire parent vers Kestrell, alors IIS ne pourra pas servir le sous-répertoire et votre application devra le faire. Cela signifie que vous devrez configurer un serveur de fichiers statique pour ce répertoire spécifique et lui indiquer l'emplacement des fichiers, comme vous l'avez fait. 

Ce que vous pourrez peut-être faire, c’est dire à IIS de ne pas utiliser de proxy pour ce sous-répertoire virtuel spécifique (tout comme vous pouvez définir un emplacement de fichier statique dans nginx - à la différence près que IIS ne prend probablement pas en charge cette fonctionnalité. fonctionnalité). 

Cependant, vous pouvez créer un lien symbolique dans le répertoire de votre application pour accéder au dossier en réseau, si Windows en est capable (mklink). Ensuite, .NET Core devrait pouvoir le servir de manière statique. Mais vraiment, cela ressemble à un bidouillage. 

Si vous ne pouvez pas configurer IIS, vous devez utiliser app.UseFileServer () et définir l'emplacement du document dans la base de données. De cette façon, vous pouvez simplement supprimer et réinsérer l'application plus tard. 

4
Stefan Steiger

Je sais que c'est une question avec 1,8 année, mais si quelqu'un a besoin de résoudre le même problème, essayez d'utiliser ceci:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "images")),
        RequestPath = new PathString("/MyImages")
    });
}

Il est parfaitement possible de modifier les paramètres de PhysicalFileProvider dans n’importe quel dossier local ou partagé, et ainsi de servir un fichier. 

Faire cela de cette manière n'est pas recommandé. Mais, pour étude proposer, c'est acceptable.

Le module de fichier statique fournit no contrôles d'autorisation. Tous les fichiers qu'il dessert, y compris ceux de moins de wwwroot sont disponibles au public. Pour servir des fichiers basés sur autorisation: stockez-les en dehors de wwwroot et de tout répertoire accessible au middleware de fichier statique et Servez-les via un fichier action du contrôleur, renvoyant un FileResult où l’autorisation est appliqué.

Dans la documentation Asp.Net de Microsoft, nous pouvons trouver des informations plus complètes pour résoudre ce problème.

Vérifiez ce lien: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/static-files

1
Rafael

Ma solution utilisait path="/" au lieu de path="*" dans le fichier web.config

0
Nicolas Battaglia