2017-02-08 1 views
2

J'utilise httpwebrequest pour publier un fichier avec des données de formulaire supplémentaires à partir d'une application MVC sur un site ASP classique.Qu'est-ce qui pourrait causer cette corruption dans les fichiers .docx pendant httpwebrequest?

Si le fichier est un .docx, il arrive toujours comme corrompu. D'autres semblent bien s'ouvrir, mais il se peut que leurs formats soient plus flexibles.

Lorsque j'ouvre les fichiers d'origine et endommagés dans Sublime Text, j'ai remarqué que le fichier endommagé manque un bloc de 0000 à la fin. Lorsque je remplace manuellement ce bloc, le fichier s'ouvre correctement.

enter image description here

Y at-il quelque chose que je fais mal dans mon code .NET qui provoque cela se produise? Ou le problème est-il plus ésotérique?

Le code ASP classique utilise Persist's AspUpload pour recevoir le fichier. Ceci est utilisé dans de nombreux endroits ailleurs sur le site de réception et n'a jamais causé de problèmes auparavant. Donc je ne pense pas que l'erreur soit là. De plus, c'est juste un simple appel, et je ne peux pas voir ce qu'il y a à se tromper!

Set File = Upload.Files("fileField")

Je suis à une perte sur la façon de démarrer le débogage ce problème plus loin.


C'est le code que je utilise pour poster le fichier:

public async Task<string> TestFileSend() 
{ 
    string result; 

    var postToUrl = "https://www.mywebsite.com/receive-file.asp"; 

    Dictionary<string, string> extraData = new Dictionary<string, string>(); 
    extraData.Add("colour", "red"); 
    extraData.Add("name", "sandra"); 

    var filePath = "/path-to-file/file.docx"; 
    byte[] fileAsByteArray = File.ReadAllBytes(filePath); 


    // setup data to send 
    var dataBoundry = "---------------------------9849436581144108930470211272"; 
    var dataBoundryAsBytes = Encoding.ASCII.GetBytes(Environment.NewLine + "--" + dataBoundry + Environment.NewLine); 

    var startOfFileData = "--" + dataBoundry + Environment.NewLine + 
     @"Content-Disposition: form-data; name=""fileField""; filename=""file.docx""" + Environment.NewLine; 

    startOfFileData += @"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document" + Environment.NewLine + Environment.NewLine; 
    var startOfFileDataAsBytes = Encoding.UTF8.GetBytes(startOfFileData); 
    var endOfRequest = "--" + dataBoundry + "--"; 
    byte[] endOfRequestAsBytes = Encoding.UTF8.GetBytes(endOfRequest); 


    // perform request 
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(postToUrl); 
    httpWebRequest.ContentType = "multipart/form-data; boundary=" + dataBoundry; 
    httpWebRequest.Method = "POST"; 
    using (var stream = await httpWebRequest.GetRequestStreamAsync()) 
    { 
     foreach (KeyValuePair<string, string> item in extraData) 
     { 
      var dataItemBytes = DataItemAsBytes(item.Key, item.Value); 
      stream.Write(dataBoundryAsBytes, 0, dataBoundryAsBytes.Length); 
      stream.Write(dataItemBytes, 0, dataItemBytes.Length); 
     } 
     stream.Write(startOfFileDataAsBytes, 0, startOfFileDataAsBytes.Length); 
     stream.Write(fileAsByteArray, 0, fileAsByteArray.Length); 
     stream.Write(endOfRequestAsBytes, 0, endOfRequestAsBytes.Length); 
    } 
    try 
    { 
     using (WebResponse response = httpWebRequest.GetResponse()) 
     { 
      HttpWebResponse httpResponse = (HttpWebResponse)response; 
      using (Stream myData = response.GetResponseStream()) 
      using (var reader = new StreamReader(myData)) 
      { 
       result = reader.ReadToEnd(); 
      } 
     } 
    } 
    catch (WebException e) 
    { 
     result = e.Message; 
    } 

    return result; 
} 

Problème résolu - Ceci est le texte modifié du Code de travail

Jon frapper avec sa réponse. J'ai ajouté la ligne qu'il a suggéré immédiatement après avoir écrit le flux de fichier et ils transfèrent maintenant sans aucun problème.

public async Task<string> TestFileSend() 
{ 
    string result; 

    var postToUrl = "https://www.mywebsite.com/receive-file.asp"; 

    Dictionary<string, string> extraData = new Dictionary<string, string>(); 
    extraData.Add("colour", "red"); 
    extraData.Add("name", "sandra"); 

    var filePath = "/path-to-file/file.docx"; 
    byte[] fileAsByteArray = File.ReadAllBytes(filePath); 


    // setup data to send 
    var dataBoundry = "---------------------------9849436581144108930470211272"; 
    var dataBoundryAsBytes = Encoding.ASCII.GetBytes(Environment.NewLine + "--" + dataBoundry + Environment.NewLine); 

    var startOfFileData = "--" + dataBoundry + Environment.NewLine + 
     @"Content-Disposition: form-data; name=""fileField""; filename=""file.docx""" + Environment.NewLine; 

    startOfFileData += @"Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document" + Environment.NewLine + Environment.NewLine; 
    var startOfFileDataAsBytes = Encoding.UTF8.GetBytes(startOfFileData); 
    var endOfRequest = "--" + dataBoundry + "--"; 
    byte[] endOfRequestAsBytes = Encoding.UTF8.GetBytes(endOfRequest); 


    // perform request 
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(postToUrl); 
    httpWebRequest.ContentType = "multipart/form-data; boundary=" + dataBoundry; 
    httpWebRequest.Method = "POST"; 
    using (var stream = await httpWebRequest.GetRequestStreamAsync()) 
    { 
     foreach (KeyValuePair<string, string> item in extraData) 
     { 
      var dataItemBytes = DataItemAsBytes(item.Key, item.Value); 
      stream.Write(dataBoundryAsBytes, 0, dataBoundryAsBytes.Length); 
      stream.Write(dataItemBytes, 0, dataItemBytes.Length); 
     } 
     stream.Write(startOfFileDataAsBytes, 0, startOfFileDataAsBytes.Length); 
     stream.Write(fileAsByteArray, 0, fileAsByteArray.Length); 
     // *** THIS ADDITIONAL LINE IS THE KEY 
     stream.Write(new byte[] { 45, 45 }, 0, 2); 
     // *** 
     stream.Write(endOfRequestAsBytes, 0, endOfRequestAsBytes.Length); 
    } 
    try 
    { 
     using (WebResponse response = httpWebRequest.GetResponse()) 
     { 
      HttpWebResponse httpResponse = (HttpWebResponse)response; 
      using (Stream myData = response.GetResponseStream()) 
      using (var reader = new StreamReader(myData)) 
      { 
       result = reader.ReadToEnd(); 
      } 
     } 
    } 
    catch (WebException e) 
    { 
     result = e.Message; 
    } 

    return result; 
} 

Répondre

1

J'ai récemment joué au sujet des données-multipart/form et a remarqué qu'il a un –- supplémentaire sur la fin de la limite multipart finale. Il y a un exemple dans ce stackoverflow answer. Je pense c'est où vous perdez les deux octets. Si tel est le cas, la solution consiste à ajouter une dernière écriture dans le flux de requête de deux octets de 45 (ASCII -).

stream.Write(new byte[]{45, 45}, 0, 2); 

Je ne peux pas être sûr, mais il semble être un bon ajustement. J'espère que cela aide.

+0

Spot on - vous m'avez sauvé des heures - merci beaucoup :) –