在ASP.NET 2.0中操作数据之五十四:添加新记录时包含一个文件上
从DetailsView控件的智能标签选择“编辑模板”,从下拉列表选择BrochurePath TemplateField的InsertItemTemplate模板,将模板里的TextBox删除,从工具箱拖一个FileUpload控件到页面,设其ID为BrochureUpload。类似的,为Picture TemplateField的InsertItemTemplate模板添加一个ID为PictureUpload的FileUpload控件。
完成添加后,这2个TemplateField的声明代码应该和下面的差不多: <asp:TemplateField HeaderText="Brochure" SortExpression="BrochurePath"> <InsertItemTemplate> <asp:FileUpload ID="BrochureUpload" runat="server" /> </InsertItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Picture"> <InsertItemTemplate> <asp:FileUpload ID="PictureUpload" runat="server" /> </InsertItemTemplate> </asp:TemplateField> 当用户添加一个新类时,我们希望确保上传的图片和说明小册子是恰当的文件类型。对说明小册子,必须是PDF类型;对图片,我们需要用户上传一个image文件。那是不是image文件必须是某个特定的类型呢,比如GIF或JPG?考虑到其它不同类型的文件,我们需要扩展表Categories的列以包含这些类型的文件,同时我们可以在页面DisplayCategoryPicture.aspx里通过Response.ContentType将这些文件发送到客户端。由于表Categories现在并没有这样的列,我们只有限制用户上传指定为某种类型的image文件。表Categories里现有的images为位图,不过使用JPG类型或许更恰当。 当用户上传的文件类型不正确时,我们将取消插入操作,并显示一个提示信息。在DetailsView控件下添加一个Label Web控件,设ID为UploadWarning,清除Text属性,设CssClass属性为“Warning”, 再将Visible和EnableViewState属性都设为false。Warning CSS定义在Styles.css里,作用是将文字显示为粗斜体,红色大号字。 注意:最理想的情况是将CategoryName和Description BoundFields都转换为TemplateFields,达到定制插入界面的目的。比如,对Description插入界面来说,使用一个允许分行的文本框或许更好;对CategoryName插入界面,因为CategoryName不允许为NULL值,我们应该添加一个RequiredFieldValidator控件,以确保输入类的名称。这些步骤都留给读者做练习,更深入的探讨请参考前面的教程之20《定制数据修改界面》 第6步:将上传的小册子保存在服务器的文件系统 但用户键入相关的类别信息,点Insert按钮后,发生页面回传,接着发生一连串的插入流程。首先,DetailsView控件的ItemInserting event事件发生;接着,调用ObjectDataSource控件的Insert()方法,它将导致Categories表添加新记录;最后,发生DetailsView控件的ItemInserted event事件。 在调用ObjectDataSource控件的Insert()方法以前,我们必须确保用户已经上传了恰当的文件并保存在服务器的文件系统。为此,我们为DetailsView控件的ItemInserting事件创建一个事件处理器,添加如下的代码: // Reference the FileUpload control FileUpload BrochureUpload = (FileUpload)NewCategory.FindControl("BrochureUpload"); if (BrochureUpload.HasFile) { // Make sure that a PDF has been uploaded if (string.Compare(System.IO.Path.GetExtension (BrochureUpload.FileName), ".pdf", true) != 0) { UploadWarning.Text = "Only PDF documents may be used for a category's brochure."; UploadWarning.Visible = true; e.Cancel = true; return; } } 代码首先引用DetailsView控件模板里名为BrochureUpload的FileUpload控件,如果已经上传了文件,就检查FileUpload控件的extension是否为“.PDF”, 如果不是则取消插入操作并退出。 注意:通过检查文件的扩展名(extension)来确保用户上传的为PDF文件的做法并不是万全之策。比如,可能用户的确上传的是PDF文件,只不过其扩展名为.Brochure;或者用户提供的并不是PDF文件,却使用.pdf的扩展名。保险的做法是通过编程对文件内容做最后一次检查。如此一来,虽然彻底,但稍嫌过头(overkill)。在绝大多数情况下,检查文件扩展名就已经足够了。 就像在教程《使用FileUpload上传文件》里讨论的那样,将文件保存在文件系统里时要特别小心,以免覆盖别人上传的文件。本节,我们尝试对上传文件使用一个已经使用的名字,在名字末尾添加一个数字,以示区别。举例,如果在文件夹~/Brochures里存在一个名为Meats.pdf的文件,上传文件时我们取名为Meats-1.pdf,如果文件夹里恰好也存在一个Meats-1.pdf文件,我们就取名为Meats-2.pdf,以此类推,直到文件名唯一为止。 下面的代码使用File.Exists(path)方法来判断是否已经存在同名文件,如果存在,就重新命名,直到名字唯一为止: const string BrochureDirectory = "~/Brochures/"; string brochurePath = BrochureDirectory + BrochureUpload.FileName; string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName); int iteration = 1; while (System.IO.File.Exists(Server.MapPath(brochurePath))) { brochurePath = string.Concat(BrochureDirectory, fileNameWithoutExtension, "-", iteration, ".pdf"); iteration++; } 一旦找到唯一的文件名后,立即将文件保存在文件系统,同时更新ObjectDataSource控件的InsertParameter参数brochurePath的值,以便将文件名写入数据库。就像在教程《使用FileUpload上传文件》里看到的一样,可以使用FileUpload控件的SaveAs(path)方法来保存文件。使用e.Values集合来更新ObjectDataSource控件的参数brochurePath。 // Save the file to disk and set the value of the brochurePath parameter BrochureUpload.SaveAs(Server.MapPath(brochurePath)); e.Values["brochurePath"] = brochurePath; 第7步:将上传的图片保存到数据库 (编辑:徐州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |