제출 버튼을 누른 MVC


128

내 MVC 양식에 두 개의 버튼이 있습니다.

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

내 컨트롤러 작업에서 어떤 것을 눌렀는지 어떻게 알 수 있습니까?


이 버튼에 클릭시 이벤트를 추가하여 적절한 방법으로 이동하는 자체 AJAX 호출로 이동하십시오. 즉 : <input name="submit" type="submit" id="submit" value="Save" onclick="saveMethod" />?
ragerory

답변:


169

제출 버튼 이름을 동일하게 지정

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

그런 다음 컨트롤러에서 제출 가치를 얻으십시오. 클릭 한 버튼 만 해당 값을 전달합니다.

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

물론 스위치 블록으로 다른 작업을 수행하기 위해 해당 값을 평가할 수 있습니다.

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의 솔루션에는 영향을받지 않습니다.
Richard Szalay 08

동일한 이름을 가진 두 개의 입력은 암시 된 단일 값이 아니라 각 값에 대해 하나의 요소로 배열을 게시합니다. 그래서 나는 이것을 사용하기를 바라고 / 시도했기 때문에 달리 말할 수 있기를 원하지만 이것은 효과가 없습니다.
크리스토퍼 킹

1
@RichardSzalay - 당신은 그냥 사용하지 수 <button type="submit" name="action" value="draft"> Internationalized Save Text </button>, 국제화 목적으로 사용자에 직면 문자열을 사용자 정의 할 수 있도록하고, 폼 요소 이름이 직접적으로 (그 자체 홀수 인) 사용자에게 노출되지 않습니다
KyleMit

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

그리고 컨트롤러 작업에서 :

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

1
매개 변수 목록에 추가하고 올바르게 이름을 지정하면 더 많은 버튼을 추가 할 수 있다고 생각합니다. 좋은 해결책!
GONeale

35

이것은 더 나은 답변이므로 버튼의 텍스트와 값을 모두 가질 수 있습니다.

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>

컨트롤러 :

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

간단히 말해 SUBMIT 버튼이지만 name 속성을 사용하여 이름을 선택하면 컨트롤러 메소드 매개 변수의 name submit 또는 버튼을 의무적으로 사용하지 않으므로 원하는대로 호출 할 수 있습니다 ...


감사합니다 선생님, 이것이 제가 꼭 필요한 것입니다
oHoodie

언어에 따라 버튼의 값을 변경하는 다국어 시스템이 있으면 중단됩니다.
Dave Tapson

Dave-아무도 그런 시스템을 코딩하지는 않을 것 같습니다. 컨트롤러 이름이나 함수 이름을 현지화하는 것과 같습니다. 이 버튼 의 은 서버 측에서만 사용하기위한 것으로, 어디에도 표시되지 않으며 현지화 할 필요가 없습니다.
NickG

20

아래와 같이 이름표에서 버튼을 식별 할 수 있습니다. 컨트롤러에서 이와 같이 확인해야합니다.

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

이것은 버튼 이름을 포스트 액션 결과에 전달하지 않으려는 경우에 매우 유용합니다.
yogihosting

이 시나리오에서는 단위 테스트에서 요청 클래스를 조롱하는 것이 더 복잡 할 수 있습니다.
Muflix

6

다음은 커스텀 MultiButtonAttribute를 사용하여 지시를 따르기 매우 쉽고 좋은 방법입니다.

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

요약하면 제출 버튼을 다음과 같이 만드십시오.

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

이 같은 행동 :

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

그리고이 클래스를 만드십시오 :

[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
블로그가 사라지는 날에 항상 참조 링크를 요약하는 것이 가장 좋습니다. 요약하면 블로그 MultiButtonAttribute는 제출 버튼을 차별화 할 수 있는 사용자 정의 속성을 가지고 있다고 주장 합니다. 실제로 아주 좋은 생각입니다.
코딩 사라지다

1
만약 Arnis L.> : 같은 조언을 따라했다, 당신은 그가 4 년 전에 동일한 링크를 제공하는 것을 눈치 챘을 수도
사라 코딩

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

이는 각 작업마다 맞춤형 매개 변수 세트없이 매우 복잡한 양식 데이터를 일관되게 전달할 수있어 복잡한 형식에 대해 컨트롤러 논리를 고도로 사용자 정의 할 수 있으므로 게시 된 모든 항목에 대한 우수한 솔루션입니다. Kudos Fredrik :)이 FormCollection이 여러 형식으로 전달된다고 가정합니까?
Stokely

스토 클리 감사합니다. 여러 양식에서이 메소드를 호출 할 수 있습니다. ajax 호출을 수행하는 경우 동일한 FormCollection에 많은 양식을 포함 할 수 있습니다.
프레드릭 스티 그슨

3

더 쉽게하기 위해 버튼을 다음과 같이 변경할 수 있다고 말합니다.

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

컨트롤러 :

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

2

이 게시물은 오래 전에 답변을 받았기 때문에 Coppermill에 대답하지 않을 것입니다. 내 게시물은 이와 같은 솔루션을 찾는 사람에게 도움이 될 것입니다. 우선, "WDuffy의 솔루션은 완전히 정확합니다"라고 말해야하지만 제대로 작동하지만 내 솔루션 (실제로 내 것이 아닌)이 다른 요소에 사용되며 프리젠 테이션 레이어를 컨트롤러와 더 독립적으로 만듭니다 (컨트롤러가 의존하기 때문에) 버튼의 레이블을 표시하는 데 사용되는 "값",이 기능은 다른 언어에 중요합니다.)

여기 내 해결책이 있습니다. 다른 이름을 지정하십시오.

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

그리고 아래와 같은 동작에서 버튼 이름을 인수로 지정해야합니다.

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

사용자가 버튼 중 하나를 사용하여 페이지를 제출하면 인수 중 하나만 값을 갖습니다. 나는 이것이 다른 사람들에게 도움이 될 것이라고 생각합니다.

최신 정보

이 답변은 꽤 오래되었고 실제로 내 의견을 재고합니다. 아마도 위의 솔루션은 매개 변수를 모델의 속성에 전달하는 상황에 적합합니다. 귀찮게하지 말고 프로젝트에 가장 적합한 솔루션을 선택하십시오.


다음과 같은 건설적인 비판이 있습니다.이 게시물을 게시 할 때 기존 답변이 잘 적용됩니다. 또한 이것은 잘 확장되지 않습니다. HTML input[type=submit]은 트리거 된 값만 다시 게시 하므로 모든 모델이 동일한 name(예 :) 속성에 바인딩 action할 수 있으며 value서명에 많은 변수를 도입 할 필요없이 해당 문자열을 기반으로 버튼을 구별 할 수 있습니다 . 게시하기 전에 형식 / 들여 쓰기에 대해 생각하는 데 시간이 걸릴 수 있습니다.
KyleMit

0

Request.Form Collection을 사용하여 찾을 수 없습니까? 프로세스를 클릭하면 request.form [ "process"]이 비어 있지 않습니다.


0

두 버튼 모두에 이름을 지정하고 양식에서 값을 확인하십시오.

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

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

컨트롤러 쪽 :

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 페이지에서이 구문은 작동합니다.

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

작동하지만 매개 변수 string submit대 쓰기를 선호합니다 string submit = Request.Form["Submit"];. Razor Pages 및 / 또는 MVC의 가장 큰 장점 중 하나는 메소드의 가독성이며, 그렇지 않으면 PHP 일 수 있습니다.
yzorg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.