Gönder düğmesine basılmış olan MVC


128

MVC formumda iki düğmem var:

<input name="submit" type="submit" id="submit" value="Save" />
<input name="process" type="submit" id="process" value="Process" />

Kontrolör eylemimden hangisine basıldığını nasıl bilebilirim?


Neden kendi AJAX çağrılarına giden ve uygun yöntemlerine gidecek olan bu düğmelere onclick olayları eklemiyorsunuz? yani: <input name="submit" type="submit" id="submit" value="Save" onclick="saveMethod" />?
ragerory

Yanıtlar:


169

Her iki gönderme düğmenizi de aynı şekilde adlandırın

<input name="submit" type="submit" id="submit" value="Save" />
<input name="submit" type="submit" id="process" value="Process" />

Sonra denetleyicinizde gönderi değerini alın. Yalnızca tıklanan düğme değerini iletecektir.

public ActionResult Index(string submit)
{
    Response.Write(submit);
    return View();
}

Bir anahtar bloğu ile farklı işlemler gerçekleştirmek için elbette bu değeri değerlendirebilirsiniz.

public ActionResult Index(string submit)
{
    switch (submit)
    {
        case "Save":
            // Do something
            break;
        case "Process":
            // Do something
            break;
        default:
            throw new Exception();
            break;
    }

    return View();
}

13
Darin'in çözümünün hassas olmadığı bu çözüme yerelleştirmenin getirebileceği sorunlara dikkat edin.
Richard Szalay

Aynı ada sahip iki giriş, her değer için tek bir değerle değil, her değer için bir öğeyle birlikte gönderilen bir diziyle sonuçlanır. Bunu kullanmayı umduğum / çalıştığım için, keşke aksini söyleyebilseydim, ama bu işe yaramıyor.
Christopher King

1
@RichardSzalay - yalnızca <button type="submit" name="action" value="draft"> Internationalized Save Text </button>i18n amaçları için kullanamazdınız , bu nedenle kullanıcının karşısındaki dize özelleştirilebilir ve form öğesi adları hiçbir zaman doğrudan kullanıcıya gösterilmez (ki bu kendi başına
tuhaftır

48
<input name="submit" type="submit" id="submit" value="Save" />
<input name="process" type="submit" id="process" value="Process" />

Ve denetleyici eyleminizde:

public ActionResult SomeAction(string submit)
{
    if (!string.IsNullOrEmpty(submit))
    {
        // Save was pressed
    }
    else
    {
        // Process was pressed
    }
}

1
Basitçe parametre listesine ekleyerek ve doğru şekilde adlandırarak daha fazla düğme eklenebileceğini hayal ediyorum. Güzel çözüm!
GONeale

35

bu daha iyi bir cevaptır, bu nedenle bir düğme için hem metne hem de değere sahip olabiliriz:

http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx

</p>
<button name="button" value="register">Register</button>
<button name="button" value="cancel">Cancel</button>
</p>

ve kontrolör:

public ActionResult Register(string button, string userName, string email, string password, string confirmPassword)
{
if (button == "cancel")
    return RedirectToAction("Index", "Home");
...

kısacası, bir GÖNDER düğmesi ancak ad özniteliğini kullanarak adı seçersiniz, daha da güçlüdür çünkü denetleyici yöntem parametrelerinde gönder veya düğmeye ad vermek zorunda değilsiniz, onu istediğiniz gibi çağırabilirsiniz ...


Teşekkürler efendim, tam da ihtiyacım olan şey bu
oHoodie

Düğmenin değerini dile göre değiştiren çok dilli bir sisteminiz varsa bu bozulur.
Dave Tapson

Dave - Kimsenin böyle bir sistemi kodlayacağını sanmıyorum. Bu, denetleyici adlarınızı veya işlev adlarınızı yerelleştirmek gibidir. Değer düğmesinin sadece sunucu tarafında kullanımı içindir - bu yerde görüntülenmez ve lokalize edilmesi gerekmez.
NickG

20

Düğmenizi oradaki isim etiketinden aşağıdaki gibi tanımlayabilirsiniz, denetleyicinizde bu şekilde kontrol etmeniz gerekir

if (Request.Form["submit"] != null)
{
//Write your code here
}
else if (Request.Form["process"] != null)
{
//Write your code here
}

Bu, düğmenin adını post action sonucuna geçirmek istemediğiniz durumlarda çok yararlıdır.
yogihost

bu senaryoda birim testinde Request sınıfıyla dalga geçmek daha karmaşık olabilir.
Muflix

6

Özel bir MultiButtonAttribute kullanarak talimatları takip etmesi gerçekten kolay bir şekilde yapmanın gerçekten güzel ve basit bir yolu:

http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

Özetlemek gerekirse, gönderme düğmelerinizi şu şekilde yapın:

<input type="submit" value="Cancel" name="action" />
<input type="submit" value="Create" name="action" /> 

Bunun gibi eylemleriniz:

[HttpPost]
[MultiButton(MatchFormKey="action", MatchFormValue="Cancel")]
public ActionResult Cancel()
{
    return Content("Cancel clicked");
}

[HttpPost]
[MultiButton(MatchFormKey = "action", MatchFormValue = "Create")]
public ActionResult Create(Person person)
{
    return Content("Create clicked");
} 

Ve bu sınıfı oluşturun:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultiButtonAttribute : ActionNameSelectorAttribute
{
    public string MatchFormKey { get; set; }
    public string MatchFormValue { get; set; }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request[MatchFormKey] != null &&
            controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue;
    }
}

1
Referans verilen bir bağlantıyı özetlemek her zaman en iyisidir (blogun kaybolduğu gün için). Özetle, blog MultiButtonAttribute, gönderme düğmelerinin ayırt edilmesine olanak tanıyan özel bir özniteliğe sahip olmayı savunuyor . Aslında oldukça güzel bir fikir.
Kodlama Gone

1
Ve eğer Arnis L.aynı tavsiyeye uymuş olsaydınız, aynı bağlantıyı 4 yıl önce sağladığını fark etmiş olabilirsiniz:>
Kodlama

3
// Buttons
<input name="submit" type="submit" id="submit" value="Save" />
<input name="process" type="submit" id="process" value="Process" />

// Controller
[HttpPost]
public ActionResult index(FormCollection collection)
{
    string submitType = "unknown";

    if(collection["submit"] != null)
    {
        submitType = "submit";
    }
    else if (collection["process"] != null)
    {
        submitType = "process";
    }

} // End of the index method

Bu, çok karmaşık form verilerinin her eylemde özelleştirilmiş parametre setleri olmadan tutarlı bir şekilde aktarılmasına olanak tanıdığından, denetleyici mantığının karmaşık formlar için son derece özelleştirilebilir olmasına olanak tanıdığından, yayınlanan diğer her şey için üstün bir çözümdür. Kudos Fredrik :) Bu FormCollection'ın birden çok biçimde geçeceğini varsayıyorum?
Stokely

Teşekkür ederim Stokely. Bu yöntemi birden çok formdan çağırabilirsiniz, bir ajax çağrısı yaparsanız, aynı FormCollection'a birçok form dahil edebilirsiniz.
Fredrik Stigsson

3

Daha kolay hale getirmek için, düğmelerinizi şu şekilde değiştirebileceğinizi söyleyeceğim:

<input name="btnSubmit" type="submit" value="Save" />
<input name="btnProcess" type="submit" value="Process" />

Denetleyiciniz:

public ActionResult Create(string btnSubmit, string btnProcess)
{
    if(btnSubmit != null)
       // do something for the Button btnSubmit
    else 
       // do something for the Button btnProcess
}

2

Bu gönderi Coppermill'e cevap vermeyecek çünkü uzun zaman önce cevaplandı. Yazım, böyle bir çözüm arayanlar için faydalı olacaktır. Her şeyden önce, "WDuffy'nin çözümü tamamen doğru" demeliyim ve iyi çalışıyor, ancak benim çözümüm (aslında benim değil) diğer öğelerde kullanılacak ve sunum katmanını denetleyiciden daha bağımsız hale getiriyor (çünkü denetleyiciniz Düğmenin etiketini göstermek için kullanılan "değer", bu özellik diğer diller için önemlidir.).

İşte benim çözümüm, onlara farklı isimler verin:

<input type="submit" name="buttonSave" value="Save"/>
<input type="submit" name="buttonProcess" value="Process"/>
<input type="submit" name="buttonCancel" value="Cancel"/>

Ve eylemde aşağıdaki gibi düğmelerin adlarını bağımsız değişken olarak belirtmelisiniz:

public ActionResult Register(string buttonSave, string buttonProcess, string buttonCancel)
{
    if (buttonSave!= null)
    {
        //save is pressed
    }
    if (buttonProcess!= null)
    {
        //Process is pressed
    }
    if (buttonCancel!= null)
    {
        //Cancel is pressed
    }
}

kullanıcı, düğmelerden birini kullanarak sayfayı gönderdiğinde, bağımsız değişkenlerden yalnızca birinin değeri olacaktır. Sanırım bu başkaları için faydalı olacak.

Güncelleme

Bu cevap oldukça eski ve aslında fikrimi yeniden gözden geçiriyorum. belki yukarıdaki çözüm, parametrenin modelin özelliklerine geçtiği durumlar için iyidir. kendinizi rahatsız etmeyin ve projeniz için en iyi çözümü alın.


Bazı yapıcı eleştiriler de var: Bu, yayınladığınızdan itibaren mevcut cevaplar tarafından iyi bir şekilde kapsanmaktadır. Ek olarak, bu iyi ölçeklenmiyor. HTML yalnızca input[type=submit]tetiklenen değeri geri gönderir , böylece hepsi aynı özellikteki bir özelliğe bağlanabilir name(örn. action) Ve ardından value, imzanıza bu kadar çok değişkeni eklemenize gerek kalmadan düğmeleri bu dizeye göre farklılaştırabilirsiniz . . Lütfen göndermeden önce biçimlendirme / girinti hakkında da düşünmek için biraz zaman ayırın.
KyleMit

0

Request.Form Collection kullanarak bulamıyor musunuz? İşlem tıklanırsa request.form ["işlem"] boş olmayacaktır


0

Her iki düğmeye de adı verin ve kontrol değerini formdan alın.

<div>
   <input name="submitButton" type="submit" value="Register" />
</div>

<div>
   <input name="cancelButton" type="submit" value="Cancel" />
</div>

Denetleyici tarafında:

public ActionResult Save(FormCollection form)
{
 if (this.httpContext.Request.Form["cancelButton"] !=null)
 {
   // return to the action;
 }

else if(this.httpContext.Request.Form["submitButton"] !=null)
 {
   // save the oprtation and retrun to the action;
 }
}

0

Core 2.2 Razor sayfalarında bu sözdizimi çalışır:

    <button type="submit" name="Submit">Save</button>
    <button type="submit" name="Cancel">Cancel</button>
public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
        return Page();
    var sub = Request.Form["Submit"];
    var can = Request.Form["Cancel"];
    if (sub.Count > 0)
       {
       .......

İşe yarayabilir, ancak parametre yerine string submityazmayı tercih ederim string submit = Request.Form["Submit"];. Razor Pages ve / veya MVC'nin en büyük avantajlarından biri yöntemlerin okunabilirliğidir, aksi takdirde PHP olabilir.
yzorg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.