2016-06-02 3 views
0

J'ai un service WCF qui fonctionne au format brut, en utilisant les flux:Supprimer le fichier temporaire après son retour au format brut dans WCF

[ServiceContract] 
public interface IEncryptingService 
{ 
    [WebInvoke(UriTemplate = "/")] 
    [OperationContract] 
    Stream SignDocument(Stream requestStream); 
} 

public class EncryptingService : IEncryptingService 
{ 
    public Stream SignDocument(Stream requestStream) 
    { 
     string originalFileName = Path.GetTempFileName(); 
     string signedFileName = Path.GetTempFileName(); 

     using (var originalFileStream = File.Open(originalFileName, FileMode.Create, FileAccess.Write)) 
     { 
      requestStream.CopyTo(originalFileStream); 
     } 

     XmlDocumentSigner.SignFile(originalFileName, signedFileName); 

     return File.Open(signedFileName, FileMode.Open, FileAccess.Read); 
    } 
} 

Maintenant, comment puis-je supprimer ce fichier après la fin WCF retourner le fichier?

J'ai essayé d'utiliser le bloc finally, mais il est appelé juste après return, et génère une exception, car le fichier est toujours utilisé par un processus. Bien sûr, il s'agit d'une solution de contournement comme un agent d'arrière-plan attendant la suppression d'un fichier, mais, à mon avis, ce n'est pas comme la façon dont les services Web doivent être implémentés.

+2

Ne pouvez-vous éviter d'utiliser des fichiers en premier lieu? Juste en utilisant (en mémoire) les flux à la place? –

+0

@ Christian.K Malheureusement, 'XmlDocumentSigner' est une enveloppe autour d'une bibliothèque DLL externe non gérée qui utilise des algorithmes très spécifiques (aucune bibliothèque alternative gérée ou non) et ne peut que signer des fichiers :( –

Répondre

1

La solution est venue à l'esprit inexcusablement rapidement, et c'est tout à fait logique: je peux simplement lire le contenu du fichier en mémoire et supprimer le fichier.

public Stream SignDocument(Stream requestStream) 
{ 
    string originalFileName = Path.GetTempFileName(); 
    string signedFileName = Path.GetTempFileName(); 

    using (var originalFileStream = File.Open(originalFileName, FileMode.Create, FileAccess.Write)) 
    { 
     requestStream.CopyTo(originalFileStream); 
    } 

    XmlDocumentSigner.SignFile(originalFileName, signedFileName); 

    byte[] signedFileBytes = File.ReadAllBytes(signedFileName); 
    File.Delete(signedFileName); 
    return new MemoryStream(signedFileBytes); 
} 

Notez que la déclaration using fait ce code ne parviennent ainsi:

using (var ms = new MemoryStream(signedFileBytes)) 
{ 
    return ms; 
} 
+1

Vous me battez, bien fait à trouver votre réponse.Vôtre était aussi la version la moins compliquée! – TheLethalCoder

+0

@TheLethalCoder Merci :) –

+0

Voir ici aussi: https://devdump.wordpress.com/2008/12/07/disposing-return-values/. Ils parlent de disposition, mais vous pouvez vous abonner à OperationCompleted et supprimer votre fichier là. C'est mieux que de copier tout le fichier en mémoire. – Evk

1

Je ne l'ai pas essayé, mais vous pouvez ouvrir le fichier et écrire ce flux à un autre. Quelque chose comme:

MemoryStream ms = new MemoryStream(); 
using (FileStream fs = File.OpenRead(signedFileName)) 
{ 
    //Read from fs and write to ms 
} 

Ensuite, tout ce que vous devez faire est d'appeler la suppression sur le fichier et retour ms:

File.Delete(signedFileName); 
return ms;