wake-up-neo.com

ASP.NET MVC - Wie kann ich die void Controller-Methode aufrufen, ohne die Ansicht zu verlassen?

Hintergrund der Frage:

Ich implementiere eine grundlegende "Warenkorb" -Logik für eine MVC-App. Wenn ich derzeit auf einen Link klicke, der auf dem unten abgebildeten Screenshot als "Add To Cart" gekennzeichnet ist, wird eine "AddToCart" -Methode im "ProductController" wie folgt aufgerufen:

enter image description here

Product.cshtml code:

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

'AddToCart' Methode im ProductController:

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

Die Angelegenheit:

Kein Problem als solches, aber wenn ich auf "Add To Cart" in ActionLink in der ProductDetail.cshtml-Schaltfläche klicke, ruft die Seite die "AddToCart" -Methode auf dem ProductController auf und ergibt eine leere Ansicht auf der Seite - wie unten gezeigt.Ich möchte, dass die Ansicht auf 'ProductDetail.cshtml' verbleibt und die Methode 'AddToCart' aufgerufen wird. Wie mache ich das?

enter image description here

22
user1352057

Grundsätzlich verwendet @Html.ActionLink() oder <a></a>-Tag die get-Anfrage, um die Seite zu finden. Wann immer Sie darauf geklickt haben, fordern Sie daher Ihre AddToCart action-Methode in ProductController an und wenn diese Aktionsmethode null oder nichtig zurückgibt, wird eine leere oder leere Seite angezeigt, wie Sie sie erlebt haben (weil oder @ Html.ActionLink () Anforderung abfragen).

Wenn Sie also Ihren Wert in den Warenkorb legen möchten, rufen Sie die AddToCart - Methode mit ajax auf.

HTML:

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

Jquery oder 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' Methode im ProductController:

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

Wenn diesmal der Aufruf an die AddToCart -Methode erfolgt, wird ajax verwendet. Daher wird die gesamte Seite nicht umgeleitet oder geändert, sondern ein asynchroner Aufruf, der die AddToCart-Aktionsmethode in Ihrem ProductController und den aktuellen Befehl ausführt Seite bleibt gleich. Daher wird das Produkt auch in den Warenkorb gelegt und die Seite wird nicht leer.

Hoffe das hilft.

17

Die Antwort von Syed Muhammad Zeeshan ist das, wonach Sie suchen. Sie können jedoch ein EmptyResult zurückgeben.

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

Demnach hat es keine Auswirkungen auf Ihren Code ASP.Net MVC Controller-Aktionen, die void .__ zurückgeben. Vielleicht möchten Sie jedoch manchmal Daten zurückgeben und dann könnten Sie Folgendes tun:

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

Es gibt viele Wege, um das zu erreichen, was Sie möchten, aber einige von ihnen erfordern viel mehr Kenntnisse über Dinge wie JavaScript, als Ihnen bewusst erscheint.

Wenn Sie ASP.NET-MVC-Anwendungen schreiben, müssen Sie sich eingehender mit der Interaktion von Browsern mit dem Webserver auskennen. Dies geschieht über ein Protokoll namens HTTP. Es ist ein einfaches Protokoll an der Oberfläche, aber es hat viele subtile Details, die Sie verstehen müssen, um ASP.NET MVC-Apps erfolgreich zu schreiben. Sie müssen auch mehr über HTML, CSS und JavaScript erfahren.

In Ihrem Fall erstellen Sie ein Ankertag (<a href="..."/>), das den Browser beim Klicken dazu anweist, zur URL in der href zu navigieren. Deshalb erhalten Sie eine andere Seite.

Wenn Sie das nicht möchten, können Sie Ihre Anwendung auf verschiedene Weise ändern. Der erste wäre, anstatt einen ActionLink zu verwenden, haben Sie stattdessen einfach ein Formular und buchen Werte in Ihren aktuellen Controller zurück. Und rufen Sie den Code "In den Warenkorb" von Ihrer Post-Action-Methode an.

Eine andere Möglichkeit wäre, dass Ihre AddToCart-Methode den Referrer-Header (wiederum ein Teil dieses subtileren http-Wissens) betrachtet und auf diese Seite umleitet, nachdem die Arbeit ausgeführt wurde.

Eine andere Möglichkeit wäre die Verwendung von Ajax, wie von Syed vorgeschlagen, bei dem Daten asynchron vom Browser an Ihren Controller gesendet werden. Dies erfordert, dass Sie mehr über JavaScript lernen.

Eine andere Möglichkeit ist, einen eingebetteten Iframe zu verwenden und Ihr "Add to Cart" als eigene Seite in diesem Iframe anzeigen zu lassen. Ich würde diesen Ansatz nicht unbedingt vorschlagen, aber es ist möglich.

2

Wie bereits erwähnt, müssen Sie AJAX verwenden, wenn Sie mit asp.net MVC eine Controller-Funktion POST ausführen, ohne die Ansicht zu verlassen.

Ein guter Anwendungsfall dafür ist, wenn Sie eine Datei hochladen möchten, ohne die Seite zu aktualisieren, und diese auf dem Server speichern.

Alle der

return new EmptyResult();

Funktioniert nicht, sie leiten Sie trotzdem um.

So machen Sie es, in Ihrer Ansicht haben Sie das folgende Formular als Beispiel:

            <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>

Auf der JavaScript-Seite müssen Sie dies mit Script-Tags zu Ihrer Ansicht hinzufügen.

  $("#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);
                }
            });
        }
    });

Ihr Controller könnte in etwa so aussehen, um diesen Dateityp zu verarbeiten:

    [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
        }
    }
1
Louie Bacaj
  • using System.Web.Mvc; 
  • using 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
    
    }
    
0

Der Controller sollte ActionResult zurückgeben. In diesem Fall eine Weiterleitung auf die Anruferseite.

0
Péter

Ich hatte Probleme damit und konnte es nicht mit Ajax zum Laufen bringen.

Schließlich bekam ich eine funktionierende Lösung, indem ich dafür sorgte, dass meine Controller-Methode den Typ ActionResult anstelle von void zurückgab und ein RedirectToAction () zurückgab und die Aktion für die Ansicht einging, die ich beim Aufruf der Controller-Methode beibehalten wollte.

public ActionResult Method()
        {
            // logic

            return RedirectToAction("ActionName");
        }
0
TGiblin95