web-dev-qa-db-fra.com

Comment servir un fichier HTML depuis un autre répertoire en tant que ActionResult

J'ai un cas spécialisé où je souhaite servir un fichier html direct d'une action de contrôleur.

Je veux le servir à partir d'un dossier différent du dossier Vues. Le fichier se trouve dans

Solution\Html\index.htm

Et je veux le servir à partir d'une action de contrôleur standard. Puis-je utiliser le fichier de retour? Et Comment je fais ça?

33
Aran Mulholland

Si vous voulez rendre ce fichier index.htm dans le navigateur, vous pouvez créer une action de contrôleur comme celle-ci:

public void GetHtml()
{
    var encoding = new System.Text.UTF8Encoding();
    var htm = System.IO.File.ReadAllText(Server.MapPath("/Solution/Html/") + "index.htm", encoding);
    byte[] data = encoding.GetBytes(htm);
    Response.OutputStream.Write(data, 0, data.Length);
    Response.OutputStream.Flush();
}

ou simplement par:

public ActionResult GetHtml()
{
    return File(Server.MapPath("/Solution/Html/") + "index.htm", "text/html"); 
}

Supposons donc que cette action est dans le contrôleur Home et que certains utilisateurs cliquent sur http://votresite.com/Home/GetHtml puis index.htm sera rendu.

EDIT: 2 autres méthodes

Si vous voulez voir le code HTML brut de index.htm dans le navigateur:

public ActionResult GetHtml()
{
    Response.AddHeader("Content-Disposition", new System.Net.Mime.ContentDisposition { Inline = true, FileName = "index.htm"}.ToString());
    return File(Server.MapPath("/Solution/Html/") + "index.htm", "text/plain"); 
}

Si vous voulez seulement télécharger le fichier:

public FilePathResult GetHtml()
{
    return File(Server.MapPath("/Solution/Html/") + "index.htm", "text/html", "index.htm"); 
}
39
lucask

Regarde ça :

    public ActionResult Index()
    {
        return new FilePathResult("~/Html/index.htm", "text/html");
    }
45
Wahid Bitar

J'ai étendu la réponse de wahid pour créer HtmlResult 

Créer un résultat HTML qui étend FilePathResult

public class HtmlResult : FilePathResult
{
    public HtmlResult(string path)
        : base(path, "text/html")
    {
    }
}

Méthode statique créée sur le contrôleur

public static HtmlResult Html(this Controller controller, string path)
{
    return new HtmlResult(path);
}

utilisé comme nous revenons vue 

public HtmlResult Index()
{
    return this.Html("~/Index.html");
}

J'espère que ça aide

8
om471987

Pouvez-vous lire le fichier html dans une chaîne et le retourner en action? Il est rendu comme une page HTML comme indiqué ci-dessous:

public string GetHtmlFile(string file)
{
    file = Server.MapPath("~/" + file);
    StreamReader streamReader = new StreamReader(file);
    string text = streamReader.ReadToEnd();
    streamReader.Close();
    return text;
}

Accueil/GetHtmlFile? File = Solution\Html\index.htm

Si la destination ou le mécanisme de stockage des fichiers HTML est compliqué, vous pouvez Fournisseur de chemin virtuel

Exemple MVC de fournisseur de chemin virtuel

0
Abhijit Kadam

Une autre approche si vous utilisez .net core consiste à utiliser un FileProvider .Les fichiers peuvent se trouver dans un dossier ou être incorporés au moment de la compilation. 

Dans cet exemple, nous utiliserons des fichiers incorporés.

Ajoutez un dossier dans votre projet, disons actifs, créez un fichier myfile.html, ajoutez du HTML de base au fichier say

<html>
<head>
  <title>Test</title>
</head>
<body>
   Hello World
</body>
</html>

Cliquez avec le bouton droit sur le nouveau fichier (en supposant que vous soyez dans Visual Studio), sélectionnez Propriétés, dans la fenêtre Propriétés/Action de construction, sélectionnez une ressource incorporée. Il ajoutera le fichier au fichier csproj.

Faites un clic droit sur votre projet, éditez votre fichier csproj . Vérifiez que votre groupe de propriétés contient les éléments suivants:

<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>

Si non, merci de l'ajouter. Le fichier csproj doit également contenir le fichier HTML nouvellement créé en tant que:

  <ItemGroup>
    <EmbeddedResource Include="assets\myfile.html" />
  </ItemGroup>

Pour lire le fichier dans votre contrôleur et le transmettre au client, un fournisseur de fichier est ajouté au fichier startup.cs.

Modifiez votre fichier startup.cs en vous assurant qu'il inclut l'environnement HostingEnvironment:

private readonly IHostingEnvironment HostingEnvironment;
public Startup(IHostingEnvironment hostingEnvironment)
{
     HostingEnvironment = hostingEnvironment;
}

Créez ensuite un fournisseur de fichiers et faites-en un service pouvant être injecté au moment de l'exécution. Créez-le comme suit:

 var physicalProvider = HostingEnvironment.ContentRootFileProvider;
 var manifestEmbeddedProvider =
      new ManifestEmbeddedFileProvider(Assembly.GetEntryAssembly());
 var compositeProvider =
      new CompositeFileProvider(physicalProvider, manifestEmbeddedProvider);

 services.AddSingleton<IFileProvider>(compositeProvider);

Pour servir le fichier, allez sur votre contrôleur, utilisez l'injection de dépendance pour obtenir FileProvider, créer un nouveau service et servir le fichier. Pour ce faire, commencez par l'injection de dépendance en ajoutant le fournisseur à votre constructeur.

IFileProvider _fileProvider;
public MyController(IFileProvider fileProvider)
{
    this._fileProvider = fileProvider;
}

Ensuite, utilisez le fournisseur de fichiers dans votre service

[HttpGet("/myfile")]
[Produces("text/html")]
public Stream GetMyFile()
{
   // Use GetFileInfo to get details on the file passing in the path added to the csproj
   // Using the fileInfo returned create a stream and return it.
   IFileInfo fileinfo = _fileProvider.GetFileInfo("assets/myfile.html");
   return fileinfo.CreateReadStream();
}

Pour plus d'informations, voir ASP .Exemple de fournisseur de fichier .Net Core et la documentation Microsoft ici .

0
Jason

Je veux mettre mes deux sous. J'ai trouvé cela le plus laconique et c'est déjà là: 

public ActionResult Index()
{
     var encoding = new System.Text.UTF8Encoding();
     var html = ""; //get it from file, from blob or whatever
     return this.Content(html, "text/html; charset=utf-8");
}
0
Ognyan Dimitrov