MVC mà nút gửi đã được nhấn


127

Tôi có hai nút trên mẫu MVC của mình:

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

Từ hành động điều khiển của tôi, làm thế nào để tôi biết cái nào đã được nhấn?


Tại sao không chỉ thêm các sự kiện onclick vào các nút này để thực hiện cuộc gọi AJAX của riêng họ mà sẽ đi đến các phương thức thích hợp của họ? tức là : <input name="submit" type="submit" id="submit" value="Save" onclick="saveMethod" />?
ragerory

Câu trả lời:


168

Đặt tên cho cả hai nút gửi của bạn giống nhau

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

Sau đó, trong bộ điều khiển của bạn nhận được giá trị của trình. Chỉ nút được nhấp sẽ vượt qua giá trị của nó.

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

Tất nhiên bạn có thể đánh giá giá trị đó để thực hiện các hoạt động khác nhau với một khối chuyển đổi.

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
Coi chừng các vấn đề mà nội địa hóa có thể mang lại cho giải pháp này, mà giải pháp của Darin không dễ bị ảnh hưởng.
Richard Szalay

Hai đầu vào có cùng tên dẫn đến một mảng được đăng với một phần tử cho mỗi giá trị, không phải là một giá trị như ngụ ý. Vì vậy, tôi ước tôi có thể nói khác vì tôi đã hy vọng / cố gắng sử dụng nó, nhưng điều này không hiệu quả.
Christopher King

1
@RichardSzalay - bạn không thể chỉ sử dụng <button type="submit" name="action" value="draft"> Internationalized Save Text </button>cho mục đích i18n, vì vậy chuỗi phải đối mặt với người dùng có thể tùy chỉnh và tên thành phần của biểu mẫu không bao giờ được hiển thị trực tiếp với người dùng (chính là số lẻ)
KyleMit 19/03/18

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

Và trong hành động điều khiển của bạn:

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

1
Tôi tưởng tượng nhiều nút có thể được thêm vào bằng cách thêm nó vào danh sách tham số và đặt tên chính xác. Giải pháp tốt đẹp!
GONeale

35

Đây là một câu trả lời tốt hơn, vì vậy chúng ta có thể có cả văn bản và giá trị cho một nút:

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

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

và bộ điều khiển:

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

nói ngắn gọn là nút SUBMIT nhưng bạn chọn tên bằng thuộc tính name, nó thậm chí còn mạnh hơn bởi vì bạn không bắt buộc phải gửi tên hoặc nút trong các tham số của phương thức điều khiển, bạn có thể gọi nó như bạn muốn ...


Cảm ơn ngài, đây chính xác là những gì tôi cần
oHoodie

Điều này sẽ phá vỡ nếu bạn có một hệ thống đa ngôn ngữ thay đổi giá trị của nút theo ngôn ngữ.
Dave Tapson

Dave - Tôi không nghĩ ai sẽ viết mã cho một hệ thống như vậy. Điều đó giống như nội địa hóa tên bộ điều khiển hoặc tên hàm của bạn. Các giá trị của các nút là cho phía máy chủ chỉ sử dụng - nó không hiển thị bất cứ nơi nào và không cần phải có tính cục bộ.
NickG

20

bạn có thể xác định nút của mình từ đó có thẻ tên như bên dưới, Bạn cần kiểm tra như thế này trong bộ điều khiển của bạn

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

Điều này rất hữu ích trong các tình huống khi bạn không muốn chuyển tên của nút cho trình xử lý bài đăng.
Yogihosting

trong kịch bản này có thể phức tạp hơn để giả định lớp Yêu cầu trong bài kiểm tra đơn vị.
Muflix

6

Đây là một cách thực hiện đơn giản và tốt đẹp với cách thực hiện dễ dàng theo hướng dẫn bằng cách sử dụng MultiButtonAttribution tùy chỉnh:

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

Để tóm tắt, hãy tạo các nút gửi của bạn như thế này:

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

Hành động của bạn như thế này:

[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");
} 

Và tạo lớp này:

[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
Luôn luôn tốt nhất để tóm tắt một liên kết được tham chiếu (cho ngày mà blog biến mất). Tóm lại, blog ủng hộ việc có một MultiButtonAttributethuộc tính tùy chỉnh để cho phép phân biệt giữa các nút gửi. Trên thực tế khá là một ý tưởng tốt.
Mã hóa

1
Và nếu Arnis L.đã làm theo lời khuyên tương tự, bạn có thể nhận thấy rằng anh ấy đã cung cấp cùng một liên kết chính xác 4 năm trước:>
Mã hóa

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

Đây là một giải pháp ưu việt cho mọi thứ khác được đăng vì nó cho phép dữ liệu biểu mẫu rất phức tạp được truyền một cách nhất quán mà không cần các bộ tham số tùy chỉnh trong mỗi hành động, cho phép logic điều khiển có thể tùy chỉnh cao cho các dạng phức tạp. Kudos Fredrik :) Tôi cho rằng FormCollection này sẽ vượt qua dưới nhiều hình thức?
Stokely

Cảm ơn bạn một cách kiên quyết. Bạn có thể gọi phương thức này từ nhiều biểu mẫu, nếu bạn thực hiện cuộc gọi ajax thì bạn có thể bao gồm nhiều biểu mẫu trong cùng một FormCollection.
Fredrik Stigsson

3

Để dễ dàng hơn, tôi sẽ nói bạn có thể thay đổi các nút của mình như sau:

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

Bộ điều khiển của bạn:

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

2

Bài đăng này sẽ không trả lời cho Coppermill, bởi vì anh ấy đã được trả lời từ lâu. Bài viết của tôi sẽ hữu ích cho những người sẽ tìm kiếm giải pháp như thế này. Trước hết, tôi phải nói "Giải pháp của WDuffy hoàn toàn chính xác" và nó hoạt động tốt, nhưng giải pháp của tôi (không thực sự là của tôi) sẽ được sử dụng trong các yếu tố khác và nó làm cho lớp trình bày độc lập hơn với bộ điều khiển (vì bộ điều khiển của bạn phụ thuộc vào "value" được sử dụng để hiển thị nhãn của nút, tính năng này rất quan trọng đối với các ngôn ngữ khác.).

Đây là giải pháp của tôi, cung cấp cho họ các tên khác nhau:

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

Và bạn phải chỉ định tên của các nút làm đối số trong hành động như dưới đây:

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

khi người dùng gửi trang bằng một trong các nút, chỉ một trong các đối số sẽ có giá trị. Tôi đoán điều này sẽ hữu ích cho những người khác.

Cập nhật

Câu trả lời này khá cũ và tôi thực sự xem xét lại ý kiến ​​của mình. có lẽ giải pháp trên là tốt cho tình huống chuyển tham số cho các thuộc tính của mô hình. đừng tự làm phiền mình và có giải pháp tốt nhất cho dự án của bạn.


Một số lời chỉ trích mang tính xây dựng cùng: điều này được bao phủ tốt bởi các câu trả lời hiện có khi bạn đăng bài này. Ngoài ra, điều này không có quy mô tốt. HTML sẽ chỉ đăng lại input[type=submit]giá trị đã được kích hoạt, vì vậy tất cả chúng có thể mô hình liên kết với một thuộc tính có cùng name(ví dụ action) và sau đó bạn có thể phân biệt các nút dựa trên valuechuỗi đó mà không cần phải giới thiệu nhiều biến trong chữ ký của bạn . Xin vui lòng dành chút thời gian để suy nghĩ về định dạng / thụt lề trước khi đăng.
KyleMit

0

Bạn có thể không tìm ra bằng cách sử dụng Request.Form Collection? Nếu quá trình được nhấp vào request.form ["process"] sẽ không trống


0

Đặt tên cho cả hai nút và Nhận giá trị từ biểu mẫu.

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

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

Về phía bộ điều khiển:

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

Trong trang Core 2.2 Dao cạo, cú pháp này hoạt động:

    <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)
       {
       .......

Nó có thể hoạt động, nhưng tôi thích tham số string submitso với viết string submit = Request.Form["Submit"];. Một trong những lợi ích lớn nhất của Trang dao cạo và / hoặc MVC là khả năng đọc của các phương thức, nếu không nó có thể là PHP.
yzorg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.