Je travaille sur un service Web utilisant la nouvelle WebAPI d'ASP.NET MVC qui servira des fichiers binaires, principalement .cab
et des .exe
fichiers.
La méthode de contrôleur suivante semble fonctionner, ce qui signifie qu'elle renvoie un fichier, mais elle définit le type de contenu sur application/json
:
public HttpResponseMessage<Stream> Post(string version, string environment, string filetype)
{
var path = @"C:\Temp\test.exe";
var stream = new FileStream(path, FileMode.Open);
return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream"));
}
Y a-t-il une meilleure manière de faire cela?
asp.net
asp.net-mvc
asp.net-web-api
Josh Earl
la source
la source
Réponses:
Essayez d'utiliser un simple
HttpResponseMessage
avec saContent
propriété définie sur aStreamContent
:Quelques points à noter sur l'
stream
utilisation:Vous ne devez pas appeler
stream.Dispose()
, car l'API Web doit toujours pouvoir y accéder lorsqu'elle traite les méthodes du contrôleurresult
pour renvoyer des données au client. Par conséquent, n'utilisez pas deusing (var stream = …)
bloc. L'API Web disposera du flux pour vous.Assurez-vous que la position actuelle du flux est définie sur 0 (c'est-à-dire le début des données du flux). Dans l'exemple ci-dessus, c'est une donnée puisque vous venez d'ouvrir le fichier. Cependant, dans d'autres scénarios (comme lorsque vous écrivez pour la première fois des données binaires dans a
MemoryStream
), assurez-vous destream.Seek(0, SeekOrigin.Begin);
ou définissezstream.Position = 0;
Avec les flux de fichiers, la spécification explicite des
FileAccess.Read
autorisations peut aider à éviter les problèmes de droits d'accès sur les serveurs Web; Les comptes de pool d'applications IIS reçoivent souvent uniquement des droits d'accès en lecture / liste / exécution sur wwwroot.la source
using
au résultat (HttpResponseMessage
) ou au flux lui-même, car ils seront toujours utilisés en dehors de la méthode. Comme @Dan l'a mentionné, ils sont éliminés par le framework après l'envoi de la réponse au client.Pour Web API 2 , vous pouvez implémenter
IHttpActionResult
. Voici la mienne:Ensuite, quelque chose comme ça dans votre contrôleur:
Et voici une façon de dire à IIS d'ignorer les demandes avec une extension afin que la demande parvienne au contrôleur:
la source
async
modificateur sur la signature de la méthode et de supprimer complètement la création d'une tâche: gist.github.com/ronnieoverby/ae0982c7832c531a9022Pour ceux qui utilisent .NET Core:
Vous pouvez utiliser l'interface IActionResult dans une méthode de contrôleur API, comme ceci ...
Cet exemple est simplifié, mais devrait faire passer le message. Dans .NET Core, ce processus est tellement plus simple que dans les versions précédentes de .NET - c'est-à-dire sans définir le type de réponse, le contenu, les en-têtes, etc.
En outre, bien sûr, le type MIME pour le fichier et l'extension dépendra des besoins individuels.
Référence: SO Post Answer by @NKosi
la source
Bien que la solution suggérée fonctionne correctement, il existe un autre moyen de renvoyer un tableau d'octets à partir du contrôleur, avec un flux de réponse correctement formaté:
Malheureusement, WebApi n'inclut aucun formateur pour "application / octet-stream". Il y a une implémentation ici sur GitHub: BinaryMediaTypeFormatter (il y a des adaptations mineures pour le faire fonctionner pour webapi 2, les signatures de méthode ont changé).
Vous pouvez ajouter ce formateur dans votre configuration globale:
WebApi doit maintenant utiliser
BinaryMediaTypeFormatter
si la demande spécifie l'en-tête Accept correct.Je préfère cette solution car un contrôleur d'action renvoyant l'octet [] est plus confortable à tester. Cependant, l'autre solution vous permet plus de contrôle si vous souhaitez renvoyer un autre type de contenu que "application / octet-stream" (par exemple "image / gif").
la source
Pour toute personne ayant le problème de l'API appelée plus d'une fois lors du téléchargement d'un fichier assez volumineux en utilisant la méthode dans la réponse acceptée, veuillez définir la mise en mémoire tampon des réponses sur true System.Web.HttpContext.Current.Response.Buffer = true;
Cela garantit que tout le contenu binaire est mis en mémoire tampon côté serveur avant d'être envoyé au client. Sinon, vous verrez plusieurs demandes envoyées au contrôleur et si vous ne les gérez pas correctement, le fichier sera corrompu.
la source
Buffer
propriété a été dépréciée au profit deBufferOutput
. Il est par défauttrue
.La surcharge que vous utilisez définit l'énumération des formateurs de sérialisation. Vous devez spécifier explicitement le type de contenu comme:
la source
Content Type: application/json
dans Fiddler. LeContent Type
semble être défini correctement si je casse avant de retourner lahttpResponseMessage
réponse. Avez-vous d'autres idées?Tu pourrais essayer
la source