Файловый поток веб-службы в Байт [] в FileStream в pdf при ошибке C # - PullRequest
2 голосов
/ 21 мая 2019

Я пытаюсь создать web service, который возвращает pdf файл как byte[], а затем приложение, которое его использует, захватывает byte[] и сохраняет его как pdf файл, а затем открывает его. Файл не открывается в конце.

Вот веб-служба , которая возвращает byte[]

[WebMethod]
public byte[] XXXX(int fileID)
{
    try
    {
        using (EntitiesModel dbContext = new EntitiesModel())
        {   
            string fileFullPath = .....
            .......     
            if (fileFullNamePath != null)
            {
                FileStream fileStream = new FileStream(fileFullNamePath, FileMode.Open, System.IO.FileAccess.Read);
                int len = fileStream.Length.ToInt();
                Byte[] documentContents = new byte[len];
                fileStream.Read(documentContents, 0, len);
                fileStream.Close();
                return documentContents;

Затем вызывается из приложения 1015 * со следующим кодом

string soap = "<?xml version=\"1.0\" encoding=\"utf - 8\"?>" +
              "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
              "<soap:Body>" +
              "<XXXX xmlns=\"http://tempuri.org/\">" +
              "<fileID>XXXXX</fileID>" +
              "</XXXX>" +
              "</soap:Body>" +
              "</soap:Envelope>";
string localhostContext = @"http://localhost:3381/";
string webserviceAddress = @"XXXX/XXXX/XXXXX.asmx";
string url = localhostContext + webserviceAddress ;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "text/xml";
request.ContentLength = soap.Length;
request.Timeout = 20000;
request.Method = "POST";
using (Stream stream = request.GetRequestStream())
{
    using (StreamWriter streamWriter = new StreamWriter(stream))
    {
        streamWriter.Write(soap);               }
    }
}
byte[] bytes;
try
{
    WebResponse response = request.GetResponse();
    bytes = ReadFully(response.GetResponseStream());
}
catch (Exception exception)
{
    throw;
}

private byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream memoryStream = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            memoryStream.Position = 0;
            memoryStream.Write(buffer, 0, read);
        }
        return memoryStream.ToArray();
    }
}

FileStream objfilestream =
                new FileStream(fileName, FileMode.Create,FileAccess.ReadWrite);
objfilestream.Write(bytes, 0, bytes.Length);
objfilestream.Close();
var process = Process.Start(fileName);

Код работает нормально и создает pdf, а затем пытается открыть этот pdf. Но файл не может быть открыт. Adobe Acrobat выдает ошибку

Adobe Acrobat Reader could not open XXX.pdf because it is either not a 
supported file type or because the file has been damaged (for example, it 
was sent as an email attachment and wasn't correctly decoded).

Поскольку я не получаю сообщение об ошибке в коде, я не знаю, где находится ошибка, из-за которой не создается нужный файл.

Была проблема с переменной Stream с именем input, которая не давала длину, поэтому я использовал Jon Skeet's предложение здесь Stackoverflow: создание байтового массива из потока

new byte[16*1024]; 

вместо

new byte[input.length]

1 Ответ

1 голос
/ 29 мая 2019

Были три неправильные вещи.

memoryStream.Position = 0;

в цикле while было проблематично, поэтому я удалил его.

Во-вторых, при чтении потока.Он вернул сообщение SOAP XMl с зашифрованной строкой base64 в теге XXXXResult XML.Поэтому мне пришлось извлечь это.

Наконец, мне пришлось использовать

byte[] fileResultBytes  = Convert.FromBase64String(resultString);

, чтобы получить байт [] из resultString, извлеченного из сообщения SOAP.В тестовом сообщении SOAP, которое может быть сгенерировано локально, в нем указывается тип этой строки результата.Сначала я это пропустил.

Спасибо VC.One и CodeCaster за правильные предложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...