<Div class = "item">
Each of the "Add to cart" buttons will post the relevant productid to an action called addtocart on a controller class called cartcontroller. note that HTML. beginform () renders forms with a method attribute of post by default, though it also has an overload that lets you specify get instead
§ 5. 2.3 creating a custom model Binder
ASP. net mvc has a mechanic calledModel binding. Is used to prepare the parameters passed to action methods. This is how it was possible in Chapter 2 to receiveGuestresponseInstance parsed automaticallyFrom the incoming HTTP request.
Add the following class to the infrastructure folder:
namespace sportsstore. webui. infrastructure {public class cartmodelbinder: imodelbinder {private const string cartsessionkey = "_ cart"; # region imodelbinder member public object bindmodel (controllercontext controllerco Ntext, modelbindingcontext bindingcontext) {If (bindingcontext. model! = NULL) throw new invalidoperationexception ("Cannot update instances"); cart = (Cart) controllercontext. httpcontext. session [cartsessionkey]; If (Cart = NULL) {cart = new cart (); controllercontext. httpcontext. session [cartsessionkey] = cart;} return cart ;}# endregion }}
Now you can understandCartmodelbinderSimply as a kindCart factoryThat encapsulates the logic of giving each visitor a separate instance stored in their session collection.
Add the following line to yourGlobal. asax. CS file'sApplication_start ()Method, nominatingCartmodelbinderAs the binder to use whenever a cart instance is required:
Modelbinders. binders. Add (typeof (Cart), new cartmodelbinder ());
§ 2.4 creating cartcontroller
Let's now createCartcontroller, Relying on our custom model binder to supply cart instances.
implementing addtocart and removefromcart
Namespace sportsstore. webui. controllers {public class cartcontroller: controller {private iproductsrepository productsrepository; Public cartcontroller (iproductsrepository productsrepository) {This. productsrepository = productsrepository;} public redirecttorouteresult addtocart (Cart cart, int productid, string returnurl) {product Product = productsrepository. products. firstordefault (P => P. productid = productid); cart. additem (product, 1); Return redirecttoaction ("Index", new {returnurl});} public redirecttorouteresult removefromcart (Cart cart, int productid, string returnurl) {product Product = productsrepository. products. firstordefault (P => P. productid = productid); cart. removeline (product); Return redirecttoaction ("Index", new {returnurl });}}}
The important thing to notice is that addtocart and removefromcart's parameter names match the <form> Field names defined in/Views/shared/productsummary. ascx(I. e., productid and returnurl). That enables ASP. NET MVC to associate incoming form post variables with those parameters.
§ 2.5 displaying the cart
All that action has to do is render a view, supplying the visitor'sCartAndCurrent returnurlValue: add a simple new view model class to your sportsstore. webui project's models Folder:
Namespace sportsstore. webui. Models {public class cartindexviewmodel {public cart {Get; set;} Public String returnurl {Get; Set ;}}}
Implement the simpleIndex() Action Method by adding a new method to cartcontroller:
Public viewresult index (Cart cart, string returnurl) {return view (New cartindexviewmodel {cart = cart, returnurl = returnurl });}
And let's creat the View:
<Asp: content ID = "content2" contentplaceholderid = "maincontent" runat = "server"> <H2> your cart </H2> <Table width = "90%" align = "center"> <thead> <tr> <TH align = "center"> quantity </Th> <TH align = "Left"> item </Th> <TH align = "right"> price </Th> <TH align = "right"> subtotal </Th> </tr> </thead> <tbody> <% foreach (VAR line in model. cart. lines) {%> <tr> <TD align = "center"> <% = line. quantity %> </TD> <TD align = "Left"> <% = line. product. name %> </TD> <TD align = "right"> <% = line. product. price. tostring ("C") %> </TD> <TD align = "right"> <% = (line. quantity * line. product. price ). tostring ("C") %> </TD> <% using (HTML. beginform ("removefromcart", "cart") {%> <% = html. hidden ("productid", line. product. productid) %> <% = html. hiddenfor (x => X. returnurl) %> <input type = "Submit" value = "Remove"/><%}%> </TD> </tr> <%}%> </tbody> <tfoot> <tr> <TD colspan = "3" align = "right"> total: </TD> <TD align = "right"> <% = model. cart. computetotalvalue (). tostring ("C ") %> </TD> </tr> </tfoot> </table> <p align = "center" class = "actionbuttons"> <a href = "<% = Model. returnurl %> "> continue shopping </a> </P>
§ 5. 2.6 displaying a cart summary in the title bar
A new widget that displays a brief summary of the current cart contents and offers a link to the cart display page. you'll do this in much the same way that you implemented the navigation widget. add a new actionCartcontroller:
Public viewresult Summary (Cart cart) {return view (Cart );}
Next, create a partial view for the widget with stronugly typed:
<% IF (model. lines. count> 0) {%> <Div id = "cart"> <SPAN class = "caption"> <B> your cart: </B> <% = model. lines. sum (x => X. quantity) %> item (s), <% = model. computetotalvalue (). tostring ("C") %> </span> <% = html. actionlink ("check out", "Index", "cart", new {returnurl = request. URL. pathandquery}, null) %> </div> <%} %>
To plug the widget into the master page, add the following bold code/Views/shared/site. Master:
<Div id = "Header"> <% IF (! (Viewcontext. controller is sportsstore. webui. controllers. cartcontroller) HTML. renderaction ("summary", "cart"); %> <Div class = "title"> <asp: contentplaceholder id = "titlecontent" runat = "server"/> </div>