2012-02-22 2 views
0

私はFreemanとSandersonのPro ASP.NET MVC3 Frameworkの本を読んでいて、いくつかのコードについて質問があります。これは初心者の質問かもしれませんが、私はこの本の例に関する人々の質問が役に立つことを発見しました。MVC3 SportsStoreの例:AddToCartにHttpPostとマークする必要がありますか?

SportsStoreの例のカートコントローラは、CheckoutアクションをHttpPostとしてマークしますが、AddToCartアクションもRemoveFromCartアクションもHttpPostとしてマークされていません。しかし、彼らはフォーム提出を受け取り、基本的なカートモデルを修正する。それはHttpPostをいつ使うべきかという定義ですか?

許可されているモデル変更は、この例ではデータベースに保持されていませんが、単純化のためです。モデルは、Checkoutアクションと同じようにAddToCartアクションとRemoveFromCartアクションで変更されています。

btw - コードはHttpPostの有無にかかわらず同じです。したがって、これは主にベストプラクティスに関する質問です。

以下

帳から、最終的なコントローラクラスである:...私は本からリコール場合は、サンダーソン& PALは、セッションベースのカートのオブジェクトにアクセスするための特別なModelBinderを使用

namespace SportsStore.WebUI.Controllers 
{ 
    public class CartController : Controller 
    { 
     private IProductRepository repository; 
     private IOrderProcessor orderProcessor; 

     public CartController(IProductRepository repo, IOrderProcessor proc) 
     { 
      repository = repo; 
      orderProcessor = proc; 
     } 

     public RedirectToRouteResult AddToCart(Cart cart, int productID, string returnUrl) { 
      Product product = repository.Products 
       .FirstOrDefault(p => p.ProductID == productID); 

      if (product != null) { 
       cart.AddItem(product, 1); 
      } 
      return RedirectToAction("Index", new {returnUrl}); 
     } 


     public RedirectToRouteResult RemoveFromCart(Cart cart, int productId, string returnUrl) 
     { 
      Product product = repository.Products 
       .FirstOrDefault(p => p.ProductID == productId); 

      if (product != null) 
      { 
       cart.RemoveLine(product); 
      } 
      return RedirectToAction("Index", new { returnUrl }); 
     } 

     public ViewResult Index(Cart cart, string returnUrl) 
     { 
      return View(new CartIndexViewModel 
      { 
       Cart = cart, 
       ReturnUrl = returnUrl 
      }); 
     } 

     public ViewResult Summary(Cart cart) 
     { 
      return View(cart); 
     } 

     [HttpPost] 
     public ViewResult Checkout(Cart cart, ShippingDetails shippingDetails) 
     { 
      if (cart.Lines.Count() == 0) 
      { 
       ModelState.AddModelError("", "Sorry your cart is empty"); 
      } 

      if (ModelState.IsValid) 
      { 
       orderProcessor.ProcessOrder(cart, shippingDetails); 
       cart.Clear(); 
       return View("Completed"); 
      } 
      else 
      { 
       return View(shippingDetails); 
      } 
     } 

     public ViewResult Checkout() 
     { 
      return View(new ShippingDetails()); 
     } 
    } 
} 

答えて

0

ことではありません右?

技術的には、このアクションは基本となるアプリケーションに影響しないため、本の実装は間違いではありません。セッションベースのストレージは揮発性であるため、アクションは永続的な変更を表すものではありません。

実際のアプリケーションでは、カートアイテムの追加/削除アクションに、偶数のHttpPutとHttpDelete(または非冪等のHttpPost)を使用することがあります。しかし、実際のアプリケーションでは、これらのことを揮発性のセッションストレージに保存していない可能性があります。

私は、この本は大量のストレージテーブルを作成せずにアプリケーションの例を表示しようとしていると思います。

+0

はい、カートはセッションオブジェクトとして保存されます。しかし、Cartオブジェクトが最終的にデータベーステーブルに保存された場合、これらの関数はHttpPost、正しいはずですか? –

+0

絶対に。または、偶発的な操作を行うことができれば、カートに追加する場合はHttpPut、カートから削除する場合はHttpDeleteを使用できます。しかし、あなたの行動が冪等でない場合は、HttpPostを使用してください。 – danludwig

+0

私に冪等級という言葉を紹介してくれてありがとう。 :) –

0

私はあなたのコード内のチェックアウトのActionResultもAddToCartもRemoveFromCartアクションはありませんHTTPGET

public ViewResult Checkout() 
    { 
     return View(new ShippingDetails()); 
    } 

にデフォルト設定されてCartController内で使用可能であるアクションもあるようHttpPost]で飾られていると信じていますHttpPostとしてマークされているため、HttpGetはモデルバインドのために利用できません。

+0

質問は2つのチェックアウトアクションについてではなく、AddToCartアクションとRemoveFromCartアクションに関するものです。 –

+0

あなたの質問に言及しました - SportsStoreの例のカートコントローラはCheckoutアクションをHttpPostとしてマークしますが、AddToCartアクションとRemoveFromCartアクションのどちらもHttpPostとしてマークされていません –

-1

私の限られた経験では、一貫性のために[HttpPost]とマークする必要があります。本の他の例では、2つのアクションメソッドが同じ名前を持つ状況がある。

このようにHttpPostメソッドをマークすると、メソッドの名前を簡単に指定できます。この例では、1つのAddToCartメードしかないので、区別する必要はほとんどありませんでした。

関連する問題