Bagaimana Anda menangani beberapa tombol kirim di ASP.NET MVC Framework?

734

Apakah ada cara mudah untuk menangani beberapa tombol kirim dari formulir yang sama? Sebagai contoh:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" value="Send" />
<input type="submit" value="Cancel" />
<% Html.EndForm(); %>

Adakah yang tahu bagaimana melakukan ini di ASP.NET Framework Beta? Semua contoh yang saya cari di Google memiliki satu tombol di dalamnya.

Spoike
sumber
6
Layak disebutkan mulai dari ASP.NET Core ada solusi yang jauh lebih mudah daripada yang tercantum di sini.
Steven Jeuris
Tutorial ini mungkin membantu: Menyerahkan formulir ke metode tindakan berbeda di ASP.NET MVC
Hooman Bahreini

Jawaban:

629

Berikut ini adalah sebagian besar solusi berbasis atribut bersih untuk masalah tombol kirim banyak didasarkan pada posting dan komentar dari Maarten Balliauw .

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

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        var isValidName = false;
        var keyValue = string.Format("{0}:{1}", Name, Argument);
        var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);

        if (value != null)
        {
            controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
            isValidName = true;
        }

        return isValidName;
    }
}

pisau cukur:

<form action="" method="post">
 <input type="submit" value="Save" name="action:Save" />
 <input type="submit" value="Cancel" name="action:Cancel" />
</form>

dan pengontrol:

[HttpPost]
[MultipleButton(Name = "action", Argument = "Save")]
public ActionResult Save(MessageModel mm) { ... }

[HttpPost]
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(MessageModel mm) { ... }

Pembaruan: Halaman silet terlihat memberikan fungsi yang sama di luar kotak. Untuk pengembangan baru, mungkin lebih disukai.

mkozicki
sumber
3
Saya menemukan solusi ini untuk menjadi pernikahan yang bahagia dari teknik lain yang digunakan. Bekerja dengan sempurna dan tidak mempengaruhi lokalisasi.
trevorc
17
Solusi hebat !! Jauh lebih berguna daripada jawaban yang mendapat skor teratas
Sasha
11
Masalah dengan pendekatan ini adalah bahwa jika Anda mencoba return View(viewmodel)dalam kasus di mana model Anda memiliki kesalahan, itu akan berusaha untuk mengembalikan tampilan yang disebut Sendatau tergantung pada apa nama argumen Anda.
Sepatu
15
@Shoe - baru saja menemukan hal serupa. Pastikan Anda secara spesifik menentukan nama tampilan yang akan dikembalikan jika Anda menggunakan metode ini:return View("Index", viewModel)
ajbeaven
4
hanya sebuah informasi, kita perlu menambahkan sistem. Refleksi untuk MethodInfo
Vignesh Subramanian
469

Beri nama tombol kirim Anda, dan kemudian periksa nilai yang dikirimkan dalam metode pengontrol Anda:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="Send" />
<input type="submit" name="submitButton" value="Cancel" />
<% Html.EndForm(); %>

memposting ke

public class MyController : Controller {
    public ActionResult MyAction(string submitButton) {
        switch(submitButton) {
            case "Send":
                // delegate sending to another controller action
                return(Send());
            case "Cancel":
                // call another action to perform the cancellation
                return(Cancel());
            default:
                // If they've submitted the form without a submitButton, 
                // just return the view again.
                return(View());
        }
    }

    private ActionResult Cancel() {
        // process the cancellation request here.
        return(View("Cancelled"));
    }

    private ActionResult Send() {
        // perform the actual send operation here.
        return(View("SendConfirmed"));
    }

}

EDIT:

Untuk memperluas pendekatan ini agar berfungsi dengan situs yang dilokalkan, pisahkan pesan Anda di tempat lain (mis. Kompilasi file sumber daya ke kelas sumber daya yang diketik dengan sangat baik)

Kemudian modifikasi kode sehingga berfungsi seperti:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="<%= Html.Encode(Resources.Messages.Send)%>" />
<input type="submit" name="submitButton" value="<%=Html.Encode(Resources.Messages.Cancel)%>" />
<% Html.EndForm(); %>

dan controller Anda akan terlihat seperti ini:

// Note that the localized resources aren't constants, so 
// we can't use a switch statement.

if (submitButton == Resources.Messages.Send) { 
    // delegate sending to another controller action
    return(Send());

} else if (submitButton == Resources.Messages.Cancel) {
     // call another action to perform the cancellation
     return(Cancel());
}
Dylan Beattie
sumber
28
Sayang sekali Anda bergantung pada teks yang ditampilkan pada tombol, itu agak rumit dengan antarmuka pengguna multi bahasa
Omu
3
Switch / case hanya berfungsi dengan konstanta, jadi versi yang dilokalkan tidak dapat menggunakan switch / case. Anda harus beralih ke if else atau metode pengiriman lainnya.
mlibby
10
Anda harus menggunakan <button type = "submit" daripada <input type, karena nilai dari tipe <button bukan teks;). Maka Anda dapat memiliki sesuatu seperti ini: <button name = "mySubmitButton" type = "submit" value = "keyValue"> YourButtonText </button>
J4N
4
Bagaimana ini akan bekerja dengan meneruskan model ke tindakan alih-alih hanya mengirimkan nilai?
bizzehdee
2
Berhati-hatilah untuk tidak menyebut tombol "aksi" tombol Anda jika Anda menggunakan jQuery. Ini menyebabkan konflik di dalam perpustakaan yang merusak URL tindakan.
HotN
121

Anda dapat memeriksa nama dalam aksi seperti yang telah disebutkan, tetapi Anda dapat mempertimbangkan apakah ini desain yang baik atau tidak. Merupakan ide bagus untuk mempertimbangkan tanggung jawab tindakan dan tidak memadukan desain ini terlalu banyak dengan aspek UI seperti nama tombol. Jadi pertimbangkan menggunakan 2 formulir dan 2 tindakan:

<% Html.BeginForm("Send", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Send" />
<% Html.EndForm(); %>

<% Html.BeginForm("Cancel", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Cancel" />
<% Html.EndForm(); %>

Juga, dalam kasus "Batal", Anda biasanya tidak memproses formulir dan pergi ke URL baru. Dalam hal ini Anda tidak perlu mengirimkan formulir sama sekali dan hanya perlu tautan:

<%=Html.ActionLink("Cancel", "List", "MyController") %>
Trevor de Koekkoek
sumber
53
Ini ok ketika Anda tidak memerlukan data formulir yang sama untuk setiap tombol kirim. Jika Anda membutuhkan semua data dalam bentuk umum daripada Dylan Beattie adalah cara untuk pergi. Apakah ada cara yang lebih elegan untuk melakukan ini?
zidane
3
Tentang presentasi visual, bagaimana dalam hal ini memiliki tombol "Kirim" di sebelah tombol "Batal"?
Kris-I
1
Dylan: Ya, untuk tombol batal Anda tidak perlu mengirim data sama sekali dan itu adalah praktik yang buruk untuk memasangkan controller ke elemen UI. Namun jika Anda dapat membuat "perintah" yang lebih umum atau kurang maka saya pikir tidak apa-apa, tetapi saya tidak akan mengikatnya untuk "mengirimkan Tombol" karena itu adalah nama elemen UI.
Trevor de Koekkoek
1
@ Kris: Anda dapat memposisikan tombol Anda dengan CSS dan masih dapat berada di 2 bagian formulir yang berbeda.
Trevor de Koekkoek
8
serius? apakah itu tidak berbau bagi siapa pun kecuali aku ?!
99

Eilon menyarankan Anda untuk melakukannya seperti ini:

Jika Anda memiliki lebih dari satu tombol, Anda dapat membedakannya dengan memberi nama setiap tombol:

<input type="submit" name="SaveButton" value="Save data" />
<input type="submit" name="CancelButton" value="Cancel and go back to main page" />

Dalam metode tindakan pengontrol Anda, Anda dapat menambahkan parameter bernama setelah nama tag input HTML:

public ActionResult DoSomeStuff(string saveButton, string
cancelButton, ... other parameters ...)
{ ... }

Jika ada nilai yang diposting ke salah satu parameter itu, itu berarti tombol itu yang diklik. Browser web hanya akan memposting nilai untuk satu tombol yang diklik. Semua nilai lainnya akan menjadi nol.

if (saveButton != null) { /* do save logic */ }
if (cancelButton != null) { /* do cancel logic */ }

Saya suka metode ini karena tidak bergantung pada properti nilai dari tombol kirim yang lebih mungkin berubah daripada nama yang diberikan dan tidak memerlukan javascript untuk diaktifkan

Lihat: http://forums.asp.net/p/1369617/2865166.aspx#2865166

PabloBlamirez
sumber
2
Jika ada yang menemukan pertanyaan lama ini, ini adalah jawaban terbersih jika Anda tidak ingin menggunakan elemen <button> HTML5. Jika Anda tidak keberatan dengan HTML5 maka gunakan <button> dengan atribut nilai.
Kugel
Bagaimana Anda melakukannya jika membuat panggilan ajax pada formulir ini. Tampaknya form.serialize () tidak mengambil nama tombol kirim ..
mko
@ Kugel benar, ini masih merupakan jawaban terbersih. Terima kasih
Arif YILMAZ
45

Baru saja menulis posting tentang itu: Beberapa tombol kirim dengan ASP.NET MVC :

Pada dasarnya, alih-alih menggunakan ActionMethodSelectorAttribute, saya menggunakan ActionNameSelectorAttribute, yang memungkinkan saya untuk berpura-pura nama tindakan adalah apa pun yang saya inginkan. Untungnya, ActionNameSelectorAttributetidak hanya membuat saya menentukan nama tindakan, tetapi saya dapat memilih apakah tindakan saat ini sesuai dengan permintaan.

Jadi ada kelas saya (tapi saya tidak terlalu suka nama):

public class HttpParamActionAttribute : ActionNameSelectorAttribute {
    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
        if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
            return true;

        if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
            return false;

        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
} 

Untuk menggunakan cukup tentukan formulir seperti ini:

<% using (Html.BeginForm("Action", "Post")) { %>
  <!— form fields -->
  <input type="submit" name="saveDraft" value="Save Draft" />
  <input type="submit" name="publish" value="Publish" />
<% } %> 

dan pengontrol dengan dua metode

public class PostController : Controller {
    [HttpParamAction]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SaveDraft(…) {
        //…
    }

    [HttpParamAction]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Publish(…) {
        //…
    } 
}

Seperti yang Anda lihat, atribut tidak mengharuskan Anda untuk menentukan apa pun. Juga, nama tombol diterjemahkan langsung ke nama metode. Selain itu (saya belum mencobanya) ini harus berfungsi sebagai tindakan normal juga, sehingga Anda dapat memposting ke salah satu dari mereka secara langsung.

Andrey Shchekin
sumber
1
Cantik! Saya pikir ini adalah solusi paling elegan. Menghilangkan nilai dari submittag dari pertimbangan, yang sangat ideal karena merupakan atribut murni-UI yang seharusnya tidak memiliki bantalan pada kontrol aliran. Alih-alih, nameatribut unik dari setiap submittag diterjemahkan secara langsung menjadi metode tindakan terpisah pada pengontrol Anda.
Kirk Woll
+1 Bagi saya, sejauh ini solusi terbaik untuk masalah ini. Karena saya menerapkannya, saya perhatikan bahwa banyak lalu lintas melewati HttpParamActionAttribut tetapi dibandingkan dengan semua hal lain yang harus dilakukan Asp.Net MVC saat memproses permintaan, itu benar-benar dapat diterima. Untuk hanya meretas yang harus saya lakukan adalah meletakkan 'Action' kosong bernama di controller saya untuk mencegah Resharper memperingatkan saya bahwa tindakan 'Action' tidak ada. Terima kasih banyak!
Samuel
Saya meninjau semua solusi dan juga setuju ini adalah solusi yang bagus dan sederhana. Hebat bc tidak ada pernyataan kondisional dan kuat di mana Anda dapat menentukan tindakan pengontrol baru ketika Anda memiliki tombol baru. Disebut kelas saya MultiButtonActionHandler FYI ;-)
ejhost
36

pendek dan sesuai:

Itu dijawab oleh Jeroen Dop

<input type="submit" name="submitbutton1" value="submit1" />
<input type="submit" name="submitbutton2" value="submit2" />

dan lakukan seperti ini di belakang kode

 if( Request.Form["submitbutton1"] != null)
{
    // Code for function 1
}
else if(Request.Form["submitButton2"] != null )
{
       // code for function 2
}

Semoga berhasil.

Ali Golgol
sumber
Luar biasa. persis apa yang saya lakukan di webforms. Cheers buddy
djack109
Jauh lebih sederhana daripada jawaban teratas! Terima kasih!
pabben
35

Saya akan menyarankan pihak yang berkepentingan untuk melihat solusi Maarten Balliauw . Saya pikir ini sangat elegan.

Jika tautan menghilang, ia menggunakan MultiButtonatribut yang diterapkan pada tindakan pengontrol untuk menunjukkan klik tombol mana yang harus dikaitkan dengan tindakan tersebut.

Izmoto
sumber
Ini adalah solusi yang kami gunakan sekarang dan sangat rapi. Apakah hanya MVC 2?
Simon Keep
Ini indah! Saya belum pernah melihat ini sebelumnya! Meskipun saya setuju bahwa Anda mungkin ingin mendesain ulang solusi yang menggunakan banyak pengiriman untuk hanya menggunakan satu tombol, saya berada di tempat di mana saya sembelih dan harus melakukan ini. Jawaban ini seharusnya menang!
Rikon
Ini solusi hebat. Sangat bersih
Arnej65
Mencoba pendekatan ini dan tidak dapat membuatnya bekerja di MVC3. Variasi dari pemilih suara # 1 bekerja untuk saya.
Scott Lawrence
Pendek dan manis .. tetapi tidak untuk mvc 3+
Piotr Kula
21

Anda harus dapat memberi nama tombol dan memberi nilai; lalu petakan nama ini sebagai argumen untuk tindakan tersebut. Atau, gunakan 2 tautan tindakan atau 2 formulir terpisah.

Marc Gravell
sumber
Sejauh ini solusi terbersih dan termudah yang pernah saya lihat.
Jason Evans
13

Anda bisa menulis:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Send" />
<input type="submit" name="button" value="Cancel" />
<% Html.EndForm(); %>

Dan kemudian di halaman periksa apakah nama == "Kirim" atau nama == "Batalkan" ...

Ironicnet
sumber
1
Meskipun ini bekerja, tetapi saya pikir itu salah untuk memiliki dua elemen dengan nama yang sama.
Péter
1
Itu tidak perlu salah. Tergantung bagaimana Anda menggunakan input. Anda dapat memiliki banyak elemen dengan nama yang sama, dan berharap untuk menerima banyak data (beginilah cara kerja radiobuttons dan checkbox). Tapi ya, jika Anda menggunakan metode ini adalah karena Anda melakukannya "salah" ... Itu sebabnya saya meletakkan "Anda bisa" tetapi tidak "Anda harus": P
Ironicnet
12

Sesuatu yang saya tidak suka dari ActionSelectName adalah IsValidName dipanggil untuk setiap metode tindakan di controller; Saya tidak tahu mengapa ini bekerja seperti ini. Saya suka solusi di mana setiap tombol memiliki nama yang berbeda berdasarkan fungsinya, tapi saya tidak suka kenyataan bahwa Anda harus memiliki banyak parameter dalam metode tindakan seperti tombol dalam formulir. Saya telah membuat enum untuk semua jenis tombol:

public enum ButtonType
{
    Submit,
    Cancel,
    Delete
}

Alih-alih ActionSelectName, saya menggunakan ActionFilter:

public class MultipleButtonsEnumAttribute : ActionFilterAttribute
{
    public Type EnumType { get; set; }

    public MultipleButtonsEnumAttribute(Type enumType)
    {
        EnumType = enumType;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        foreach (var key in filterContext.HttpContext.Request.Form.AllKeys)
        {
            if (Enum.IsDefined(EnumType, key))
            {
                var pDesc = filterContext.ActionDescriptor.GetParameters()
                    .FirstOrDefault(x => x.ParameterType == EnumType);
                filterContext.ActionParameters[pDesc.ParameterName] = Enum.Parse(EnumType, key);
                break;
            }
        }
    }
}

Filter akan menemukan nama tombol dalam data formulir dan jika nama tombol cocok dengan salah satu jenis tombol yang ditentukan dalam enum, itu akan menemukan parameter ButtonType di antara parameter tindakan:

[MultipleButtonsEnumAttribute(typeof(ButtonType))]
public ActionResult Manage(ButtonType buttonPressed, ManageViewModel model)
{
    if (button == ButtonType.Cancel)
    {
        return RedirectToAction("Index", "Home");
    }
    //and so on
    return View(model)
}

dan kemudian dalam pandangan, saya bisa menggunakan:

<input type="submit" value="Button Cancel" name="@ButtonType.Cancel" />
<input type="submit" value="Button Submit" name="@ButtonType.Submit" />
sanjuro
sumber
11

Inilah yang paling cocok untuk saya:

<input type="submit" value="Delete" name="onDelete" />
<input type="submit" value="Save" name="onSave" />


public ActionResult Practice(MyModel model, string onSave, string onDelete)
{
    if (onDelete != null)
    {
        // Delete the object
        ...
        return EmptyResult();
    }

    // Save the object
    ...
    return EmptyResult();
}
Sergey
sumber
Saya mendapatkan nilai nol untuk onDelete dan onSave dalam metode controller. Apa kamu tahu kenapa?
Diganta Kumar
Salah satu tidak akan menjadi nol jika Anda mengklik tombol yang sesuai. Tombol mana yang Anda klik untuk mendapatkan null?
Sergey
11

Saya telah menemukan 'masalah' ini juga tetapi menemukan solusi yang lebih logis dengan menambahkan nameatribut. Saya tidak ingat memiliki masalah ini dalam bahasa lain.

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

  • ...
  • Jika suatu formulir berisi lebih dari satu tombol kirim, hanya tombol kirim yang diaktifkan yang berhasil.
  • ...

Berarti valueatribut kode berikut dapat diubah, dilokalkan, diinternasionalkan tanpa perlu kode tambahan memeriksa file sumber daya konstan atau konstanta.

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="send" value="Send" />
<input type="submit" name="cancel" value="Cancel" />
<input type="submit" name="draft" value="Save as draft" />
<% Html.EndForm(); %>`

Di sisi penerima, Anda hanya perlu memeriksa apakah ada jenis pengiriman yang Anda ketahui tidak null

public ActionResult YourAction(YourModel model) {

    if(Request["send"] != null) {

        // we got a send

    }else if(Request["cancel"]) {

        // we got a cancel, but would you really want to post data for this?

    }else if(Request["draft"]) {

        // we got a draft

    }

}
Tom Hofman
sumber
Ini adalah solusi yang kami pilih untuk digunakan untuk aplikasi web sederhana di mana kami menginginkan fungsionalitas ASP.NET WebForms tetapi di dalam MVC.
BrandonG
10

Jika Anda tidak memiliki batasan dalam penggunaan HTML 5, Anda dapat menggunakan <button>tag dengan formactionAtribut:

<form action="demo_form.asp" method="get">
   First name: <input type="text" name="fname" /><br />
   Last name: <input type="text" name="lname" /><br />
   <button type="submit">Submit</button><br />
   <button type="submit" formaction="demo_admin.asp">Submit as admin</button>
</form>

Referensi: http://www.w3schools.com/html5/att_button_formaction.asp

Acaz Souza
sumber
9

Jika browser Anda mendukung formulasi atribut untuk tombol input (IE 10+, tidak yakin tentang browser lain) maka yang berikut ini akan berfungsi:

@using (Html.BeginForm()){
    //put form inputs here

<input id="sendBtn" value="Send" type="submit" formaction="@Url.Action("Name Of Send Action")" />

<input id="cancelBtn" value="Cancel" type="submit" formaction="@Url.Action("Name of Cancel Action") />

}
pengguna3361233
sumber
Lihatlah jawaban saya di bawah ini, tidak bergantung pada spesifikasi konsep. Jawaban Anda memang memungkinkan kemungkinan memiliki url tindakan yang berbeda, yang tidak saya miliki.
Tom Hofman
9

Ada tiga cara yang dapat digunakan untuk menyelesaikan masalah di atas

  1. Cara HTML
  2. Cara jquery
  3. Cara "ActionNameSelectorAttribute"

Di bawah ini adalah video yang merangkum ketiga pendekatan secara demonstratif.

https://www.facebook.com/shivprasad.koirala/videos/vb.100002224977742/809335512483940

Cara HTML: -

Dengan cara HTML kita perlu membuat dua formulir dan menempatkan tombol "Kirim" di dalam masing-masing formulir. Dan setiap tindakan bentuk akan menunjuk ke tindakan yang berbeda / masing-masing. Anda dapat melihat kode di bawah ini formulir pertama memposting ke "Action1" dan bentuk kedua akan memposting ke "Action2" tergantung pada tombol "Kirim" yang diklik.

<form action="Action1" method=post>
<input type=”submit name=”Submit1”/>
</form>

<form action="Action2" method=post>
<input type=”submit name=”Submit2”>
</form>

Cara Ajax: -

Jika Anda seorang pecinta Ajax, opsi kedua ini akan membuat Anda lebih bergairah. Dengan cara Ajax kita dapat membuat dua fungsi berbeda "Fun1" dan "Fun1", lihat kode di bawah ini. Fungsi-fungsi ini akan membuat panggilan Ajax dengan menggunakan JQUERY atau kerangka kerja lainnya. Masing-masing fungsi ini diikat dengan acara "Kirim" tombol "OnClick". Masing-masing fungsi melakukan panggilan ke nama tindakan masing-masing.

<Script language="javascript">
function Fun1()
{
$.post(“/Action1”,null,CallBack1);
}
function Fun2()
{
$.post(“/Action2”,null,CallBack2);
}
</Script>

<form action="/Action1" method=post>
<input type=submit name=sub1 onclick=”Fun2()”/>
</form>
<form action="/Action2" method=post>
<input type=submit name=sub2 onclick=”Fun1()”/>
</form>

Menggunakan "ActionNameSelectorAttribute": -

Ini adalah opsi yang bagus dan bersih. "ActionNameSelectorAttribute" adalah kelas atribut sederhana di mana kita dapat menulis logika pengambilan keputusan yang akan memutuskan tindakan mana yang dapat dieksekusi.

Jadi hal pertama adalah dalam HTML kita harus meletakkan nama yang tepat untuk tombol kirim untuk mengidentifikasi mereka di server.

Anda dapat melihat kami telah memasukkan "Simpan" dan "Hapus" ke nama tombol. Anda juga dapat melihat dalam tindakan yang baru saja kita masukkan nama pengontrol "Pelanggan" dan bukan nama tindakan tertentu. Kami berharap nama tindakan akan diputuskan oleh "ActionNameSelectorAttribute".

<form action=”Customer method=post>
<input type=submit value="Save" name="Save" /> <br />
<input type=submit value="Delete" name="Delete"/>
</form>

Jadi ketika tombol kirim diklik, itu pertama hits atribut "ActionNameSelector" dan kemudian tergantung pada yang mengirimkan dipecat itu memanggil tindakan yang sesuai.

masukkan deskripsi gambar di sini

Jadi langkah pertama adalah membuat kelas yang mewarisi dari kelas "ActionNameSelectorAttribute". Di kelas ini kami telah membuat properti sederhana "Nama".

Kita juga perlu mengganti fungsi "IsValidName" yang mengembalikan true atau flase. Fungsi ini adalah tempat kita menulis logika apakah suatu tindakan harus dijalankan atau tidak. Jadi jika fungsi ini mengembalikan true maka tindakan dieksekusi atau tidak.

public class SubmitButtonSelector : ActionNameSelectorAttribute
    {
        public string Name { get; set; }
        public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
        {
            // Try to find out if the name exists in the data sent from form
var value = controllerContext.Controller.ValueProvider.GetValue(Name);
            if (value != null)
            {
                return true;
            }
            return false;

        }
    }

Jantung utama dari fungsi di atas adalah dalam kode di bawah ini. Koleksi "ValueProvider" memiliki semua data yang telah diposting dari formulir. Jadi pertama-tama mencari nilai "Nama" dan jika ditemukan dalam permintaan HTTP, ia mengembalikan nilai true atau ia mengembalikan nilai false.

var value = controllerContext.Controller.ValueProvider.GetValue(Name);
if (value != null)
      {
        return true;
      }
      return false;

Kelas atribut ini kemudian dapat didekorasi dengan aksi masing-masing dan nilai "Nama" masing-masing dapat diberikan. Jadi jika kiriman memukul tindakan ini dan jika nama yang cocok dengan HTML kirimkan nama tombol itu maka jalankan tindakan lebih lanjut atau yang tidak.

public class CustomerController : Controller
{
        [SubmitButtonSelector(Name="Save")]
        public ActionResult Save()
        {
            return Content("Save Called");
        }
        [SubmitButtonSelector(Name = "Delete")]
        public ActionResult Delete()
        {
            return Content("Delete Called");
        }
}
Shivprasad Koirala
sumber
7

David Findley menulis tentang 3 opsi berbeda yang Anda miliki untuk melakukan ini, di weblog ASP.Net-nya.

Baca artikel banyak tombol dalam bentuk yang sama untuk melihat solusinya, dan kelebihan dan kekurangan masing-masing. IMHO dia memberikan solusi yang sangat elegan yang memanfaatkan atribut yang Anda hiasi dengan tindakan Anda.

Saajid Ismail
sumber
7

Ini adalah teknik yang saya gunakan dan saya belum melihatnya di sini. Tautan (diposting oleh Saajid Ismail) yang menginspirasi solusi ini adalah http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-s---formform .aspx ). Ini mengadaptasi jawaban Dylan Beattie untuk melakukan lokalisasi tanpa masalah.

Dalam Tampilan:

<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<button name="button" value="send"><%: Resources.Messages.Send %></button>
<button name="button" value="cancel"><%: Resources.Messages.Cancel %></button>
<% Html.EndForm(); %>

Di Controller:

public class MyController : Controller 
{
    public ActionResult MyAction(string button)
    {
         switch(button)
         {
             case "send":
                 this.DoSend();
                 break;
             case "cancel":
                 this.DoCancel();
                 break;
         }
    }
}
mlibby
sumber
Sepertinya solusi yang disediakan Ironicnet.
Kris van der Mast
Tentu saja mirip, tetapi ini menunjukkan baik lokalisasi dan kode pengontrol, yang merupakan sesuatu yang saya tidak melihat dilakukan dengan cara ini di utas ini. Saya menemukan utas ini sambil mencari cara melakukan ini dan ingin mendokumentasikan apa yang saya buat untuk orang lain yang mungkin berada di kapal yang sama.
mlibby
1
Bahkan, tidak sama dengan Ironicnet di luar itu. Dia menggunakan <input>elemen. Saya menggunakan <button>, yang diperlukan untuk melakukan pelokalan tanpa memiliki atribut nilai variabel.
mlibby
7

Script ini memungkinkan untuk menentukan atribut data-form-action yang akan berfungsi sebagai atribut formulasi HTML5 di semua browser (dengan cara yang tidak mencolok):

$(document).on('click', '[type="submit"][data-form-action]', function(event) {
    var $this = $(this),
    var formAction = $this.attr('data-form-action'),
    $form = $($this.closest('form'));
    $form.attr('action', formAction);             
});

Formulir yang berisi tombol akan diposting ke URL yang ditentukan dalam atribut data-form-action:

<button type="submit" data-form-action="different/url">Submit</button>   

Ini membutuhkan jQuery 1.7. Untuk versi sebelumnya Anda harus menggunakan live()bukan on().

Jay Douglass
sumber
6

Inilah metode ekstensi yang saya tulis untuk menangani beberapa gambar dan / atau tombol teks.

Inilah HTML untuk tombol gambar:

<input id="btnJoin" name="Join" src="/content/images/buttons/btnJoin.png" 
       type="image">

atau untuk tombol kirim teks:

<input type="submit" class="ui-button green" name="Submit_Join" value="Add to cart"  />
<input type="submit" class="ui-button red" name="Submit_Skip" value="Not today"  />

Ini adalah metode ekstensi yang Anda panggil dari pengontrol form.GetSubmitButtonName(). Untuk tombol gambar, ia mencari parameter formulir dengan .x(yang menunjukkan tombol gambar diklik) dan mengekstrak namanya. Untuk inputtombol biasa, ia mencari nama yang dimulai dengan Submit_dan mengekstrak perintah dari sesudahnya. Karena saya mengabstraksi logika menentukan 'perintah' Anda dapat beralih di antara tombol gambar + teks pada klien tanpa mengubah kode sisi server.

public static class FormCollectionExtensions
{
    public static string GetSubmitButtonName(this FormCollection formCollection)
    {
        return GetSubmitButtonName(formCollection, true);
    }

    public static string GetSubmitButtonName(this FormCollection formCollection, bool throwOnError)
    {
        var imageButton = formCollection.Keys.OfType<string>().Where(x => x.EndsWith(".x")).SingleOrDefault();
        var textButton = formCollection.Keys.OfType<string>().Where(x => x.StartsWith("Submit_")).SingleOrDefault();

        if (textButton != null)
        {
            return textButton.Substring("Submit_".Length);
        }

        // we got something like AddToCart.x
        if (imageButton != null)
        {
            return imageButton.Substring(0, imageButton.Length - 2);
        }

        if (throwOnError)
        {
            throw new ApplicationException("No button found");
        }
        else
        {
            return null;
        }
    }
}

Catatan: Untuk tombol teks Anda harus mengawali nama dengan Submit_. Saya lebih suka cara ini karena itu berarti Anda dapat mengubah nilai teks (tampilan) tanpa harus mengubah kode. Tidak seperti SELECTelemen, sebuah INPUTtombol hanya memiliki atribut 'nilai' dan tidak ada teks 'terpisah'. Tombol saya mengatakan hal-hal yang berbeda dalam konteks yang berbeda - tetapi memetakan ke 'perintah' yang sama. Saya lebih suka mengekstraksi nama dengan cara ini daripada harus kode untuk == "Add to cart".

Simon_Weaver
sumber
Saya suka memeriksa nama sebagai alternatif karena Anda tidak selalu dapat memeriksa nilai misalnya. Anda memiliki daftar item dan masing-masing memiliki tombol "Hapus".
Maks.
6

Saya tidak punya cukup perwakilan untuk berkomentar di tempat yang benar, tetapi saya menghabiskan sepanjang hari untuk ini sehingga ingin berbagi.

Saat mencoba menerapkan solusi "MultipleButtonAttribute" ValueProvider.GetValue(keyValue)akan kembali salah null.

Ternyata saya sedang mereferensikan System.Web.MVC versi 3.0 padahal seharusnya 4.0 (majelis lain adalah 4.0). Saya tidak tahu mengapa proyek saya tidak ditingkatkan dengan benar dan saya tidak punya masalah yang jelas.

Jadi, jika Anda ActionNameSelectorAttributetidak bekerja ... periksa itu.

Heather
sumber
6

Saya sangat terlambat ke pesta, tapi begini ... Implementasi saya meminjam dari @mkozicki tetapi membutuhkan lebih sedikit string yang dikodekan untuk mendapatkan kesalahan. Diperlukan kerangka kerja 4.5+ . Pada dasarnya, nama metode pengontrol harus menjadi kunci untuk perutean.

Markup . Nama tombol harus dikunci dengan"action:[controllerMethodName]"

(perhatikan penggunaan C # 6 nameof API, memberikan referensi tipe khusus untuk nama metode pengontrol yang ingin Anda panggil.

<form>
    ... form fields ....
    <button name="action:@nameof(MyApp.Controllers.MyController.FundDeathStar)" type="submit" formmethod="post">Fund Death Star</button>
    <button name="action:@nameof(MyApp.Controllers.MyController.HireBoba)" type="submit" formmethod="post">Hire Boba Fett</button>
</form>

Pengendali :

namespace MyApp.Controllers
{
    class MyController
    {    
        [SubmitActionToThisMethod]
        public async Task<ActionResult> FundDeathStar(ImperialModel model)
        {
            await TrainStormTroopers();
            return View();
        }

        [SubmitActionToThisMethod]
        public async Task<ActionResult> HireBoba(ImperialModel model)
        {
            await RepairSlave1();
            return View();
        }
    }
}

Atribut Magic . Perhatikan penggunaan CallerMemberNamekebaikan.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class SubmitActionToThisMethodAttribute : ActionNameSelectorAttribute
{        
    public SubmitActionToThisMethodAttribute([CallerMemberName]string ControllerMethodName = "")
    {
        controllerMethod = ControllerMethodName;
        actionFormat = string.Concat(actionConstant, ":", controllerMethod);
    }
    const string actionConstant = "action";
    readonly string actionFormat;
    readonly string controllerMethod;

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        var isValidName = false;
        var value = controllerContext.Controller.ValueProvider.GetValue(actionFormat);

        if (value != null)
        {
            controllerContext.Controller.ControllerContext.RouteData.Values[actionConstant] = controllerMethod;
            isValidName = true;
        }
        return isValidName;
    }
}
Aaron Hudon
sumber
Meskipun ini adalah pendekatan yang bagus, Anda tidak akan dapat menggunakan binder model mvc bawaan karena ia menggunakan atribut tombol "nama".
ooXei1sh
Tujuan dari solusi ini adalah menyelesaikan post routing MVC. Tolong jelaskan perbaikan.
Aaron Hudon
6
[HttpPost]
public ActionResult ConfirmMobile(string nameValueResend, string nameValueSubmit, RegisterModel model)
    {
        var button = nameValueResend ?? nameValueSubmit;
        if (button == "Resend")
        {

        }
        else
        {

        }
    }


    Razor file Content:
    @using (Html.BeginForm()
    {
        <div class="page registration-result-page">

            <div class="page-title">
                <h1> Confirm Mobile Number</h1>
            </div>

            <div class="result">
                @Html.EditorFor(model => model.VefificationCode)
                @Html.LabelFor(model => model.VefificationCode, new { })
                @Html.ValidationMessageFor(model => model.VefificationCode)
            </div>
            <div class="buttons">
                <button type="submit" class="btn" name="nameValueResend" value="Resend">
                    Resend
                </button>
                <button type="submit" class="btn" name="nameValueSubmit" value="Verify">
                    Submit
                </button>

            </div>
            </div>

    }
Mahendra
sumber
Ini adalah tautan bermanfaat lainnya yang menjelaskan berbagai cara penulisan formulir.
Himalaya Garg
5

Saya telah mencoba membuat sintesis dari semua solusi dan menciptakan atribut [ButtenHandler] yang membuatnya mudah untuk menangani banyak tombol pada formulir.

Saya telah menjelaskannya pada beberapa tombol formulir CodeProject Multiple parameterized (localizable) di ASP.NET MVC .

Untuk menangani kasing sederhana dari tombol ini:

<button type="submit" name="AddDepartment">Add Department</button>

Anda akan memiliki sesuatu seperti metode tindakan berikut:

[ButtonHandler()]
public ActionResult AddDepartment(Company model)
{
    model.Departments.Add(new Department());
    return View(model);
}

Perhatikan bagaimana nama tombol cocok dengan nama metode tindakan. Artikel ini juga menjelaskan cara memiliki tombol dengan nilai dan tombol dengan indeks.

pembuat kode
sumber
5
//model
    public class input_element
        {
         public string Btn { get; set; }
        }   

//views--submit btn can be input type also...
    @using (Html.BeginForm())
    {
            <button type="submit" name="btn" value="verify">
             Verify data</button>
            <button type="submit" name="btn" value="save">
             Save data</button>    
            <button type="submit" name="btn" value="redirect">
                 Redirect</button>
    }

//controller

    public ActionResult About()
        {
            ViewBag.Message = "Your app description page.";
            return View();
        }

        [HttpPost]
        public ActionResult About(input_element model)
        {
                if (model.Btn == "verify")
                {
                // the Verify button was clicked
                }
                else if (model.Btn == "save")
                {
                // the Save button was clicked
                } 
                else if (model.Btn == "redirect")
                {
                // the Redirect button was clicked
                } 
                return View();
        }
SHAURAJ SINGH
sumber
Anda mungkin belum menyadarinya, tetapi jawaban yang sama ini sudah diposting beberapa kali untuk pertanyaan ini.
Andrew Barber
2
Juga, Anda sepertinya memposting jawaban yang hanya berisi kode, tanpa penjelasan. Apakah Anda mempertimbangkan untuk menambahkan narasi untuk menjelaskan mengapa kode ini bekerja, dan apa yang membuatnya menjadi jawaban untuk pertanyaan itu? Ini akan sangat membantu bagi orang yang mengajukan pertanyaan, dan siapa pun yang datang.
Andrew Barber
2
Tentu, ini bekerja dengan baik. Tapi jawaban itu sudah diberikan oleh orang lain , dulu sekali. Dan mereka memasukkan penjelasan tentang mengapa itu bekerja juga.
Andrew Barber
5

ini adalah cara terbaik yang saya temukan:

http://iwayneo.blogspot.co.uk/2013/10/aspnet-mvc-action-selector-with-list.html

Ini kodenya:

    /// <summary>
    /// ActionMethodSelector to enable submit buttons to execute specific action methods.
    /// </summary>
    public class AcceptParameterAttribute : ActionMethodSelectorAttribute
   {
        /// <summary>
        /// Gets or sets the value to use to inject the index into
        /// </summary>
       public string TargetArgument { get; set; }

       /// <summary>
       /// Gets or sets the value to use in submit button to identify which method to select. This must be unique in each controller.
       /// </summary>
       public string Action { get; set; }

       /// <summary>
       /// Gets or sets the regular expression to match the action.
       /// </summary>
       public string ActionRegex { get; set; }

       /// <summary>
       /// Determines whether the action method selection is valid for the specified controller context.
       /// </summary>
       /// <param name="controllerContext">The controller context.</param>
       /// <param name="methodInfo">Information about the action method.</param>
       /// <returns>true if the action method selection is valid for the specified controller context; otherwise, false.</returns>
       public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
       {

           if (controllerContext == null)
           {
               throw new ArgumentNullException("controllerContext");
           }

           Func<NameValueCollection> formGetter;
           Func<NameValueCollection> queryStringGetter;

           ValidationUtility.GetUnvalidatedCollections(HttpContext.Current, out formGetter, out queryStringGetter);

           var form = formGetter();
           var queryString = queryStringGetter();

           var req = form.AllKeys.Any() ? form : queryString;

           if (!string.IsNullOrEmpty(this.ActionRegex))
           {
               foreach (var key in req.AllKeys.Where(k => k.StartsWith(Action, true, System.Threading.Thread.CurrentThread.CurrentCulture)))
               {
                   if (key.Contains(":"))
                   {
                       if (key.Split(':').Count() == this.ActionRegex.Split(':').Count())
                       {
                           bool match = false;
                           for (int i = 0; i < key.Split(':').Count(); i++)
                           {
                               if (Regex.IsMatch(key.Split(':')[0], this.ActionRegex.Split(':')[0]))
                               {
                                   match = true;
                               }
                               else
                               {
                                   match = false;
                                   break;
                               }
                           }

                           if (match)
                           {
                               return !string.IsNullOrEmpty(req[key]);
                           }
                       }
                   }
                   else
                   {
                       if (Regex.IsMatch(key, this.Action + this.ActionRegex))
                       {
                           return !string.IsNullOrEmpty(req[key]);
                       }
                   }

               }
               return false;
           }
           else
           {
               return req.AllKeys.Contains(this.Action);
           }
       }
   }

Nikmati tombol multi-kirim-kirim multi-tombol di masa depan.

Terima kasih


sumber
Tautan saat ini rusak, ini adalah versi arsip paling dekat yang bisa saya temukan: web.archive.org/web/20110706230408/http://blogs.sonatribe.com/…
Ian Kemp
Hai Ian - terima kasih telah menggali itu - Saya telah memposting
4

Versi HttpParamActionAttributemetode yang dimodifikasi tetapi dengan perbaikan bug karena tidak menyebabkan kesalahan pada postback sesi yang kadaluwarsa / tidak valid. Untuk melihat apakah ini masalah dengan situs Anda saat ini, buka formulir Anda di jendela dan sesaat sebelum Anda mengklik Saveatau Publish, buka jendela duplikat, dan logout. Sekarang kembali ke jendela pertama Anda dan coba kirim formulir Anda menggunakan salah satu tombol. Bagi saya, saya mendapatkan kesalahan sehingga perubahan ini menyelesaikan masalah itu untuk saya. Saya menghilangkan banyak barang demi singkatnya tetapi Anda harus mendapatkan ide. Bagian-bagian kuncinya adalah penyertaan ActionNamepada atribut dan memastikan nama yang diberikan adalah nama Tampilan yang menunjukkan formulir

Kelas Atribut

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
    private readonly string actionName;

    public HttpParamActionAttribute(string actionName)
    {
        this.actionName = actionName;
    }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
            return true;

        if (!actionName.Equals(this.actionName, StringComparison.InvariantCultureIgnoreCase))
            return false;

        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}

Pengendali

[Authorize(Roles="CanAddContent")]
public ActionResult CreateContent(Guid contentOwnerId)
{
    var viewModel = new ContentViewModel
    {
        ContentOwnerId = contentOwnerId
        //populate rest of view model
    }
    return View("CreateContent", viewModel);
}

[Authorize(Roles="CanAddContent"), HttpPost, HttpParamAction("CreateContent"), ValidateAntiForgeryToken]
public ActionResult SaveDraft(ContentFormModel model)
{
    //Save as draft
    return RedirectToAction("CreateContent");
}

[Authorize(Roles="CanAddContent"), HttpPost, HttpParamAction("CreateContent"), ValidateAntiForgeryToken]
public ActionResult Publish(ContentFormModel model)
{
    //publish content
    return RedirectToAction("CreateContent");
}

Melihat

@using (Ajax.BeginForm("CreateContent", "MyController", new { contentOwnerId = Model.ContentOwnerId }))
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(x => x.ContentOwnerId)

    <!-- Rest of your form controls -->
    <input name="SaveDraft" type="submit" value="SaveDraft" />
    <input name="Publish" type="submit" value="Publish" />
}
Nick Albrecht
sumber
3

Pendekatan JQuery saya menggunakan metode ekstensi:

public static MvcHtmlString SubmitButtonFor<TController>(this HtmlHelper helper, Expression<Action<TController>> action, string value) where TController : Controller
{
    RouteValueDictionary routingValues = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action);

    var onclick = string.Format("$('form').first().attr('action', '/{0}')", string.Join("/", routingValues.Values.ToArray().Where(x => x != null).Select(x => x.ToString()).ToArray()));
    var html = "<input type=\"submit\" value=\"" + value + "\" onclick=\"" + onclick + "\" />";

    return MvcHtmlString.Create(html);
}

Anda bisa menggunakannya seperti ini:

@(Html.SubmitButtonFor<FooController>(c => c.Save(null), "Save"))

Dan itu merender seperti ini:

<input type="submit" value="Save" onclick="$('form').first().attr('action', '/Foo/Save')" >
NahuelGQ
sumber
3

Untuk setiap tombol kirim cukup tambahkan:

$('#btnSelector').click(function () {

    $('form').attr('action', "/Your/Action/);
    $('form').submit();

});
kecelakaan
sumber
3

Berdasarkan jawaban mkozicki saya datang dengan solusi yang sedikit berbeda. Saya masih menggunakan ActionNameSelectorAttributeTapi saya harus menangani dua tombol 'Simpan' dan 'Sinkronisasi'. Mereka melakukan hal yang hampir sama sehingga saya tidak ingin melakukan dua tindakan.

atribut :

public class MultipleButtonActionAttribute : ActionNameSelectorAttribute
{        
    private readonly List<string> AcceptedButtonNames;

    public MultipleButtonActionAttribute(params string[] acceptedButtonNames)
    {
        AcceptedButtonNames = acceptedButtonNames.ToList();
    }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {            
        foreach (var acceptedButtonName in AcceptedButtonNames)
        {
            var button = controllerContext.Controller.ValueProvider.GetValue(acceptedButtonName);
            if (button == null)
            {
                continue;
            }                
            controllerContext.Controller.ControllerContext.RouteData.Values.Add("ButtonName", acceptedButtonName);
            return true;
        }
        return false;
    }
}

melihat

<input type="submit" value="Save" name="Save" />
<input type="submit" value="Save and Sync" name="Sync" />

pengontrol

 [MultipleButtonAction("Save", "Sync")]
 public ActionResult Sync(OrgSynchronizationEditModel model)
 {
     var btn = this.RouteData.Values["ButtonName"];

Saya juga ingin menunjukkan bahwa jika tindakan melakukan hal yang berbeda, saya mungkin akan mengikuti pos mkozicki.

Petr J
sumber
1

Saya telah membuat metode ActionButton untuk HtmlHelper . Ini akan menghasilkan tombol input normal dengan sedikit javascript di acara OnClick yang akan mengirimkan formulir ke Controller / Action yang ditentukan.

Anda menggunakan pembantu seperti itu

@Html.ActionButton("MyControllerName", "MyActionName", "button text")

ini akan menghasilkan HTML berikut

<input type="button" value="button text" onclick="this.form.action = '/MyWebsiteFolder/MyControllerName/MyActionName'; this.form.submit();">

Berikut adalah kode metode ekstensi:

VB.Net

<System.Runtime.CompilerServices.Extension()>
Function ActionButton(pHtml As HtmlHelper, pAction As String, pController As String, pRouteValues As Object, pBtnValue As String, pBtnName As String, pBtnID As String) As MvcHtmlString
    Dim urlHelperForActionLink As UrlHelper
    Dim btnTagBuilder As TagBuilder

    Dim actionLink As String
    Dim onClickEventJavascript As String

    urlHelperForActionLink = New UrlHelper(pHtml.ViewContext.RequestContext)
    If pController <> "" Then
        actionLink = urlHelperForActionLink.Action(pAction, pController, pRouteValues)
    Else
        actionLink = urlHelperForActionLink.Action(pAction, pRouteValues)
    End If
    onClickEventJavascript = "this.form.action = '" & actionLink & "'; this.form.submit();"

    btnTagBuilder = New TagBuilder("input")
    btnTagBuilder.MergeAttribute("type", "button")

    btnTagBuilder.MergeAttribute("onClick", onClickEventJavascript)

    If pBtnValue <> "" Then btnTagBuilder.MergeAttribute("value", pBtnValue)
    If pBtnName <> "" Then btnTagBuilder.MergeAttribute("name", pBtnName)
    If pBtnID <> "" Then btnTagBuilder.MergeAttribute("id", pBtnID)

    Return MvcHtmlString.Create(btnTagBuilder.ToString(TagRenderMode.Normal))
End Function

C # (kode C # baru didekompilasi dari VB DLL, sehingga bisa mendapatkan sedikit keindahan ... tetapi waktunya sangat singkat :-))

public static MvcHtmlString ActionButton(this HtmlHelper pHtml, string pAction, string pController, object pRouteValues, string pBtnValue, string pBtnName, string pBtnID)
{
    UrlHelper urlHelperForActionLink = new UrlHelper(pHtml.ViewContext.RequestContext);
    bool flag = Operators.CompareString(pController, "", true) != 0;
    string actionLink;
    if (flag)
    {
        actionLink = urlHelperForActionLink.Action(pAction, pController, System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(pRouteValues));
    }
    else
    {
        actionLink = urlHelperForActionLink.Action(pAction, System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(pRouteValues));
    }
    string onClickEventJavascript = "this.form.action = '" + actionLink + "'; this.form.submit();";
    TagBuilder btnTagBuilder = new TagBuilder("input");
    btnTagBuilder.MergeAttribute("type", "button");
    btnTagBuilder.MergeAttribute("onClick", onClickEventJavascript);
    flag = (Operators.CompareString(pBtnValue, "", true) != 0);
    if (flag)
    {
        btnTagBuilder.MergeAttribute("value", pBtnValue);
    }
    flag = (Operators.CompareString(pBtnName, "", true) != 0);
    if (flag)
    {
        btnTagBuilder.MergeAttribute("name", pBtnName);
    }
    flag = (Operators.CompareString(pBtnID, "", true) != 0);
    if (flag)
    {
        btnTagBuilder.MergeAttribute("id", pBtnID);
    }
    return MvcHtmlString.Create(btnTagBuilder.ToString(TagRenderMode.Normal));
}

Metode ini memiliki berbagai parameter, tetapi untuk kemudahan penggunaan Anda dapat membuat beberapa kelebihan yang hanya mengambil parameter yang Anda butuhkan.

Maks
sumber