如何阅读C#中的pdf并将文件返回给用户?
我有一个C#,剑道MVC,剃刀项目。用户点击Kendo网格中的一行,触发change事件,该事件对控制器进行api调用,该控制器读取pdf文件并将其返回给用户下载。我已经用csv文件完成了这项工作,并且工作正常,但是使用pdf时出现错误。有人可以告诉我为什么这个代码不适用于pdf?如何阅读C#中的pdf并将文件返回给用户?
Javascript语言,查看
window.location = "/api/WoApi/GetPDF/1?pdf=" + JSON.stringify(ID);
C#中的控制器
[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;
}
错误消息
> <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>
**更新#1 **
我得到了下面的代码返回一个文件,但我仍然得到同样的错误消息:
string file = "C:\\inetpub\\wwwroot\\Projects\\Attachments\\Invoice_2424.pdf";
var test = new System.Web.Mvc.FilePathResult(file, "application/pdf");
return test;
错误消息:
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>
CSV文件可能会被工作,因为它是基于文本格式,但PDF不是。
看起来你正在使用的网络API,
尝试这种方式,
[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;
}
您也可以尝试返回只是一个文件,指定用正确的MIME类型的URL。
[HttpGet]
public ActionResult GetPDF(string pdf)
{
string file = "C:\\inetpub\\wwwroot\\Projects\\Attachments\\Invoice_2424.pdf";
return File(file, "application/pdf");
}
谢谢。你的例子中是什么类型的“文件”?我试过System.IO.File(文件,“application/pdf”);但它说“文件不能像方法一样使用”。 – boilers222
这是一个'FilePathResult',应该从'using System.Web.Mvc'进来https://msdn.microsoft.com/en-us/library/system.web.mvc.filepathresult(v=vs.118) .aspx –
无法使此工作。如果我只使用File(文件,“application/pdf”),我会得到“不能像方法一样使用”。如果我使用System.Web.Mvc.File(文件,“application/pdf”),我得到的文件不存在于命名空间中。如果我使用System.Web.Mvc.FilePathResult(文件,“application/pdf”),我得到“不能像方法一样使用”错误(FilePathResult来自您发送的链接)。任何想法我做错了什么? – boilers222
什么库是响应和文件?我在Response中遇到一个错误,说它“在当前上下文中不存在”,而File“System.IO.File ...不能像方法一样使用”。请看我与Locke125的对话。听起来像这样会工作,如果我可以得到正确的图书馆。 – boilers222
你在使用ASP.Net MVC吗? –
'Response'和'File(filedata,contentType)'来自System.Web.Mvc。 –