2017-09-19 1 views
0

J'ai un projet C#, Kendo MVC, Razor. L'utilisateur clique sur une ligne dans une grille de Kendo, qui déclenche un événement sur changement, cet événement fait un appel api au contrôleur, qui lit dans un fichier pdf, et le renvoie à l'utilisateur pour le télécharger. J'ai fait cela avec des fichiers csv et ça a bien fonctionné, mais avec pdfs, j'ai une erreur. Quelqu'un peut-il me dire pourquoi ce code ne fonctionne pas avec pdfs?Comment lisez-vous un pdf en C# et renvoyez le fichier à l'utilisateur?

Javascript dans Voir

window.location = "/api/WoApi/GetPDF/1?pdf=" + JSON.stringify(ID); 

C# dans le contrôleur

[HttpGet] 
public System.Net.WebResponse GetPDF(string pdf) 
{ 
    System.Net.WebRequest request = System.Net.WebRequest.Create("C:\\inetpub\\wwwroot\\Projects\\Attachments\\Invoice_2424.pdf"); 
    System.Net.WebResponse response = request.GetResponse(); 

    return response; 
} 

Message d'erreur

> <Error> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'. 
</ExceptionMessage> 
<ExceptionType>System.InvalidOperationException</ExceptionType> 
<StackTrace/> 
<InnerException> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
Type 'System.Net.FileWebResponse' with data contract name 'FileWebResponse:http://schemas.datacontract.org/2004/07/System.Net' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer. 
</ExceptionMessage> 
<ExceptionType> 
System.Runtime.Serialization.SerializationException 
</ExceptionType> 
<StackTrace> 
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c__DisplayClass7.<WriteToStreamAsync>b__6() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token) 
</StackTrace> 
</InnerException> 
</Error> 

** Mise à jour # 1 **

Je suis le code suivant retourner un fichier, mais je obtenir toujours le même message d'erreur:

string file = "C:\\inetpub\\wwwroot\\Projects\\Attachments\\Invoice_2424.pdf"; 
var test = new System.Web.Mvc.FilePathResult(file, "application/pdf"); 
return test; 

Message d'erreur:

Error> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'. 
</ExceptionMessage> 
<ExceptionType>System.InvalidOperationException</ExceptionType> 
<StackTrace/> 
<InnerException> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
Type 'System.Web.Mvc.FilePathResult' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types. 
</ExceptionMessage> 
<ExceptionType> 
System.Runtime.Serialization.InvalidDataContractException 
</ExceptionType> 
<StackTrace> 
at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.DataContractSerializer.GetDataContract(DataContract declaredTypeContract, Type declaredType, Type objectType) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c__DisplayClass7.<WriteToStreamAsync>b__6() at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token) 
</StackTrace> 
</InnerException> 
</Error> 

Répondre

-1

fichier CSV peut être travaillé car il est format texte, mais pdf est pas.

On dirait que vous utilisez l'API Web,

Essayez cette façon,

[HttpGet] 
public HttpResponseMessage Generate() 
{ 

    var stream = new FileStream("C:\\inetpub\\wwwroot\\Projects\\Attachments\\Invoice_2424.pdf", FileMode.Open); 

    var result = new HttpResponseMessage(HttpStatusCode.OK) 
    { 
     Content = new ByteArrayContent(stream.ToArray()) 
    }; 
    result.Content.Headers.ContentDisposition = 
     new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") 
    { 
     FileName = "fileName.pdf" 
    }; 
    result.Content.Headers.ContentType = 
     new MediaTypeHeaderValue("application/octet-stream"); 

    return result; 
} 
+0

De quelles bibliothèques proviennent les réponses et les fichiers? Je reçois une erreur avec Response disant qu'il "n'existe pas dans le contexte actuel" et avec le fichier "System.IO.File ... ne peut pas être utilisé comme une méthode". Voyez aussi ma conversation avec Locke125. Des sons comme ça fonctionneront si je peux juste obtenir les bonnes bibliothèques. – boilers222

+0

Utilisez-vous ASP.Net MVC? –

+0

'Response' et 'File (filedata, contentType)' proviennent de System.Web.Mvc. –

1

Vous pouvez également essayer de revenir juste un fichier spécifiant l'URL avec le type MIME approprié.

[HttpGet] 
public ActionResult GetPDF(string pdf) 
{ 
    string file = "C:\\inetpub\\wwwroot\\Projects\\Attachments\\Invoice_2424.pdf"; 

    return File(file, "application/pdf"); 
} 
+0

Merci. Quel type est "Fichier" dans votre exemple? J'ai essayé System.IO.File (fichier, "application/pdf"); mais il dit "Fichier ne peut pas être utilisé comme une méthode". – boilers222

+0

C'est un 'FilePathResult' et devrait venir de' using System.Web.Mvc' https://msdn.microsoft.com/en-us/library/system.web.mvc.filepathresult(v=vs.118) .aspx –

+0

Impossible de faire fonctionner cela. Si j'utilise juste un fichier (fichier, "application/pdf") je reçois le "ne peut pas être utilisé comme une méthode". Si j'utilise System.Web.Mvc.File (fichier, "application/pdf"), le fichier n'existe pas dans l'espace de noms. Si j'utilise System.Web.Mvc.FilePathResult (fichier, "application/pdf"), je reçois l'erreur "ne peut pas être utilisé comme une méthode" (FilePathResult provient du lien que vous avez envoyé). Une idée de ce que je fais mal? – boilers222