如何在ASP.NET中创建文件上载接口

如何在ASP.NET中创建文件上载接口,asp.net,file-upload,Asp.net,File Upload,我正在尝试在ASP.NET webforms中创建一个文件上载界面,并希望获得一些关于如何继续的建议 文件上传界面是我正在制作的网站的一部分,用户可以在上面发布广告。该界面是“创建新广告”的一部分,用户最多可以上传6张图片。我只使用asp.net FileUpload服务器控件,因为我试图创建一个控件,该控件在用户禁用javascript时可以工作。这就是背景 所有6个文件的上载在单击按钮时进行。这会将文件存储在临时文件夹(/UserUploads/temp)中,直到用户提交表单(在这种情况下,

我正在尝试在ASP.NET webforms中创建一个文件上载界面,并希望获得一些关于如何继续的建议

文件上传界面是我正在制作的网站的一部分,用户可以在上面发布广告。该界面是“创建新广告”的一部分,用户最多可以上传6张图片。我只使用asp.net FileUpload服务器控件,因为我试图创建一个控件,该控件在用户禁用javascript时可以工作。这就是背景

所有6个文件的上载在单击按钮时进行。这会将文件存储在临时文件夹(/UserUploads/temp)中,直到用户提交表单(在这种情况下,文件将被移动到/UserUploads文件夹并在数据库中引用),或者直到用户点击取消按钮或导航离开(在这种情况下,文件将被删除)

第一个问题是:将文件存储在临时目录中是否是正确的方法?还是有更好的方法在提交父表单之前将临时文件保存在服务器上?我能想到的唯一选择是将文件保存到会话中,但这似乎是杀死服务器的诀窍

第二个问题:我不清楚当用户刚刚关闭浏览器窗口时该怎么办。我希望避免在临时目录中出现大量孤立文件。如果用户没有完成表单提交,是否有办法确保所有文件都被清除?或者我只是需要每隔一段时间清理一次临时目录


第三个问题:我这样做完全错了吗?事实上,有更好的方法来上传多个文件吗?

文件上传总是很烦人。我最近发现了一个很棒的组件,它完成了我认为所有上传组件都应该做的事情

见:

和C#at中的一个样本:

并且,在创建数据库行之前,应该将文件存储在临时文件夹中。为了避免乱七八糟的无用文件,您可以在删除或不删除这些文件时使用windows临时文件夹来删除这些文件

System.IO.Path.GetTempPath()

我建议将文件存储在数据库中,而不是临时文件夹中

不要将它们存储在会话数据库中—信息太多,但要将SessionId包含在文件数据库记录中

因此,您将拥有一个文件数据库,其中包含一个沿着

 Id (int identity field)
 Data (varbinary(max))
 MimeType (varchar(50))
 SessionId (varchar(50))

 UserId ??

然后,您只需编写一个计划的SQL任务来清除会话已过期的映像。

1)如果您使用的是SQL Server,我个人更喜欢将上载的文件存储在varbinary(max)字段中,并按其唯一ID处理。这样您就不必担心名称冲突或数据库与文件系统的不同步。这还允许上载过程独立于父窗体的插入

下面的示例演示如何从
FormView
中的
FileUpload
控件中获取文件流(和元数据),并将其作为参数提供给SQL存储过程。然后,使用实现
IHTTPHandler
的类从数据库检索文件

2) 至于清除临时文件,我会将每个上传的文件与临时主记录相关联,以便将它们绑定在一起。确认真实主控形状后,删除临时主控形状(以及真实主控形状中的参考文件)。然后定期运行SQL代理作业,删除超过X时间的临时主控文件和关联文件

保存:

Protected Sub DetailsView1_ItemInserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewInsertEventArgs) Handles DetailsView1.ItemInserting
    Dim objUploader As FileUpload = DetailsView1.FindControl("fuFile")
    If objUploader.HasFile Then
        Dim strFileName As String = objUploader.PostedFile.FileName
        strFileName = strFileName.Substring(strFileName.LastIndexOf("\") + 1)
        Dim objFileStream As System.IO.Stream = objUploader.PostedFile.InputStream
        Dim arrFileImageByteArray(objFileStream.Length) As Byte
        objFileStream.Read(arrFileImageByteArray, 0, objFileStream.Length)
        e.Values.Insert(0, "FileImage", arrFileImageByteArray)
        e.Values.Insert(1, "FileName", strFileName)
        e.Values.Insert(3, "PostingDate", Now)
        e.Values.Insert(5, "Application", "CorpForms")
    Else
        e.Cancel = True
        objMessages.Add(New StatusMessage(MessageType.Warning, "File Upload canceled.  No file was selected."))
    End If
End Sub
检索:

Public Class FileServiceHandler : Implements IHttpHandler

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        Dim idFileID As Guid
        If context.Request.QueryString("FileID") IsNot Nothing Then
            Dim strFileID As String = context.Request.QueryString("FileID")
            Try
                idFileID = Guid.Parse(strFileID)
            Catch ex As Exception
                Throw New Exception("Unable to parse File ID")
            End Try
        End If

        Dim objConnection As New SqlConnection(ConfigurationManager.ConnectionStrings("PublicWebConnectionString").ConnectionString)
        Dim objCommand As SqlCommand = objConnection.CreateCommand
        Dim objReader As SqlDataReader

        objCommand.CommandType = Data.CommandType.StoredProcedure
        objCommand.CommandText = "spGetUploadedFile"
        objCommand.Parameters.AddWithValue("FileID", idFileID.ToString)

        Dim arrFileImage() As Byte = Nothing
        Dim strFileName As String = String.Empty
        Try
            objConnection.Open()
            objReader = objCommand.ExecuteReader
            While objReader.Read
                If Not IsDBNull(objReader("FileImage")) Then
                    arrFileImage = objReader("FileImage")
                End If
                If Not IsDBNull(objReader("FileName")) Then
                    strFileName = objReader("FileName")
                End If
            End While
        Catch ex As Exception
            Throw New Exception("There was a problem retreiving the file: " & ex.Message)
        End Try
        If objConnection.State <> Data.ConnectionState.Closed Then
            objConnection.Close()
        End If
        If arrFileImage IsNot Nothing Then
            context.Response.Clear()
            context.Response.AddHeader("content-disposition", "attachment;filename=" & strFileName)
            context.Response.BinaryWrite(arrFileImage)
            context.Response.End()
        Else
            context.Response.ContentType = "text/plain"
            context.Response.Write("Unable to retrieve file ID# " & idFileID.ToString)
        End If
    End Sub

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return True
        End Get
    End Property

End Class
公共类FileServiceHandler:实现IHttpHandler
Public Sub-ProcessRequest(ByVal上下文作为HttpContext)实现IHttpHandler.ProcessRequest
将idFileID设置为Guid
如果context.Request.QueryString(“FileID”)不是空的,那么
Dim strFileID为String=context.Request.QueryString(“文件ID”)
尝试
idFileID=Guid.Parse(strFileID)
特例
抛出新异常(“无法分析文件ID”)
结束尝试
如果结束
Dim objConnection作为新的SqlConnection(ConfigurationManager.ConnectionString(“PublicWebConnectionString”).ConnectionString)
Dim objCommand As SqlCommand=objConnection.CreateCommand
Dim objReader作为SqlDataReader
objCommand.CommandType=Data.CommandType.StoredProcess
objCommand.CommandText=“spGetUploadedFile”
objCommand.Parameters.AddWithValue(“FileID”,idFileID.ToString)
Dim arrFileImage()作为字节=无
Dim strFileName为String=String.Empty
尝试
objConnection.Open()
objReader=objCommand.ExecuteReader
而objReader.Read
如果不是IsDBNull(objReader(“FileImage”)),则
arrFileImage=objReader(“FileImage”)
如果结束
如果不是IsDBNull(objReader(“文件名”)),则
strFileName=objReader(“文件名”)
如果结束
结束时
特例
抛出新异常(“检索文件时出现问题:”&ex.Message)
结束尝试
如果objConnection.State Data.ConnectionState.Closed,则
objConnection.Close()
如果结束
如果arrFileImage不是空的,那么
context.Response.Clear()
context.Response.AddHeader(“内容处置”、“附件;文件名=“&strFileName”)
context.Response.BinaryWrite(arrFileImage)
context.Response.End()
其他的
context.Response.ContentType=“text/plain”
context.Response.Write(“无法检索文件ID#”&idFileID.ToString)
如果结束
端接头
公共只读属性IsReusable()作为布尔值实现IHttpHandler.IsReusable
得到
返回真值
结束
端属性
末级
文件检索路径中的Web.Config:

<configuration>
  <system.web>
    <httpHandlers>
      <add verb="GET" path="*" type="MyNamespace.FileServiceHandler" />
    </httpHandlers>
  </system.web>
    <system.webServer>
        <handlers>
            <add name="MyNamespace.FileServiceHandler" path="*" verb="*" type="MyNamespace.FileServiceHandler" resourceType="Unspecified" preCondition="integratedMode" />
        </handlers>
    </system.webServer>
</configuration>