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

问题背景:

我正在为MVC应用程序实现一些基本的“购物车”逻辑。 目前,当我点击下面的屏幕截图中的一个链接 – 表示为“添加到购物车”时,这将调用’ProductController’中的’AddToCart’方法,如下所示:

在此处输入图像描述

Product.cshtml代码:

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

ProductController中的’AddToCart’方法:

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

问题:

这不是问题,但是当我在ProductDetail.cshtml视图上单击ActionLink上的“添加到购物车”按钮时,页面调用ProductController上的“AddToCart”方法并在页面上显示空白视图 – 如下所示。 我希望视图保留在’ProductDetail.cshtml’上,只需调用’AddToCart’方法,我该怎么做?

在此处输入图像描述

基本上, @Html.ActionLink()标签使用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中执行AddToCart操作方法,而当前页面将保持不变。 因此,产品也将添加到购物车,页面不会变为空白。

希望这可以帮助。

Syed Muhammad Zeeshan的答案就是你要找的,但是你可能会返回一个EmptyResult。

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

据此,它对你的代码没有影响ASP.Net MVC Controller返回void的动作但是有时候你想要返回数据然后你可以这样做:

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

有很多方法可以实现你想要的东西,但是其中一些方法需要比你想象的更多关于JavaScript之类的东西的高级知识。

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

在您的情况下,您正在创建一个锚标记( ),当单击时,指示浏览器导航到href中的URL。 这就是为什么你得到一个不同的页面。

如果您不想这样,可以通过多种方式更改您的应用程序。 第一个是,而不是使用ActionLink,而是只需要一个表单并将值发布回当前控制器。 并从您的post操作方法中调用“添加到购物车”代码。

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

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

另一种选择是使用嵌入式iframe,并将“添加到购物车”作为iframe中自己的页面。 我不一定会建议这种方法,但这是可能的。

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

一个很好的用例是,如果您想要在不刷新页面的情况下上传文件并将其保存在服务器上。

全部

 return new EmptyResult(); 

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

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

  

The CSV you want to upload:

然后在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(); 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 } } 

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

  • 使用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 } 

我正在努力解决这个问题,无法让它与ajax合作。

最终通过使我的控制器方法返回类型ActionResult而不是void并返回RedirectToAction()并输入与我想要在调用控制器方法时保持的视图相关的操作来获得有效的解决方案。

 public ActionResult Method() { // logic return RedirectToAction("ActionName"); }