2009-07-30 6 views
2

ご挨拶。アクションを表示ページから削除する

私の頭をMVCのまわりでラップしようとすると、レコードを表示する単純な追加/削除ページが実装されました。これにより、ユーザーは単純なタスクを実行するために移動しなくても、ほとんどのことを1つのページから簡単に行うことができます。このページでは、正常に動作するレコード(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()); 
    } 
} 

だから、企業のページから、私はちょうど作業を行うコントローラでこのアクションに私を指示した後、私が以前にいたビューを返しますActionLinkのを持っていますで。私は、新しいレコードを追加するために行くとき、それはさせませんので

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

これは、良いではありません。そこで問題は、私が削除した後レコードが私の実際のURLは次のように終わるということです私。私はレコードを追加することができます私のコントローラのアクションは、次のようになります

[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> 

私はアクションリンクを持っています(編集したものを無視してください)。レコードを削除してすぐにレコードを削除しようとすると、URLが間違っていると仮定しているため、動作しません。私はここで間違って何をしていますか?あなたが戻ってユーザーをリダイレクトしていないのはなぜ

FIXED

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

     _contractsControlRepository.DeleteBusiness(businessToDelete); 

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

答えて

4

削除がsucceded場合はリストの企業ページをか?

+0

ビンゴ。修正を示すために質問を更新します。 – Kezzer

1

私はMaciejkowの答えを二度目にリダイレクトするため、ユーザーがページを更新しようとするとデータを再投稿する機会がなくなります。

もう1つのことは、リンク(つまりGET)にアクションを削除しないということです。これらのアクションは常にPOST(キャッシュされた理由でページ上のリンクを自動ツールで追跡できる場合があります)なので、隠しフィールドでbusinessToDelete変数を使用して、削除を行うミニフォームのボタン。

+0

少し面倒ですが、それはありませんか?しかし、私はあなたの声明の中の論理を完全に理解しています。この例では、各エントリの横にある削除ボタンを持つデータテーブルを作成すると便利です。実際、これは実際にシステムの要件です。 – Kezzer

+0

NerdDinnerチュートリアルでは、HTTP GETでDELETEを許可しないという特定の理由は、「Webクローラーからの保護を慎重にしたい...誤ってリンクをたどるとデータが削除されてしまう...」 –

+0

確かに良い理由。しかし、もし私がすべてのボタンを削除したければ?私は本当にそれぞれのフォームとボタンを提供する必要がありますか?フォームとは対照的に、それらをハイパーリンクとして必要とします。 – Kezzer

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: /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)); 
    }   
} 
関連する問題