2010-10-10 8 views
1

J'ai une application Web MVC 2. Le site web capture des demandes de subvention pour des prêts. Avec chaque application, je peux télécharger des documents. La façon que nous télécharger des documents dans la base de données est la suivante:Afficher le document téléchargé à partir de la base de données

private IEnumerable<byte> GetStreamByteArrayData(Stream stream) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead = 0; 
    while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     for (int byteIndex = 0; byteIndex < bytesRead; byteIndex++) 
     { 
     yield return buffer[byteIndex]; 
     } 
    } 
} 

La méthode d'appel ressemble à ceci:

Convert.ToBase64String(GetStreamByteArrayData(hpf.InputStream).ToArray()); 

Dans ma grille qui affiche les documents téléchargés j'ai le nom du document, type MIME et ainsi de suite. Ce que j'essaie de faire, c'est d'avoir le nom du document dans un lien. Lorsque le lien est cliqué, le document est ouvert. Je n'ai aucune idée de comment faire cela dans une application MVC.

Quelqu'un peut-il s'il vous plaît conseiller ou fournir un code source exemple? Toute aide serait appréciée.

Merci.

+0

clarification rapide; que voulez-vous dire par «ouvert»? Juste téléchargé, ou avez-vous besoin d'un moyen d'intégrer des documents dans la page? –

+0

"Lorsque le lien est cliqué, le document est ouvert" sonne exactement droit. Fais-le. :) – bzlm

+0

Rappelez-vous que le document est dans la base de données, codé en utilisant la méthode ci-dessus. Donc, lorsque le lien est cliqué dans la grille, je vais devoir le décoder à partir de la base de données et ensuite seulement l'ouvrir. Je ne suis pas sûr de savoir comment faire cela dans ma méthode d'action? À quoi ressemblera mon lien? –

Répondre

2

En supposant que vous avez enregistré le nom, le type MIME et le contenu de chaque document dans la base de données que vous pourriez avoir une action de contrôleur qui servira un fichier donné, il est id unique:

public ActionResult Download(int? id) 
{ 
    Document document = _repository.GetDocument(id); 
    if (document == null) 
    { 
     throw new HttpException(404, "Not found"); 
    } 

    // For example document.ContentType = "application/pdf" and 
    // document.Name = "test.pdf" 
    return File(document.Contents, document.ContentType, document.Name); 
} 

Le modèle de document pourrait ressembler à ceci:

public class Document 
{ 
    public int Id { get; set; } 
    public byte[] Contents { get; set; } 
    public string ContentType { get; set; } 
    public string Name { get; set; } 
} 

Et vous pouvez enfin générer des liens vers cette action dans votre grille:

<%: Html.ActionLink("Download", "Download", new { id = "123" })%> 

Si vous ne disposez pas du type de contenu et le nom du document stocké dans la base de données vous pouvez les passer en tant que paramètres d'action:

<%: Html.ActionLink("Download", "Download", 
    new { id = "123", contentType = "application/pdf", name = "test.pdf" }) %> 
+0

Merci cela fonctionne très bien. –

+0

petite question, pourquoi l'identifiant est-il un intensible? –

0

Faire un gestionnaire .ashx que BinaryWrite s le contenu pourrait aider. Ci-dessous un moyen d'y parvenir:

ÉTAPE 1: Charge

  • Chargez vos données dans le DataTable (en supposant que vous avez une colonne d'identité ainsi)
  • Ajouter un élément de modèle de type lien dans votre balisage
  • Ajouter une colonne lINK et définissez les enregistrements comme http://yourpath/ShowContent.ashx?ID=111 (par exemple, Id est la clé primaire) soit en passant par chaque enregistrement ou lors de l'enregistrement des enregistrements dans la base de données.
  • Set et DataBind au GridView

ÉTAPE 2: Affichage

Une fois cliquez sur un lien dans le GridView, elle fait appel à la ShowContent.ashx; gérer l'événement et il suit doit se produire:

  • Obtenez l'événement ShowContent.ashx
  • Obtenez la valeur de l'ID de chaîne de requête
  • Sélectionnez cet enregistrement de la DataTable en utilisant l'ID
  • et BinaryWrite quelque chose comme ce qui suit:

    byte[] content = (byte[])dataRow["COL_CONTENT"]; HttpContext.Current.Response.ContentType = dataRow["COL_CONTENT_TYPE"]; HttpContext.Current.Response.BinaryWrite(content);

Notez que vous devrez peut-être ajouter votre DataTable/enregistrements dans la session pour le traitement pratique des enregistrements.

Profitez de l'exemple, A Boilerplate HttpHandler

Questions connexes