从视图页面删除操作

时间:2009-07-30 10:34:00

标签: asp.net-mvc

问候。

为了试图围绕MVC,我刚刚实现了一个简单的添加/删除页面,它也可以查看记录。这使得用户可以更轻松地从一个页面执行大多数操作,而无需离开以执行简单任务。该页面允许您添加一个工作正常的记录(具有ID和名称的业务)。但是,当我删除记录时,我已完成以下操作以允许删除:

<%= Html.ActionLink("delete", "DeleteBusiness", new { businessToDelete = B.BusinessID }) %>

这可以正常删除记录。这就是我的控制器操作的样子:

public ActionResult DeleteBusiness(string businessToDelete)
{
     try
     {
       if (!ModelState.IsValid)
         return View("Businesses", _contractsControlRepository.ListBusinesses());

         _contractsControlRepository.DeleteBusiness(businessToDelete);

         return View("Businesses", _contractsControlRepository.ListBusinesses());
     }
     catch
     {
       return View("Businesses", _contractsControlRepository.ListBusinesses());
     }
}

所以从Businesses页面我有一个ActionLink,它只是指导我在控制器中完成这项工作,然后返回我以前的视图。然后问题是一旦我删除了记录,我的实际网址就像这样:

http://localhost:3340/Accounts/ContractsControl/DeleteBusiness?businessToDelete=TEST

这不好,因为当我去添加新记录时,它不会让我。我允许添加记录的控制器操作如下所示:

  [AcceptVerbs(HttpVerbs.Post)]
  public ActionResult Businesses(Business business)
  {
    try
    {
      if (!ModelState.IsValid)
        return View(_contractsControlRepository.ListBusinesses());

      _contractsControlRepository.CreateBusiness(business);
      return View(_contractsControlRepository.ListBusinesses());
    }
    catch
    {
      return View(_contractsControlRepository.ListBusinesses());
    }
  }

任何post请求都被视为创建新记录。它是否正确?以下是我的观点,最重要的是:

<% using (Html.BeginForm())
   { %>

  <fieldset class="inline-fieldset">
    <legend>Add Business</legend>

    <p>
    <label for="ID">ID</label>

    <%= Html.TextBox("BusinessID", null, new { style = "width:50px;", @class = "uppercase", maxlength = "4" })%>
    <%= Html.ValidationMessage("BusinessID", "*")%>

    <label for="Business">Business</label>

    <%= Html.TextBox("BusinessCol")%>
    <%= Html.ValidationMessage("BusinessCol", "*")%>

    <input type="submit" value="Add" />
  </p>

  <%= Html.ValidationSummary("Uh-oh!") %>

  </fieldset>

<% } %>

<table>
<tr>
<th>ID</th>
<th>Business</th>
<th></th>
<th></th>
</tr>
  <% foreach (Business B in ViewData.Model)
  { %>
    <tr>
      <td><%= B.BusinessID %></td>
      <td><%= B.BusinessCol %></td>
      <td class="edit"><%= Html.ActionLink("edit", "EditBusiness", new { id = B.BusinessID }) %></td>
      <td class="delete"><%= Html.ActionLink("delete", "DeleteBusiness", new { businessToDelete = B.BusinessID }) %></td>
    </tr>
  <% } %>
</table>

正如您在最底部看到的,我有动作链接(忽略编辑链接)。因此,如果我删除一条记录,然后立即尝试添加一条记录,它将无法正常工作,因为(我假设)该网址是错误的。我在这里做错了什么?

固定

  public RedirectToRouteResult DeleteBusiness(string businessToDelete)
  {
    try
    {
      if (!ModelState.IsValid)
        return RedirectToAction("Businesses");

      _contractsControlRepository.DeleteBusiness(businessToDelete);

      return RedirectToAction("Businesses");
    }
    catch
    {
      return RedirectToAction("Businesses");
    }
  }

3 个答案:

答案 0 :(得分:4)

如果删除成功,为什么不将用户重定向回List Businesses页面?

答案 1 :(得分:1)

我是第二个maciejkow的回答,重定向消除了用户在尝试刷新页面时重新发布数据的机会。

另一件事,我不会在链接中放置删除操作(即GET),这些操作应始终是POST(自动工具有时可以按照页面上的链接出于缓存原因),所以我会包装一个使用迷你形式的按钮进行删除,将businessToDelete变量放在隐藏字段中。

答案 2 :(得分:1)

我刚刚浏览了NerdDinner教程。

在那里,删除控制器

// GET: /Dinners/Delete/1
public ActionResult Delete(int id)
{
    Dinner dinner = dinnerRepository.GetDinner(id);
    if (dinner == null)
    {
        return View("NotFound");
    }
    else
    {
        return View(dinner);
    }
}


    // POST: /Dinners/Delete/1
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Delete(int id, string confirmButton)
    {
        Dinner dinner = dinnerRepository.GetDinner(id);

        if (dinner == null)
        {
            return View("NotFound");
        }

        dinnerRepository.Delete(dinner);
        dinnerRepository.Save();

        return View("Deleted");
    }

和Get的控制器是。

// GET: /Dinners/Edit/2
[Authorize]
public ActionResult Edit(int id)
{

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (!dinner.IsHostedBy(User.Identity.Name))
    {
        return View("InvalidOwner");
    }

    return View(new DinnerFormViewModel(dinner));
}

//
// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post),Authorize]
public ActionResult Edit(int id, FormCollection formValues)
{
    Dinner dinner = dinnerRepository.GetDinner(id);
    if (!dinner.IsHostedBy(User.Identity.Name))
    {
        return View("InvalidOwner");
    }
    try
    {

        UpdateModel(dinner);
        dinnerRepository.Save();

        return RedirectToAction("Details", new { id = dinner.DinnerID });
    }
    catch (Exception ex)
    {
        foreach (var issue in dinner.GetRuleViolations())
        {
            ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
        }
        return View(new DinnerFormViewModel(dinner));
    }           
}