如何触发Http Post Action到Form

时间:2012-12-29 14:25:44

标签: asp.net-mvc

我是Asp.net MVC的新手,我遇到以下代码问题。

  @model SportsStore.Domain.Entities.ShippingDetails

@{
    ViewBag.Title = "SportsStore: Checkout";
}

<h2>Check out now</h2>
Please enter your details and we'll send your goods right away!
@using (Html.BeginForm("Checkout", "Cart"))
{
    @Html.ValidationSummary()

    <h3>Ship to</h3>
    <div>Name: @Html.EditorFor(x => x.Name)</div>

    <h3>Address</h3>
    <div>Line 1: @Html.EditorFor(x => x.Line1)</div>
    <div>Line 2: @Html.EditorFor(x => x.Line2)</div>
    <div>Line 3: @Html.EditorFor(x => x.Line3)</div>
    <div>City: @Html.EditorFor(x => x.City)</div>
    <div>State: @Html.EditorFor(x => x.State)</div>
    <div>Zip: @Html.EditorFor(x => x.Zip)</div>
    <div>Country: @Html.EditorFor(x => x.Country)</div>

    <h3>Options</h3>
    <label>
    @Html.EditorFor(x => x.GiftWrap)
    Gift wrap these items
    </label>


        <p align="center">
            <input class="actionButtons" type="submit" value="Complete order"/>           
        </p>


}

我希望输入类型提交从我的控制器调用Post version Checkout操作,如下所示

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Entities;
using SportsStore.WebUI.Models;

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

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

        [HttpPost]
        public ViewResult Checkout(ShippingDetails shippingDetails, Cart cart)
        {
            var test = Request.Form["Line1"];
            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 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);
        }

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

        private Cart GetCart()
        {
            Cart cart = (Cart)Session["Cart"];
            if (cart == null)
            {
                cart = new Cart();
                Session["Cart"] = cart;
            }
            return cart;
        }

    }
}

然而,每当我按下此输入按钮时,都没有任何反应。

有人可以告诉我有什么问题吗?我认为提交类型的输入按钮会调用动作的后期版本,但显然这不起作用。

编辑:

我尝试在浏览器中禁用所有javascript,但这并不能解决问题。

这是我的路由信息​​:

public static void RegisterRoutes(RouteCollection routes)


 {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(null,"", // Only matches the empty URL (i.e. /)
            new
            {
            controller = "Product",
            action = "List",
            category = (string)null,
            page = 1
            }
            );

        routes.MapRoute(null, "Page{page}", new { Controller = "Product", action = "List" });

        routes.MapRoute(null,"{category}", // Matches /Football or /AnythingWithNoSlash
            new { controller = "Product", action = "List", page = 1 });

        routes.MapRoute(null,
        "{category}/Page{page}", // Matches /Football/Page567
        new { controller = "Product", action = "List" }, // Defaults
        new { page = @"\d+" } // Constraints: page must be numerical
        );

        routes.MapRoute(null, "{controller}/{action}");
    }

这是我在Global.asax中的ApplicationStart方法

protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
        ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());
    }

我真的不知道还能做什么。如果有人有任何想法,请告诉我。

2 个答案:

答案 0 :(得分:1)

  

我希望输入类型提交从我的控制器调用Post version Checkout操作

为什么你会期待这样的事情?您似乎没有在表单上注明:

@using (Html.BeginForm("Checkout", "Cart"))
{
    ...
}

如果未在呈现表单时显式指定要调用的操作和控制器名称,则将使用HttpPost调用与呈现此视图的操作相同的操作。因此,例如,如果此视图是从Index操作呈现的,那么如果使用Html.BeginForm,ASP.NET MVC将在同一控制器上查找带有HttpPost的Index操作。

例如:

public ActionResult Index()
{
    ... render the form
}

[HttpPost]
public ActionResult Index(ShippingDetails shippingDetails, Cart cart)
{
    ... process the form submission
}

这就是惯例。如果你不想遵循约定,你需要使用Html.BeginForm的重载,它允许你指定你想要调用的动作和控制器。

答案 1 :(得分:1)

您必须明确指定要POST表单。默认情况下,它执行GET。

@using(Html.BeginForm("Checkout", "Cart", FormMethod.Post))
{
    ...
}