使用webapi下载文件

柠檬

我正在尝试在webapi控制器中编写操作以允许下载文件。但是由于某些奇怪的原因,该代码无法正常工作。

这是我的代码:

<RoutePrefix("api/files")>
Public Class PermitFilesController
    Inherits ApiController

    <Route("download")>
    public function GetFile() As HttpResponseMessage 

        Dim fStream as FileStream =  File.Open("C:\Projects\1234.pdf", FileMode.Open, FileAccess.Read )
        Dim response = Request.CreateResponse(HttpStatusCode.OK)
        response.Content = new StreamContent(fStream)
        'response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        'response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(fStream.Name)
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf")
        return response
    End Function

我尝试仅使用浏览器中的网址进行下载:

localhost:<myport>/api/files/download

错误(在Chrome中为)是错误代码:ERR_CONNECTION_RESET在FF中,它甚至更陌生:它以相同的错误将我重定向到www.localhost.com:/ ...-主机重置了连接

我在代码中放置了一个断点,然后我注意到该代码被调用了两次(一旦我从最后一行的跟踪退出,它就会再次被调用到第一行)。

我在此控制器中还有其他几个动作,它们都可以正常工作。

有人知道我在做什么错吗?


编辑

我启动了Fiddler,现在我的浏览器显示此错误:

[Fiddler] ReadResponse()失败:服务器未返回对此请求的响应。服务器返回了0个字节。


编辑

我想提一下,webapi已集成到旧版经典asp.net应用程序中

初始化代码如下:

在global.asax.Application_Start中

WebApiHelper.Initialize
....
....
Public Class WebApiHelper

  Public Shared Sub Initialize()
    GlobalConfiguration.Configuration.MessageHandlers.Add(New BasicAuthMessageHandler() With { _
             .PrincipalProvider = New MPNAuthProvider() _
           })

    AreaRegistration.RegisterAllAreas()

    WebApiConfig.Register(GlobalConfiguration.Configuration)
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
    RouteConfig.RegisterRoutes(RouteTable.Routes)

    GlobalConfiguration.Configuration.EnsureInitialized()
End Sub

....

MPNAuthProvider用于确保对某些WebAPI控制器的身份验证访问

Public Class MPNAuthProvider
  Implements IProviderPrincipal

  Public Function CreatePrincipal(username As String, password As String) As IPrincipal Implements IProviderPrincipal.CreatePrincipal

    Dim userID As Integer = 0
    If Not UserData.ValidateUser(username, password, userID) Then Return Nothing

    Dim identity = New GenericIdentity(userID)
    Dim principal = New GenericPrincipal(identity, {"User"})
    Return principal
  End Function

End Class

我还有什么要检查的吗?

谢谢

柠檬

初始解决方案

在朱利安·雅各布斯(Julien Jacobs)的建议下,我将我的代码测试到一个单独的独立的webapi项目中,确实该代码是正确的。

因此,我开始研究web.config。

我发现了以下必须注释掉的设置:

<system.web>
....
  <httpModules>
    <add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" />
    <add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
  </httpModules>

<modules runAllManagedModulesForAllRequests="true">
  <remove name="RadUploadModule" />
  <remove name="RadCompression" />
  <add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" preCondition="integratedMode" />
  <add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="integratedMode" />
</modules>

在我对它们进行注释之后,代码开始正常运行。

但是事实证明这不是理想的解决方案,因此请继续阅读...


更新的解决方案

在对该应用程序进行了更多测试之后,我意识到,RadCompression虽然不是绝对必需的,但对于使用Telerik Ajax的Web应用程序来说却非常有用,因为它为所有ajax通信量(配置了viewstate)提供了透明的动态压缩。

因为我禁用了它,所以应用程序开始变慢。

因此,我必须找到一种重新启用RadCompression的方法,但对某些请求(例如用于文件下载的webapi端点)禁用它。

解决方案是:

为RadCompression配置添加特殊的配置部分

<configSections>
 <sectionGroup name="telerik.web.ui">
    <section name="radCompression" type="Telerik.Web.UI.RadCompressionConfigurationSection, Telerik.Web.UI, PublicKeyToken=121fae78165ba3d4" allowDefinition="MachineToApplication" requirePermission="false"/>
  </sectionGroup>
  ....
</configSections>    

在system.web \ httpModules中添加处理程序

<system.web>
  ....
  <httpModules>
    <add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
  </httpModules>

在system.webServer \ modules中添加处理程序

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
    <add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="managedHandler" />
  </modules>
</system.webServer>

关键部分是要为特定请求(URI)禁用RadCompression,请添加一个新的config部分,如下所示

 <telerik.web.ui>
    <radCompression enablePostbackCompression="true">
      <excludeHandlers>
        <!--This will match every api/permitfiles/download file regardless of its location in the web site-->          <add handlerPath="api/permitfiles/download" matchExact="false"/>

      </excludeHandlers>
    </radCompression>
  </telerik.web.ui>

进行了这些更改后,RadCompression在应用程序中全局启用了所有请求,但仅限于特定请求(例如,下载webapi文件)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章