ASP.NET MVC - Как вызвать метод void controller, не выходя из представления?
Вопрос:
Я внедряю базовую логику "корзины покупок" в приложение MVC. В настоящее время, когда я нажимаю ссылку, обозначенную как "Добавить в корзину" на снимке экрана ниже, вызывается метод AddToCart в "ProductController", как показано ниже:
![enter image description here]()
Код продукта .cshtml:
@Html.ActionLink("Add To Cart", "AddToCart")
"AddToCart" в ProductController:
public void AddToCart()
{
//Logic to add item to the cart.
}
Проблема:
Не проблема как таковая, но в настоящее время, когда я нажимаю кнопку "Добавить в корзину" в ActionLink в представлении ProductDetail.cshtml, страница вызывает метод AddToCart на ProductController и дает пустой просмотр на странице - в качестве показано ниже. Я хочу, чтобы представление оставалось на 'ProductDetail.cshtml' и просто вызывало метод AddToCart, как это сделать?
![enter image description here]()
Ответы
Ответ 1
В основном тег @Html.ActionLink()
или <a></a>
использует запрос получения для поиска страницы. Следовательно, всякий раз, когда вы нажимаете на нее, вы запрашиваете свой метод AddToCart в ProductController, и если этот метод действия возвращает null или void, так что пустая или пустая страница отображается по вашему опыту ( потому что или @Html.ActionLink() получают запрос по умолчанию).
Итак, если вы хотите добавить свое значение в корзину, вызовите метод AddToCart, используя ajax i.e:
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
}
});
});
"AddToCart" в ProductController:
public void AddToCart()
{
//Logic to add item to the cart.
}
Теперь, когда вызов переходит к методу AddToCart, он переходит с помощью ajax, поэтому вся страница не будет перенаправляться или изменяться, но ее асинхронный вызов, который выполняет метод действия AddToCart в ProductController, и текущая страница останется такой же. Следовательно, продукт также будет добавлен в корзину, и страница не изменится на пустую.
Надеюсь, что это поможет.
Ответ 2
Есть много способов выполнить то, что вы хотите, но некоторые из них требуют гораздо более глубокого знания таких вещей, как JavaScript, чем вы, кажется, знаете.
Когда вы пишете приложения ASP.NET MVC, вам необходимо иметь более глубокие знания о том, как браузеры взаимодействуют с веб-сервером. Это происходит по протоколу HTTP. Это простой протокол на поверхности, но он содержит много тонких деталей, которые вам нужно понять, чтобы успешно писать приложения ASP.NET MVC. Вам также нужно узнать больше о Html, CSS и JavaScript.
В вашем случае вы создаете якорный тег (<a href="..."/>
), который при нажатии на него указывает браузеру перейти к URL-адресу в href. Вот почему вы получаете другую страницу.
Если вы этого не хотите, есть несколько способов изменить ваше приложение. Первым будет, вместо использования ActionLink, вместо этого вы просто получите форму и отправьте значения обратно на текущий контроллер. И назовите код "добавить в корзину" из вашего метода post action.
Другим способом будет ваш метод AddToCart посмотреть заголовок referrer (опять же, часть этого более тонкого знания http) и перенаправить обратно на эту страницу после того, как он обработает свою работу.
Еще один способ - использовать Ajax, как было предложено Syed, в котором данные отправляются на ваш контроллер асинхронно браузером. Это требует, чтобы вы больше узнали о JavaScript.
Другим вариантом является использование встроенного iframe и его "добавление в корзину" - это собственная страница внутри этого iframe. Я бы не стал предлагать этот подход, но это возможность.
Ответ 3
Ответ 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();
}
Ответ 4
Как многие люди упомянули здесь, вам нужно будет использовать AJAX, если вы используете asp.net MVC, чтобы попасть в функцию POST контроллера, не выходя из своего представления.
Хорошим вариантом для этого является то, что вы хотите загрузить файл без обновления страницы и сохранить ее на сервере.
Все
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
}
}
Ответ 5
Контроллер должен вернуть ActionResult. В этом случае перенаправление на страницу вызывающего абонента.
Ответ 6
- с использованием 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
}