我有一个MVC主 - 详细视图,基于主细节模型和每个详细记录的删除按钮。
按下删除按钮,我发布要删除的ID和整个模型,我从模型中删除正确的详细记录并将其返回到视图。
问题是视图呈现不正确的详细记录。 无论按下什么内容,它实际上都会删除最后一条记录。
模特
public class Customer
{
public int ID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public List<Contact> CustomerContacts { get; set; }
}
public class Contact
{
public int ID { get; set; }
public int CustomerID { get; set; }
public string ContactName { get; set; }
[Required]
public string ContactEmail { get; set; }
}
控制器操作
public ActionResult Index()
{
Customer customer = new Customer(){ ID=1, Name="CustOne", Description="Descr1"};
Contact contact1 = new Contact() { ID = 1, CustomerID = 1, ContactName = "Cont_One", ContactEmail = "a@b.com" };
Contact contact2 = new Contact() { ID = 2, CustomerID = 1, ContactName = "Cont_Two", ContactEmail = "b@c.com" };
customer.CustomerContacts = new List<Contact>();
customer.CustomerContacts.Add(contact1);
customer.CustomerContacts.Add(contact2);
return View(customer);
}
[HttpPost]
public ActionResult Index(string btnSubmit, Customer customer)
{
int CustomerContactID = Convert.ToInt32(btnSubmit);
if (!ModelState.IsValid)
{
return View(customer);
}
int indexOfCust = customer.CustomerContacts.FindIndex(c => c.ID == CustomerContactID);
customer.CustomerContacts.RemoveAt(indexOfCust);
return View(customer);
}
观点:
@model MyMVCProblem.Models.Customer
@{
ViewBag.Title = "Home Page";
}
<br />
@using (Html.BeginForm())
{
<table>
<tr>
<td>Name</td>
<td>
@Html.TextBoxFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)
</td>
</tr>
<tr>
<td>Description</td>
<td>
@Html.TextAreaFor(m => m.Description)
</td>
</tr>
</table>
for (int i = 0; i < Model.CustomerContacts.Count; i++)
{
<table>
<tr>
<td>Contact Name</td>
<td>
@Html.HiddenFor(m => m.CustomerContacts[i].ID)
@Html.TextBoxFor(m => m.CustomerContacts[i].ContactName)
@Html.ValidationMessageFor(m => m.CustomerContacts[i].ContactName)
</td>
</tr>
<tr>
<td>Contact e-mail</td>
<td>
@Html.TextBoxFor(m => m.CustomerContacts[i].ContactEmail)
@Html.ValidationMessageFor(m => m.CustomerContacts[i].ContactEmail)
</td>
</tr>
</table>
<button type="submit" name="btnSubmit" id="Submit" value="@Model.CustomerContacts[i].ID">Delete</button>
<br /><br />
}
}
答案 0 :(得分:2)
一种可能的解决方案是清除ModelState 示例:
[HttpPost]
public ActionResult Index(string btnSubmit, Customer customer)
{
int CustomerContactID = Convert.ToInt32(btnSubmit);
if (!ModelState.IsValid)
{
return View(customer);
}
int indexOfCust = customer.CustomerContacts.FindIndex(c => c.ID == CustomerContactID);
customer.CustomerContacts.RemoveAt(indexOfCust);
ModelState.Clear();
return View(customer);
}
答案 1 :(得分:1)
我建议的东西,但不确定这是否真的能解决你的问题,是使用部分视图和$ .ajax调用delete函数。换句话说,您可以在部分视图中呈现CustomerContacts表,该视图使用List模型。这样,在第一次加载页面时就可以使用
<div id="customerContactsList">
@{ Html.RenderPartial("_CustomerContactsList", Model.CustomerContacts); }
</div>
然后你可以让你的循环在那个部分中呈现表格。实现此功能后,您可以在控制器中使用POST方法,例如
[HttpPost]
public ActionResult DeleteCustomerContact(int id)
{
// Call the delete function
// e.g. DeleteContact(id);
// Then re-read your contacts list
List<CustomerContacts> contacts = GetContacts(...);
return PartialView("_CustomerContactsList", contacts);
}
在表单代码上,为删除按钮添加一个回调来调用所述方法,并且在成功时只渲染带有列表的局部视图。只需要添加一个ajax调用并将其绑定到click事件
$('btnDelete').click(function() {
$.ajax({
url: 'DeleteCustomerContact',
type: 'POST',
data: customerContactId,
dataType: 'text',
contentType: 'application/json; charset=utf-8',
success: function ( result ) {
$('#customerContactsList').html(result);
},
error: function () {
alert('error');
}
});
});
现在这不能保证解决您的问题,因为我不确定实际原因是什么,但这是一个非常明确的方法,因为一旦调用delete方法,客户联系人列表总是会刷新。
希望它有所帮助。