问题
你希望允许用户在你的网站上传并保存文件。
解决方案
通过HttpPostedFileBase.实现上传文件和保存到磁盘。
讨论
在接下来的例子里,之前创建的去添加和更新图书的View将被更新成允许用户选择一个文件并且上传缩略图文件。作为开始,Book/Create view 应该被更新,改变From的编码类型并且为缩略图字段替换掉脚手架 textbox。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
@model MvcApplication.Models.Book @{ ViewBag.Title = "Create"; } < h2 > Create</ h2 > < script src = "@Url.Content(" ~/Scripts/jquery.validate.min.js")" type = "text/javascript" ></ script > < script src=" @Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type = "text/javascript" ></ script > @using (Html.BeginForm("Create", "Books", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.ValidationSummary(true) < fieldset > < legend >Book</ legend > < div class = "editor-label" > @Html.LabelFor(model => model.Title) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Isbn) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Isbn) @Html.ValidationMessageFor(model => model.Isbn) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Summary) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Summary) @Html.ValidationMessageFor(model => model.Summary) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Author) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Author) @Html.ValidationMessageFor(model => model.Author) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Thumbnail) </ div > < div class = "editor-field" > < input type = "file" name = "file" /> @Html.ValidationMessageFor(model => model.Thumbnail) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Price) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Published) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Published) @Html.ValidationMessageFor(model => model.Published) </ div > < p > < input type = "submit" value = "Create" /> </ p > </ fieldset > } < div > @Html.ActionLink("Back to List", "Index") </ div > |
Book/Edit view 也应该以相同的方式被更新,除了添加一个hidden字段(在旧的thumbnail那)。这将用于在BookController中上传新文件之前删除旧的文件。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
@model MvcApplication.Models.Book @{ ViewBag.Title = "Edit"; } < h2 > Edit</ h2 > < script src = "@Url.Content(" ~/Scripts/jquery.validate.min.js")" type = "text/javascript" ></ script > < script src=" @Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type = "text/javascript" ></ script > @using (Html.BeginForm("Edit", "Books", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.ValidationSummary(true) < fieldset > < legend >Book</ legend > @Html.HiddenFor(model => model.ID) < div class = "editor-label" > @Html.LabelFor(model => model.Title) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Isbn) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Isbn) @Html.ValidationMessageFor(model => model.Isbn) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Summary) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Summary) @Html.ValidationMessageFor(model => model.Summary) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Author) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Author) @Html.ValidationMessageFor(model => model.Author) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Thumbnail) </ div > < div class = "editor-field" > < input type = "file" name = "file" /> @Html.HiddenFor(model => model.Thumbnail) @Html.ValidationMessageFor(model => model.Thumbnail) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Price) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price) </ div > < div class = "editor-label" > @Html.LabelFor(model => model.Published) </ div > < div class = "editor-field" > @Html.EditorFor(model => model.Published) @Html.ValidationMessageFor(model => model.Published) </ div > < p > < input type = "submit" value = "Save" /> </ p > </ fieldset > } < div > @Html.ActionLink("Back to List", "Index") </ div > |
由于BooksController中Create和edit功能都是保存上传文件,为了避免重复代码,我们将创建一个新的类。这个类将被创建在Utils文件夹中。Utils文件夹->右击并选择添加→类。这类命名为FileUpload.cs。这个新的类将负责两个关键功能:保存文件,并删除该文件。在下面的例子中,FileUpload类接收一个HttpPostedFile相应的变量,并将它保存到Web服务器上的特定点。另一个功能呢,相反,它接收到的文件的名称,并从Web服务器删除它。