web-dev-qa-db-fra.com

ASP.NET MVC - Comment appeler une méthode de contrôleur d’annulation sans quitter la vue?

Arrière-plan de la question:

J'implémente une logique de base de "panier" dans une application MVC. Actuellement, lorsque je clique sur un lien - désigné par "Ajouter au panier" sur la capture d'écran ci-dessous, cela appelle une méthode "AddToCart" dans le "ProductController", comme indiqué:

enter image description here

Code produit.cshtml:

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

Méthode 'AddToCart' dans le ProductController:

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

Le problème:

Ce n'est pas un problème en tant que tel, mais lorsque je clique sur le bouton 'Ajouter au panier' du lien Action sur la vue ProductDetail.cshtml, la page appelle la méthode 'AddToCart' sur le ProductController et donne une vue vierge de la page - comme illustré ci-dessous.Je souhaite que la vue reste sur 'ProductDetail.cshtml' et appelle simplement la méthode 'AddToCart', comment procéder?

enter image description here

22
user1352057

En gros, la balise @Html.ActionLink() ou <a></a> utilise la requête get pour localiser la page. Par conséquent, chaque fois que vous avez cliqué dessus, vous demandez à votre méthode d’action AddToCart dans ProductController et si cette méthode d’action renvoie null ou void, une page vierge ou vide est affichée telle que vous l’avez expérimentée (parce que ou @ Html.ActionLink () obtenir la demande par défaut).

Donc, si vous voulez ajouter votre valeur au panier, appelez la méthode AddToCart en utilisant ajax i.e:

HTML:

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

Jquery ou 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
        }

    });

});

Méthode 'AddToCart' dans le ProductController:

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

Maintenant, cette fois-ci, lorsque l'appel passe à la méthode AddToCart, il utilise ajax. Toute la page ne sera ni redirigée ni modifiée, mais il s'agit d'un appel asynchrone qui exécute la méthode d'action AddToCart dans votre ProductController et le courant. la page restera la même. Par conséquent, le produit sera également ajouté au panier et la page ne deviendra pas vierge.

J'espère que cela t'aides.

17

La réponse de Syed Muhammad Zeeshan est ce que vous recherchez, mais vous pouvez renvoyer un résultat vide.

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

Selon cela, cela n'a aucun impact sur votre code Les actions du contrôleur ASP.Net MVC qui renvoient void Mais vous voudrez peut-être parfois renvoyer des données pour pouvoir faire quelque chose comme ceci:

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

Il existe de nombreuses façons d’accomplir ce que vous voulez, mais certaines d’entre elles requièrent une connaissance beaucoup plus avancée de JavaScript, par exemple.

Lorsque vous écrivez des applications ASP.NET MVC, vous devez avoir une connaissance plus approfondie de la manière dont les navigateurs interagissent avec le serveur Web. Cela se produit via un protocole appelé HTTP. C'est un protocole simple en surface, mais il comporte de nombreux détails subtils que vous devez comprendre pour réussir à écrire des applications ASP.NET MVC. Vous devez également en savoir plus sur HTML, CSS et JavaScript.

Dans votre cas, vous créez une balise d'ancrage (<a href="..."/>) qui, lorsque vous cliquez dessus, indique au navigateur de naviguer vers l'URL dans le href. C'est pourquoi vous obtenez une page différente.

Si vous ne le souhaitez pas, vous pouvez modifier votre demande de plusieurs façons. La première serait qu'au lieu d'utiliser un ActionLink, vous avez simplement un formulaire et enregistrez des valeurs sur votre contrôleur actuel. Et appelez votre code "ajouter au panier" à partir de votre méthode post-action.

Une autre méthode consiste à demander à votre méthode AddToCart d'examiner l'en-tête du référent (là encore, une partie de cette connaissance plus subtile de http) et de la rediriger vers cette page une fois le traitement terminé.

Une autre méthode consiste à utiliser Ajax, comme suggéré par Syed, dans lequel les données sont envoyées à votre contrôleur de manière asynchrone par le navigateur. Cela nécessite que vous en appreniez plus sur JavaScript.

Une autre option consiste à utiliser un iframe intégré et à faire en sorte que votre "ajouter au panier" soit sa propre page à l'intérieur de ce iframe. Je ne suggérerais pas nécessairement cette approche, mais c'est une possibilité.

2
Erik Funkenbusch

Comme beaucoup de personnes mentionnées ici, vous devrez utiliser AJAX si vous utilisez asp.net MVC pour activer une fonction de contrôleur POST sans quitter votre vue.

Un bon cas d'utilisation consiste à télécharger un fichier sans actualiser la page et à l'enregistrer sur le serveur.

La totalité de la

return new EmptyResult();

Cela ne fonctionnera pas, ils vous redirigeront toujours.

Voici comment vous le faites, à votre avis, utilisez le formulaire suivant à titre d'exemple:

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

Ensuite, dans le côté JavaScript, vous devez ajouter ceci à votre vue avec des balises de 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);
                }
            });
        }
    });

Votre contrôleur pourrait ressembler à quelque chose comme ceci pour traiter ce type de fichier:

    [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

Le contrôleur doit renvoyer ActionResult. Dans ce cas, une redirection vers la page de l'appelant.

0
Péter

Je me débattais avec ça et je ne pouvais pas le faire fonctionner avec ajax.

Finalement, j'ai trouvé une solution efficace en renvoyant ActionResult à ma méthode de contrôleur, plutôt que void, en renvoyant une requête RedirectToAction () et en saisissant l'action relative à la vue que je souhaitais conserver lors de l'appel de la méthode de contrôleur.

public ActionResult Method()
        {
            // logic

            return RedirectToAction("ActionName");
        }
0
TGiblin95