ASP.NET MVC - 如何在不离开视图的情况下调用void控制器方法?

时间:2014-11-09 20:39:28

标签: c# asp.net-mvc asp.net-mvc-4

问题背景:

我正在实施一些基本的购物车' MVC应用程序的逻辑。目前,当我点击链接时 - 表示为'添加到购物车'在下面的屏幕截图中,这个叫做AddToCart' &ProductStroller'中的方法如图所示:

enter image description here

Product.cshtml代码:

@Html.ActionLink("Add To Cart", "AddToCart")

' AddToCart' ProductController中的方法:

public void AddToCart()
{
   //Logic to add item to the cart.
}

问题:

不是问题,但目前我点击了“添加到购物车”#39; ProductDetail.cshtml上ActionLink上的按钮查看该页面调用“AddToCart”#39; ProductController上的方法,并在页面上给出一个空白视图 - 如下所示。 我希望视图继续保留' ProductDetail.cshtml'然后打电话给AddToCart'方法,我该怎么做?

enter image description here

7 个答案:

答案 0 :(得分:18)

基本上@Html.ActionLink()<a></a>标记使用get请求来定位页面。因此,无论何时单击它,您都会在 ProductController 中请求 AddToCart 操作方法,如果该操作方法返回null或void,则会显示空白或空白页面(因为或者@ Html.ActionLink()默认获取请求。

因此,如果您想将您的价值添加到购物车,请使用ajax调用 AddToCart 方法,即:

<强> HTML:

@Html.ActionLink("Add To Cart", "AddToCart", null, new { id="myLink"})

Jquery或Javascript:

$("#myLink").click(function(e){

    e.preventDefault();
    $.ajax({

        url:$(this).attr("href"), // comma here instead of semicolon   
        success: function(){
        alert("Value Added");  // or any other indication if you want to show
        }

    });

});
ProductController中的

'AddToCart'方法:

public void AddToCart()
{
   //Logic to add item to the cart.
}

现在这次调用转到 AddToCart 方法时,它会使用ajax,因此整个页面不会重定向或更改,但它是一个异步调用,它在 ProductController ,当前页面将保持不变。因此,产品也会添加到购物车,页面不会变为空白。

希望这有帮助。

答案 1 :(得分:2)

有很多方法可以达到你想要的效果,但有些方法需要比你想象的更多关于JavaScript之类的知识。

编写ASP.NET MVC应用程序时,您需要更深入地了解浏览器如何与Web服务器交互。这通过称为HTTP的协议发生。它表面上是一个简单的协议,但它有许多细微的细节,你需要理解才能成功编写ASP.NET MVC应用程序。您还需要了解有关Html,CSS和JavaScript的更多信息。

在您的情况下,您正在创建一个锚标记(<a href="..."/>),当点击该标记时,指示浏览器导航到href中的网址。这就是为什么你得到一个不同的页面。

如果您不想要,可以通过多种方式更改您的申请。第一个是,而不是使用ActionLink,而是只需要一个表单并将值发布回当前控制器。并致电您的&#34;添加到购物车&#34;你的邮政行动方法的代码。

另一种方法是让你的AddToCart方法查看referrer标题(再次,这是http的更微妙知识的一部分),并在处理完工作后重定向回该页面。

另一种方法是使用Ajax,如Syed所建议的,其中数据由浏览器异步发送到您的控制器。这需要您了解有关JavaScript的更多信息。

另一种选择是使用嵌入式iframe并将您的&#34;添加到购物车&#34;是iframe中的自己的页面。我不一定会建议这种做法,但这是一种可能性。

答案 2 :(得分:2)

Syed Muhammad Zeeshan的答案正是您所寻找的,但您可能会返回一个EmptyResult。

public ActionResult AddToCart()
{
    //Logic to add item to the cart.
    return new EmptyResult();
}

据此,它对您的代码ASP.Net MVC Controller Actions that return void没有影响 但也许有时你想要返回数据然后你可以做这样的事情:

if (a) 
{
    return JSon(data);
}
else
{ 
     return new EmptyResult();
}

答案 3 :(得分:1)

正如很多人在这里提到的那样,如果你使用asp.net MVC命中控制器POST函数而不必离开你的视图,你将需要使用AJAX。

一个很好的用例就是如果你想上传文件而不刷新页面并将其保存在服务器上。

所有

return new EmptyResult();

不工作,他们仍然会重定向你。

以下是您的操作方法,在您的视图中以下面的形式为例:

            <form enctype="multipart/form-data" id="my-form">
                    <p>
                        The CSV you want to upload:
                    </p>
                    <input type="file" class="file-upload" name="FileUpload" />
                </div>
                <div>
                    <button type="submit" class="btn btn-default" name="Submit"  value="Upload">Upload</button>
                </div>
            </form>

然后在JavaScript方面,你需要在Script标签中将它添加到你的视图中。

  $("#my-form").on('submit', function (event) {
        event.preventDefault();
        // create form data
        var formData = new FormData();
        //grab the file that was provided by the user
        var file = $('.file-upload')[0].files[0];
        // Loop through each of the selected files.
        formData.append('file', file);
        if (file) {
            // Perform the ajax post
            $.ajax({
                url: '/YourController/UploadCsv',
                data: formData,
                processData: false,
                contentType: false,
                type: 'POST',
                success: function (data) {
                    alert(data);
                }
            });
        }
    });

您的控制器可能看起来像这样处理这种类型的文件:

    [HttpPost]
    public void UploadCsv()
    {
        var listOfObjects = new List<ObjectModel>();
        var FileUpload = Request.Files[0]; //Uploaded file
        //check we have a file
        if (FileUpload.ContentLength > 0)
        {
            //Workout our file path
            string fileName = Path.GetFileName(FileUpload.FileName);
            string path = Path.Combine(Server.MapPath("~/App_Data/"), fileName);

            //Try and upload
            try
            {
                //save the file
                FileUpload.SaveAs(path);

                var sr = new StreamReader(FileUpload.InputStream);
                string csvData = sr.ReadToEnd();

                foreach (string r in csvData.Split('\n').Skip(1))
                {
                    var row = r;
                    if (!string.IsNullOrEmpty(row))
                    {
                        //do something with your data
                        var dataArray = row.Split(',');
                    }
                }


            }
            catch (Exception ex)
            {
                //Catch errors
                //log an error
            }
        }
        else
        {
            //log an error
        }
    }

答案 4 :(得分:0)

Controller应该返回ActionResult。在这种情况下,重定向到调用者页面。

答案 5 :(得分:0)

  • 使用System.Web.Mvc;
  • 使用System.Web.Mvc.Html;

    public ActionResult Index()
    {
        HtmlHelper helper = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView(ControllerContext, "Index"), new ViewDataDictionary(), new TempDataDictionary(), new System.IO.StringWriter()), new ViewPage());
        helper.RenderAction("Index2");
    
        return View();
    }
    
    public void Index2(/*your arg*/)
    {
        //your code
    
    }
    

答案 6 :(得分:0)

我为此而苦苦挣扎,无法与ajax一起使用。

通过使我的控制器方法返回类型为ActionResult而不是void并返回RedirectToAction()并输入与我希望在调用控制器方法时保留的视图相关的动作,最终得到了可行的解决方案。

public ActionResult Method()
        {
            // logic

            return RedirectToAction("ActionName");
        }