[C#] ASP.NET MVC Framework에서 여러 제출 단추를 어떻게 처리합니까?

동일한 양식의 여러 제출 버튼을 처리하는 쉬운 방법이 있습니까? 예를 들면 다음과 같습니다.

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

ASP.NET Framework Beta 에서이 작업을 수행하는 방법을 알고 있습니까? 내가 검색 한 모든 예제에는 단일 버튼이 있습니다.



답변

다음은 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;
    }
}

면도칼:

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

컨트롤러 :

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

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

업데이트 : Razor 페이지기본적으로 동일한 기능을 제공하는 것으로 보입니다. 새로운 개발의 경우 바람직 할 수 있습니다.


답변

제출 버튼의 이름을 지정한 다음 컨트롤러 방법에서 제출 된 값을 검사하십시오.

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

에 게시

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

}

편집하다:

현지화 된 사이트에서 작업하도록이 방법을 확장하려면 메시지를 다른 곳에서 격리하십시오 (예 : 리소스 파일을 강력한 형식의 리소스 클래스로 컴파일)

그런 다음 코드가 다음과 같이 작동하도록 수정하십시오.

<% 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(); %>

컨트롤러는 다음과 같아야합니다.

// 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());
}


답변

언급 된대로 조치에서 이름을 확인할 수 있지만 이것이 좋은 디자인인지 여부를 고려할 수 있습니다. 작업의 책임을 고려하고이 디자인을 버튼 이름과 같은 UI 측면에 너무 많이 연결하지 않는 것이 좋습니다. 따라서 두 가지 양식과 두 가지 조치를 사용하십시오.

<% 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(); %>

또한 “취소”의 경우 일반적으로 양식을 처리하지 않고 새 URL로 이동합니다. 이 경우 양식을 전혀 제출할 필요가 없으며 링크 만 있으면됩니다.

<%=Html.ActionLink("Cancel", "List", "MyController") %>


답변

Eilon은 다음과 같이 할 수 있다고 제안합니다.

하나 이상의 버튼이있는 경우 각 버튼에 이름을 지정하여 구별 할 수 있습니다.

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

컨트롤러 조치 방법에서 HTML 입력 태그 이름을 따라 이름 지정된 매개 변수를 추가 할 수 있습니다.

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

해당 매개 변수 중 하나에 값이 게시되면 해당 버튼이 클릭 된 것입니다. 웹 브라우저 는 클릭 버튼 하나에 만 값을 게시합니다 . 다른 모든 값은 null입니다.

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

할당 된 이름보다 변경 될 가능성이 높고 자바 스크립트를 활성화 할 필요가없는 제출 버튼의 value 속성에 의존하지 않기 때문에이 방법을 좋아합니다.

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


답변

그냥 그것에 대해 게시물을 작성 :
복수는 ASP.NET MVC로 전송 버튼 :

기본적으로, 대신 사용하여 ActionMethodSelectorAttribute내가 사용하고,
ActionNameSelectorAttribute나를 액션 이름을 척 할 수있는 것은, 내가이 원하는 모든 것이다. 다행히도 ActionNameSelectorAttribute동작 이름을 지정하지 않고 현재 동작이 요청과 일치하는지 여부를 선택할 수 있습니다.

그래서 내 수업이 있습니다 (btw 나는 너무 좋아하지 않습니다).

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

다음과 같이 양식을 정의하려면 사용하십시오.

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

두 가지 방법으로 컨트롤러

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

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

보시다시피, 속성은 아무것도 지정하지 않아도됩니다. 또한 버튼 이름은 메소드 이름으로 직접 변환됩니다. 또한 (내가 시도하지 않았 음) 이들은 정상적인 동작으로 작동해야하므로 직접 게시 할 수 있습니다.


답변

짧고 스위트입니다.

그것은 Jeroen Dop 에 의해 답변되었습니다

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

코드 뒤에 이런 식으로

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

행운을 빕니다.


답변

나는 이해 당사자 가 Maarten Balliauw의 솔루션을 살펴볼 것을 제안 합니다 . 나는 그것이 매우 우아하다고 생각합니다.

링크가 사라지면 MultiButton컨트롤러 작업에 적용된 속성을 사용하여 해당 작업과 관련된 버튼 클릭을 나타냅니다.