我有4 Models
Post,Car,Category,SubCategory。 Car有一些额外的属性,并且还继承Post,Post Model
中的所有内容,包括CategoryID和SubCategoryID的属性。我需要创建一个View
,可以动态更改以便能够保存汽车。用户首先看到两个dropdown
列表中的类别和子类别,在选中后,它会加载右PartialView
。它很好,但由于一些原因我无法将其保存在数据库中。
首先,我不知道在哪里为页面声明model
,如果它在创建View
中 - 意味着它无法更改,因为我只希望输入字段出现并动态更改但不应重新加载页面。这也意味着Car Model
有一些额外的属性,string
和int
,我无法创建具有ViewModel
所有可能属性的string
不是nullable
。
如果在model
中声明PartialView
,则表示我可以为Car和Post创建单独的ViewModel
,但表单标记将位于PartialView
和{{1类别和子类别的列表在创建dropdown
中的此表单标记之外,因为它不应更改。当表单发布时,我收到错误,因为我使用View
来获取CategoryID和SubCategoryID。我需要以某种方式解决这个问题。
我尝试使用Request.Form["..ID"];
,但是出现了类别ID和子类别ID的空条目错误,只传递了表单标记中的值。
Ajax
Models
创建public class Category
{
public int CategoryID { get; set; }
public string Name { get; set; }
}
public class SubCategory
{
public int SubCategoryID { get; set; }
[Required]
public string Name { get; set; }
[ForeignKey("CategoryID")]
public virtual Category Category { get; set; }
public int? CategoryID { get; set; }
}
public class Post
{
public int PostID { get; set; }
public string Title { get; set; }
public string Msg { get; set; }
[DataType(DataType.Currency)]
public decimal Price { get; set; }
public string PostCode { get; set; }
[DataType(DataType.ImageUrl)]
public string MainPhotoPath { get; set; }
public DateTime PostedAt { get; set; }
public bool Active { get; set; }
public string ApplicationUserId { get; set; }
[ForeignKey("SubCategoryID")]
public virtual SubCategory SubCategory { get; set; }
public int SubCategoryID { get; set; }
public int CategoryID { get; set; }
public string CityName { get; set; }
}
public class Car : Post
{
public string Make { get; set; }
public int Year { get; set; }
public int EngineSize { get; set; }
public int Mileage { get; set; }
public string FuelType { get; set; }
public string Transmission { get; set; }
}
View
选择类别和子类别的菜单
@using Mvc.CascadeDropDown
@{
ViewBag.Title = "Create";
}
<div class="row">
<div class="col-lg-12">
<div class="text-center">
<h2>Add a new Post</h2>
<h3 id="CityDiv">City: @ViewBag.Location</h3>
</div>
<div class="col-lg-12">
@Html.Action("Menu")
<div id="createNewPost">
</div>
</div>
</div>
</div>
<script type="text/javascript">
$("#SubCategoryID").click(function () {
var selectedSubCategory = $("#SubCategoryID").val();
if (selectedSubCategory == 4) {
var url = "/Posts/CarPartial/";
$.ajax({
url: url,
cache: false,
type: "POST",
success: function (data) {
$("#createNewPost").html(data);
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
else {
var url = "/Posts/PostPartial/";
$.ajax({
url: url,
cache: false,
type: "POST",
success: function (data) {
$("#createNewPost").html(data);
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
});
$("#CreatePostFormID").submit(function () {
var _categoryId = $("#CategoryID").val();
var _subcategoryId = $("#SubCategoryID").val();
var url = "/Posts/Create/";
$.ajax({
url: url,
data: { cId: _categoryId, subId: _subcategoryId },
cache: false,
type: "POST",
success: function (data) {
alert("ok");
},
error: function (reponse) {
alert("error : " + reponse);
}
});
});
</script>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
如果子类别仅需要帖子@model PostIt.Models.DropDown
<h4>
Please choose a category first
</h4>
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.CategoryModel, new SelectList(Model.CategoryModel, "CategoryID", "Name"), new { @id = "CategoryID", @class = "form-control col-md-offset-2 margin-bottom" })
<select id="SubCategoryID" name="SubCategoryID" class="form-control col-md-offset-2 margin-bottom"></select>
}
<script language="javascript" type="text/javascript">
$(window).load(function () {
$("#CategoryID").click(function () {
var _categoryId = $("#CategoryID").val();
var procemessage = "<option value='0'> Please wait...</option>";
$("#SubCategoryID").html(procemessage).show();
var url = "/Posts/GetSubCategoryById/";
$.ajax({
url: url,
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
var markup = "<option value='0'>Select a subcategory</option>";
for (var x = 0; x < data.length; x++) {
markup += "<option class='selectedSubCategory' value=" + data[x].Value + ">" + data[x].Text + "</option>";
}
$("#CategoryID").val(_categoryId);
$("#SubCategoryID").html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
});
});
</script>
,则PartialView
createNewPost
内加载 div
Model
@model PostIt.Models.PostViewModel
@using (Html.BeginForm("Create", "Posts", FormMethod.Post, new { enctype = "multipart/form-data", id = "CreatePostFormID" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
@Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Msg, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Msg, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Msg, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PostCode, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PostCode, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PostCode, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.MainPhotoPath, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBoxFor(model => model.MainPhotoPath, new { type = "file" })
@Html.ValidationMessageFor(model => model.MainPhotoPath, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" id="SubmitID" /> | @Html.ActionLink("Cancel", "Index")
</div>
</div>
</div>
}
创建帖子。
ActionMethod
答案 0 :(得分:1)
我不是故意要转储过多的代码而且我已经从中吸取了教训......
如果有人正在努力解决同样的问题,答案如下:
使用model
标记声明PartialView
中的@using (Html.BeginForm
,以便您可以根据model
创建表单。创建表单可以通过Ajax
动态更改,因此基本上一个创建表单可以处理任何模型。
由于dropdown
列表包含必要的CategoryID和SubCategoryID的值在表单标记之外,因此它不会传递给控制器,即使在顶部使用Ajax
,它也只会破坏它。首先它会调用ActionResult
,但没有为ID传递值,返回错误,甚至不会调用Ajax
函数。
要解决此问题,在右侧PartialView
的控制器中创建model
时,我会随身携带ID值。
Ajax
致电发布PartialView
var url = "/Posts/PostPartial/";
$.ajax({
url: url,
data: { cid : selectedCategory, sid : selectedSubCategory },
cache: false,
type: "POST",
success: function (data) {
$("#createNewPost").html(data);
},
error: function (reponse) {
alert("error : " + reponse);
}
});
控制器内的 ActionResult
返回右PartialView
。在这种情况下,它是一个帖子。
public ActionResult PostPartial(int cid, int sid)
{
PostViewModel viewmodel = new PostViewModel();
viewmodel.CategoryID = cid;
viewmodel.SubCategoryID = sid;
return PartialView("CreatePost", viewmodel);
}
上面的Create ActionResult
工作正常,但是名为PostViewModel的ViewModel
必须具有CategoryID和SubCategoryID的属性,并且控制器中必须bind
属性才能创建ActionResult
。