MVC 模型绑定复杂类型,具有 属性 复杂类型集合和 Angular JS
MVC model binding complex type that has a property of complex type collection with Angular JS
我正在使用 Angular JS 和 ASP.NET MVC 开发 Web 应用程序。但是我遇到了模型绑定复杂类型的问题。我正在上传文件列表,基本上是字符串列表。在数据库中,它们(字符串列表和文件列表)是相同的列并且 table 因为我在文件上传后保存了路径。对于字符串,我使用文件路径保存同一列。例如,数据库 table 有 Id(int) 和 Data(string) 列。
然后我将post由AngularJS编辑的字符串数据保存在数据列中,作为文件路径,也保存在数据列中。但关键是,我需要记住顺序。例如,用户添加一个文本字段然后输入值,然后动态添加文件字段然后选择文件,然后添加一个文本字段并再次输入值。所以顺序必须是 [ "text 1 value" , File , "text 2 value" ]。但问题是我们无法绑定混合了文件 HttpPostedFileBase 和文本值字符串的数据列表。所以我所做的是创建如下所示的视图模型。
public class CreateBlogVM
{
[Required]
[MaxLength(250)]
public string Title { get; set; }
[Required]
public ContentModel[] TextContents { get; set; }
[Required]
public ContentFileModel[] Files { get; set; }
}
public class ContentModel
{
public int OrderNo { get; set; }
public string Content { get; set; }
}
public class ContentFileModel
{
public int OrderNo { get; set; }
public HttpPostedFileBase File { get; set; }
}
正如您在上面看到的,CreateBlogVM 将是我现在绑定的 ViewModel。 class 将具有两个复杂类型的属性 - TextContents 和 Files,我在上面解释了我在做什么。因此,为了记住订单,我创建了一个带有 OrderNo 字段的复杂类型(客户端将传递此值),正如您在上面看到的那样,因为我们无法像这样绑定数据列表
[HttpPostedFileBase, String, String, HttpPostedFileBase]
但问题是当我从 Angular js post 数据时,所有值都是 null 并且没有绑定数据。只有 "Title" 值具有约束力。
var textContents = new Array();
var photoContents = new Array();
for(var i=0; i<$scope.rows.length; i++)
{
if($scope.rows[i].type=="text")
{
var value = $scope.rows[i].value;
if (value == "" || value == null) {
showAlert("Text field should not be empty", "danger");
return;
}
else {
var content = { OrderNo: i, Content: value }
textContents.push(content)
}
}
else if($scope.rows[i].type=="photo")
{
var file = $scope.rows[i].file;
if(file==null)
{
showAlert("Photo file is required", "danger");
return;
}
else {
var content = { OrderNo: i, File: file };
photoContents.push(file);
}
}
}
var fd = new FormData();
fd.append('Title', $scope.title);
fd.append("TextContents", textContents);
fd.append("Files", photoContents);
$http.post("/Admin/Blog/Create", fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
})
.success(function () {
})
.error(function () {
});
以上代码是我向服务器提交数据的方式。当我 post 数据时,所有值都是 null 并且 mvc 没有绑定数据。但是当我绑定值而不使用像这样的复杂类型时
public JsonResult Create(HttpPostedFileBase files, String contents, String title)
但是如果我像上面那样绑定,我就不能对文件和字符串内容进行排序。那么我的代码有什么问题呢?如何绑定具有复杂类型对象属性列表的复杂数据?
更改模型,以便在 Content
和关联的 File
之间获得直接关系(不需要 Order
属性)
public class CreateBlogVM
{
[Required]
[MaxLength(250)]
public string Title { get; set; }
public List<FileVM> Files { get; set; }
}
public class FileVM
{
[Required]
public string Content { get; set; }
[Required]
public HttpPostedFileBase Image { get; set; }
}
您只能将简单的 name/value
对附加到 FormData
(而不是 objects 的数组)。在您的循环中,使用
附加数据
var fd = new FormData();
fd.append('Title', $scope.title);
for (var i=0; i<$scope.rows.length; i++)
{
....
var content = $scope.rows[i].value;
fd.append('Files[' + i + '].Content', content);
....
var file = $scope.rows[i].file;
fd.append('Files[' + i + '].Image', file);
}
....
以便您使用与您的 collection 属性 相关的索引器生成名称(Files[0].Content
、Files[0].Image
、Files[1].Content
等)
那么您的 POST 方法签名将是
public JsonResult Create(CreateBlogVM model)
我正在使用 Angular JS 和 ASP.NET MVC 开发 Web 应用程序。但是我遇到了模型绑定复杂类型的问题。我正在上传文件列表,基本上是字符串列表。在数据库中,它们(字符串列表和文件列表)是相同的列并且 table 因为我在文件上传后保存了路径。对于字符串,我使用文件路径保存同一列。例如,数据库 table 有 Id(int) 和 Data(string) 列。
然后我将post由AngularJS编辑的字符串数据保存在数据列中,作为文件路径,也保存在数据列中。但关键是,我需要记住顺序。例如,用户添加一个文本字段然后输入值,然后动态添加文件字段然后选择文件,然后添加一个文本字段并再次输入值。所以顺序必须是 [ "text 1 value" , File , "text 2 value" ]。但问题是我们无法绑定混合了文件 HttpPostedFileBase 和文本值字符串的数据列表。所以我所做的是创建如下所示的视图模型。
public class CreateBlogVM
{
[Required]
[MaxLength(250)]
public string Title { get; set; }
[Required]
public ContentModel[] TextContents { get; set; }
[Required]
public ContentFileModel[] Files { get; set; }
}
public class ContentModel
{
public int OrderNo { get; set; }
public string Content { get; set; }
}
public class ContentFileModel
{
public int OrderNo { get; set; }
public HttpPostedFileBase File { get; set; }
}
正如您在上面看到的,CreateBlogVM 将是我现在绑定的 ViewModel。 class 将具有两个复杂类型的属性 - TextContents 和 Files,我在上面解释了我在做什么。因此,为了记住订单,我创建了一个带有 OrderNo 字段的复杂类型(客户端将传递此值),正如您在上面看到的那样,因为我们无法像这样绑定数据列表
[HttpPostedFileBase, String, String, HttpPostedFileBase]
但问题是当我从 Angular js post 数据时,所有值都是 null 并且没有绑定数据。只有 "Title" 值具有约束力。
var textContents = new Array();
var photoContents = new Array();
for(var i=0; i<$scope.rows.length; i++)
{
if($scope.rows[i].type=="text")
{
var value = $scope.rows[i].value;
if (value == "" || value == null) {
showAlert("Text field should not be empty", "danger");
return;
}
else {
var content = { OrderNo: i, Content: value }
textContents.push(content)
}
}
else if($scope.rows[i].type=="photo")
{
var file = $scope.rows[i].file;
if(file==null)
{
showAlert("Photo file is required", "danger");
return;
}
else {
var content = { OrderNo: i, File: file };
photoContents.push(file);
}
}
}
var fd = new FormData();
fd.append('Title', $scope.title);
fd.append("TextContents", textContents);
fd.append("Files", photoContents);
$http.post("/Admin/Blog/Create", fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
})
.success(function () {
})
.error(function () {
});
以上代码是我向服务器提交数据的方式。当我 post 数据时,所有值都是 null 并且 mvc 没有绑定数据。但是当我绑定值而不使用像这样的复杂类型时
public JsonResult Create(HttpPostedFileBase files, String contents, String title)
但是如果我像上面那样绑定,我就不能对文件和字符串内容进行排序。那么我的代码有什么问题呢?如何绑定具有复杂类型对象属性列表的复杂数据?
更改模型,以便在 Content
和关联的 File
之间获得直接关系(不需要 Order
属性)
public class CreateBlogVM
{
[Required]
[MaxLength(250)]
public string Title { get; set; }
public List<FileVM> Files { get; set; }
}
public class FileVM
{
[Required]
public string Content { get; set; }
[Required]
public HttpPostedFileBase Image { get; set; }
}
您只能将简单的 name/value
对附加到 FormData
(而不是 objects 的数组)。在您的循环中,使用
var fd = new FormData();
fd.append('Title', $scope.title);
for (var i=0; i<$scope.rows.length; i++)
{
....
var content = $scope.rows[i].value;
fd.append('Files[' + i + '].Content', content);
....
var file = $scope.rows[i].file;
fd.append('Files[' + i + '].Image', file);
}
....
以便您使用与您的 collection 属性 相关的索引器生成名称(Files[0].Content
、Files[0].Image
、Files[1].Content
等)
那么您的 POST 方法签名将是
public JsonResult Create(CreateBlogVM model)