Wie die Rückkehr einer PDF-Datei von einem Web-API-Anwendung

Ich habe eine Web-API-Projekt, das auf einem server läuft. Es soll die Rückkehr von PDF-Dateien aus zwei verschiedenen Arten von Quellen: ein Tatsächliches portable document file (PDF), und einen base64-string in einer Datenbank gespeichert. Die Mühe, die ich habe ist, senden Sie das Dokument zurück zu einem client-MVC-Anwendung. Der rest von diesem ist, die details über alles, was passiert ist und das hab ich auch schon versucht.

Ich habe code geschrieben, der erfolgreich übersetzt diese zwei Formate in C# code und dann (wieder) in PDF-form. Ich habe erfolgreich übertragen ein byte-array, das soll darstellen, eines dieser Dokumente, aber ich kann Sie nicht für die Anzeige im browser (in einem neuen tab von selbst). Ich bekomme immer eine Art von "kann nicht angezeigt werden" Fehler.

Kürzlich habe ich eine Möglichkeit zum anzeigen der Dokumente auf der server-Seite, um sicherzustellen, dass ich zumindest bekommen, es zu tun. Es wird das Dokument in den code und erstellt eine FileStreamResult mit, dass es dann wieder als ein (impliziter cast) ActionResult. Ich habe, dass die Rückkehr zu einer serverseitigen MVC-controller und warf es in eine einfache Rückgabe (keine Aussicht), die zeigt die PDF-Prima im browser. Allerdings versuchen, gehen Sie einfach direkt auf die Web-API-Funktion gibt einfach das, was aussieht wie eine JSON-Darstellung eines FileStreamResult.

Wenn ich versuche, um die Rückgabe ordnungsgemäß zu meinen Kunden MVC-Anwendung, es sagt mir, dass "_buffer" kann nicht direkt festgelegt werden. Einige Fehler-Nachricht an den Effekt, dass einige der Eigenschaften zurückgegeben wird, und geworfen in ein Objekt sind privat und können nicht zugegriffen werden.

Den genannten byte-array-Darstellung des PDF-Dokuments, wenn übersetzt in einen base64-string, der nicht scheinen, um die gleiche Anzahl an Zeichen wie der "_buffer" zurückgegebene string in JSON durch ein FileStreamResult. Es fehlt etwa 26k 'A' am Ende.

Irgendwelche Ideen, wie man diese PDF-Datei korrekt zurück? Ich kann code bereitstellen, wenn nötig, aber es werden einige bekannte Weg, um wieder ein PDF von einem server-seitige Web-API-Anwendung, um eine client-side MVC-Anwendung und zeigen Sie Sie als Webseite in einem browser.

P. S. ich weiß, dass der "client-Seite" Anwendung ist technisch nicht auf der client-Seite. Es wird auch eine server-Anwendung, aber das sollte keine Rolle in diesem Fall. Relativ zu den Web-API-server, mein MVC-Anwendung "client-side".

Code
Für immer pdf:

private System.Web.Mvc.ActionResult GetPDF()
{
    int bufferSize = 100;
    int startIndex = 0;
    long retval;
    byte[] buffer = new byte[bufferSize];
    MemoryStream stream = new MemoryStream();
    SqlCommand command;
    SqlConnection sqlca;
    SqlDataReader reader;

    using (sqlca = new SqlConnection(CONNECTION_STRING))
    {
        command = new SqlCommand((LINQ_TO_GET_FILE).ToString(), sqlca);
        sqlca.Open();
        reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
        try
        {
            while (reader.Read())
            {
                do
                {
                    retval = reader.GetBytes(0, startIndex, buffer, 0, bufferSize);
                    stream.Write(buffer, 0, bufferSize);
                    startIndex += bufferSize;
                } while (retval == bufferSize);
            }
        }
        finally
        {
            reader.Close();
            sqlca.Close();
        }
    }
    stream.Position = 0;
    System.Web.Mvc.FileStreamResult fsr = new System.Web.Mvc.FileStreamResult(stream, "application/pdf");
    return fsr;
}

API-Funktion, die bekommt von GetPDF:

    [AcceptVerbs("GET","POST")]
    public System.Web.Mvc.ActionResult getPdf()
    {
        System.Web.Mvc.ActionResult retVal = GetPDF();
        return retVal;
    }

Für die Anzeige von PDF-server-side:

public ActionResult getChart()
{
    return new PDFController().GetPDF();
}

Den code in das MVC-Anwendung hat sich viel verändert im Laufe der Zeit. Die Art, wie es jetzt ist, geht es nicht um die Bühne, wo er versucht, die Anzeige im browser. Es wird ein Fehler vor.

public async Task<ActionResult> get_pdf(args,keys)
{
    JObject jObj;
    StringBuilder argumentsSB = new StringBuilder();
    if (args.Length != 0)
    {
        argumentsSB.Append("?");
        argumentsSB.Append(keys[0]);
        argumentsSB.Append("=");
        argumentsSB.Append(args[0]);
        for (int i = 1; i < args.Length; i += 1)
        {
            argumentsSB.Append("&");
            argumentsSB.Append(keys[i]);
            argumentsSB.Append("=");
            argumentsSB.Append(args[i]);
        }
    }
    else
    {
        argumentsSB.Append("");
    }
    var arguments = argumentsSB.ToString();
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var response = await client.GetAsync(URL_OF_SERVER+"api/pdf/getPdf/" + arguments).ConfigureAwait(false);
        jObj = (JObject)JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
    }
    return jObj.ToObject<ActionResult>();
}

JSON bekomme ich bei der Ausführung der Methode direkt aus der Web-API-controller:

{
    "FileStream":{
        "_buffer":"JVBER...NjdENEUxAA...AA==",
        "_origin":0,
        "_position":0,
        "_length":45600,
        "_capacity":65536,
        "_expandable":true,
        "_writable":true,
        "_exposable":true,
        "_isOpen":true,
        "__identity":null},
    "ContentType":"application/pdf",
    "FileDownloadName":""
}

Ich verkürzt "_buffer" weil es lächerlich lange.
Ich habe derzeit erhalten die Fehlermeldung, die unten auf der Rückleitung get_pdf(args,keys)

Ausnahmedetails: Newtonsoft.Json.JsonSerializationException: es Konnte keine Instanz des Typs System.Web.Mvc.ActionResult. Der Typ ist ein interface oder eine abstrakte Klasse und kann nicht instanziiert werden. Pfad 'FileStream'.

Zurück, wenn ich eine leere pdf-reader (der Leser war leer. keine Datei), habe ich diese code:

public async Task<ActionResult> get_pdf(args,keys)
{
    byte[] retArr;
    StringBuilder argumentsSB = new StringBuilder();
    if (args.Length != 0)
    {
        argumentsSB.Append("?");
        argumentsSB.Append(keys[0]);
        argumentsSB.Append("=");
        argumentsSB.Append(args[0]);
        for (int i = 1; i < args.Length; i += 1)
        {
            argumentsSB.Append("&");
            argumentsSB.Append(keys[i]);
            argumentsSB.Append("=");
            argumentsSB.Append(args[i]);
        }
    }
    else
    {
        argumentsSB.Append("");
    }
    var arguments = argumentsSB.ToString();
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/pdf"));
        var response = await client.GetAsync(URL_OF_SERVER+"api/webservice/" + method + "/" + arguments).ConfigureAwait(false);
        retArr = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
    }
    var x = retArr.Skip(1).Take(y.Length-2).ToArray();
    /*Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/pdf";
    Response.AppendHeader("Content-Disposition", "inline;filename=document.pdf");
    Response.BufferOutput = true;
    Response.BinaryWrite(x);
    Response.Flush();
    Response.End();*/
    return new FileStreamResult(new MemoryStream(x),MediaTypeNames.Application.Pdf);
    }

Auskommentiert ist code von einigen anderen versucht. Wenn ich mit diesem code, ich wurde wieder ein byte-array der server. Es sah aus wie:

JVBER...NjdENEUx

InformationsquelleAutor der Frage Doctor93 | 2016-03-16

Schreibe einen Kommentar