Ich habe ein Web-API-Projekt, das auf einem Server ausgeführt wird. Es soll PDFs aus zwei verschiedenen Arten von Quellen zurückgeben: eine tatsächliche portable Dokumentdatei (PDF) und eine Base64-Zeichenfolge, die in einer Datenbank gespeichert ist. Das Problem, das ich habe, ist das Senden des Dokuments an eine Client-MVC-Anwendung. Der Rest davon sind die Details über alles, was passiert ist und das ich bereits versucht habe.Zurückgeben einer PDF aus einer Web-API-Anwendung
Ich habe Code geschrieben, der diese beiden Formate erfolgreich in C# -Code und dann (zurück) in PDF-Form übersetzt. Ich habe erfolgreich ein Byte-Array übertragen, das eines dieser Dokumente darstellen sollte, aber ich kann es nicht im Browser anzeigen lassen (in einem neuen Tab selbst). Ich bekomme immer eine Art von "kann nicht angezeigt werden" Fehler.
Kürzlich machte ich eine Möglichkeit, die Dokumente auf der Serverseite zu sehen, um sicherzustellen, dass ich es zumindest dazu bringen kann. Es ruft das Dokument in den Code ab und erstellt ein FileStreamResult mit diesem, das dann als ActionResult (impliziter Cast) zurückgegeben wird. Ich habe das, um zu einem serverseitigen MVC-Controller zurückzukehren und warf es in eine einfache Rückkehr (keine Ansicht), die das PDF gerade gut im Browser anzeigt. Wenn Sie jedoch einfach direkt zur Web-API-Funktion wechseln, wird einfach eine JSON-Darstellung eines FileStreamResult zurückgegeben.
Wenn ich versuche, das ordnungsgemäß zu meiner Client MVC-Anwendung zurückzukehren, sagt es mir, dass "_buffer" nicht direkt festgelegt werden kann. Einige Fehlermeldungen dahingehend, dass einige der zurückgegebenen und in ein Objekt geworfenen Eigenschaften privat sind und nicht darauf zugegriffen werden kann.
Die zuvor erwähnte Bytearray-Darstellung der PDF-Datei, wenn sie in eine Base64-Zeichenfolge übersetzt wird, scheint nicht die gleiche Anzahl von Zeichen zu haben wie die Zeichenfolge "_buffer", die von einem FileStreamResult im JSON zurückgegeben wird. Es fehlen am Ende etwa 26k 'A's.
Haben Sie Ideen, wie Sie diese PDF-Datei korrekt wiederherstellen können? Ich kann Code bei Bedarf bereitstellen, aber es muss eine bekannte Möglichkeit geben, eine PDF von einer serverseitigen Web-API-Anwendung an eine MVC-Anwendung auf der Clientseite zurückzugeben und sie als Webseite in einem Browser anzuzeigen.
P.S. Ich weiß, dass die "clientseitige" Anwendung technisch nicht auf der Client-Seite ist. Es wird auch eine Server-Anwendung sein, aber das sollte in diesem Fall keine Rolle spielen. Im Vergleich zum Web-API-Server ist meine MVC-Anwendung "clientseitig".
-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 von GetPDF bekommt:
[AcceptVerbs("GET","POST")]
public System.Web.Mvc.ActionResult getPdf()
{
System.Web.Mvc.ActionResult retVal = GetPDF();
return retVal;
}
Für die Anzeige PDF Server-Seite:
public ActionResult getChart()
{
return new PDFController().GetPDF();
}
Der Code in Die MVC-Anwendung hat sich geändert d viel im Laufe der Zeit. So wie es jetzt ist, kommt es nicht zu dem Punkt, wo es versucht, im Browser anzuzeigen. Es wird vorher ein Fehler angezeigt.
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>();
}
Die JSON ich vom Laufen die Methode erhalten direkt aus dem Web-API-Controller ist:
{
"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":""
}
I "_buffer" verkürzt, weil es lächerlich lang ist. ich zur Zeit die Fehlermeldung unten auf der Rückleitung von get_pdf (args, Schlüssel)
Ausnahmedetails: Newtonsoft.Json.JsonSerializationException: Es konnte keine Instanz des Typs System.Web.Mvc.ActionResult erstellen. Type ist eine Schnittstelle oder abstrakte Klasse und kann nicht instanziiert werden. Pfad 'FileStream'.
Damals, als ich einen leeren PDF-Reader (. Der Leser war leer keine Datei) erhalten verwendet, habe ich diesen 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);
}
kommentiert out Code von einigen anderen Versuchen. Als ich diesen Code verwendete, gab ich ein Byte-Array vom Server zurück. Es sah aus wie:
JVBER...NjdENEUx
einig Beispiel-Code anzeigen, spezifische Fehlermeldungen usw. –
@ Mr.T Ich habe fügte alles hinzu, was ich gerade in meinem Edit hinzufügen könnte. – Doctor93
Warum verwenden Sie 'JObject' überhaupt in' get_pdf'? – Jacob