programing

ASP에서 여러 개의 제출 버튼을 처리하는 방법은 무엇입니까?NET MVC 프레임워크?

minimums 2023. 4. 8. 08:18
반응형

ASP에서 여러 개의 제출 버튼을 처리하는 방법은 무엇입니까?NET MVC 프레임워크?

같은 양식의 여러 개의 제출 버튼을 쉽게 처리할 수 있는 방법이 있습니까?예를 들어 다음과 같습니다.

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

ASP에서 이 작업을 수행하는 방법을 알고 계십니까?NET Framework 베타판?내가 검색해본 모든 예에는 버튼이 하나 있다.

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

업데이트: 레이저 페이지도 개봉 즉시 동일한 기능을 제공할 수 있습니다.새로운 개발에는 그것이 더 좋을 수 있다.

[ Submit ]버튼에 이름을 붙이고 다음으로 컨트롤러 방식으로 전송된 값을 검사합니다.

<% 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 측면과 너무 많이 결합하지 말고 액션의 책임을 고려하는 것이 좋습니다.따라서 2가지 폼과 2가지 액션을 사용하는 것을 고려해 주십시오.

<% 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 */ }

이 방법은 지정된 이름보다 변경 가능성이 높은 제출 버튼의 값 속성에 의존하지 않고 Javascript를 활성화할 필요가 없기 때문에 마음에 듭니다.

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

ASP를 포함한 복수의 송신 버튼에 관한 투고를 방금 작성했습니다.NET MVC:

본본,,를 사용하지 않고,ActionMethodSelectorAttribute , , 을 사용하고 .ActionNameSelectorAttribute액션명을 원하는 대로 연기할 수 있습니다.ActionNameSelectorAttribute에서는 액션명을 지정할 뿐만 아니라 현재 액션이 요구와 일치하는지 여부를 선택할 수 있습니다.

그래서 내 수업도 있다(하지만 나는 그 이름이 별로 마음에 들지 않는다).

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" />
<% } %> 

및 컨트롤러는 2가지 방법으로

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

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

보시다시피 Atribute에서는 아무것도 지정할 필요가 없습니다.또한 버튼의 이름은 메서드 이름으로 직접 변환됩니다.또한 (아직 시도하지 않았습니다) 이러한 작업도 정상적으로 작동해야 하므로 어떤 작업에도 직접 글을 올릴 수 있습니다.

짧고 스위트:

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
}

행운을 빌어요.

나는 관심있는 사람들이 마텐 발리오우의 해결책을 볼 을 제안합니다.굉장히 우아한 것 같아요.

가 소멸된 링크는 ""를 합니다.MultiButtonAtribute를 컨트롤러 액션에 적용하여 해당 액션과 관련된 버튼클릭을 나타냅니다.

버튼의 이름을 지정하고 값을 지정할 수 있어야 합니다.이 이름을 인수로 액션에 매핑할 수 있습니다.또는 2개의 개별 액션링크 또는 2개의 형식을 사용합니다.

다음과 같이 쓸 수 있습니다.

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

그런 다음 페이지에서 이름 == "보내기" 또는 이름 == "취소"를 확인합니다.

'문제'를 '문제'를 '문제'라고 해서 '문제'를 좀 .name다른 언어에서는 이 문제가 있었던 것을 기억할 수 없었습니다.

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

  • ...
  • 폼에 복수의 송신 버튼이 포함되어 있는 경우는, 액티브한 송신 버튼만이 성공합니다.
  • ...

코드라는 뜻이죠.value속성을 변경, 현지화, 국제화할 수 있습니다.강력하게 보호된 리소스 파일이나 상수를 추가로 코드 체크할 필요는 없습니다.

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

에서는, 이, 송신 타입이, 송신 타입이, 송신 타입이, 타입이, 타입을 .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

    }

}

Action Select Name이 마음에 들지 않는 점은 IsValidName이 컨트롤러의 모든 액션 메서드에 대해 호출된다는 것입니다.왜 이렇게 동작하는지 모르겠습니다.저는 버튼마다 동작에 따라 이름이 달라지는 솔루션을 좋아하지만, 동작 방법에는 폼의 버튼만큼 많은 파라미터가 있어야 한다는 점이 마음에 들지 않습니다.모든 버튼 유형에 대한 열거를 만들었습니다.

public enum ButtonType
{
    Submit,
    Cancel,
    Delete
}

Action Select Name 대신 Action Filter를 사용합니다.

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

필터는 폼 데이터에서 버튼 이름을 찾고 버튼 이름이 열거에 정의된 버튼 유형 중 하나와 일치하는 경우 액션 매개 변수 중 ButtonType 매개 변수를 찾습니다.

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

뷰에서 다음을 사용할 수 있습니다.

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

나에게 가장 적합한 것은 다음과 같습니다.

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

브라우저가 입력 버튼 속성 형식(IE 10+, 다른 브라우저에 대해서는 확실하지 않음)을 지원하는 경우 다음 기능이 작동합니다.

@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") />

}

5 의 이 없는 는, 5 를 할 수 .<button>를 달다formaction★★★★

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

참고 자료: http://www.w3schools.com/html5/att_button_formaction.asp

위의 문제를 해결하려면 세 가지 방법이 있습니다.

  1. HTML 방식
  2. 쭈리웨이
  3. "Action Name Selector Attribute" 방법

아래는 세 가지 접근 방식을 모두 예시적으로 요약한 비디오입니다.

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

HTML 방식:-

HTML 방식으로 두 개의 양식을 만들고 각 양식 안에 "Submit" 버튼을 배치해야 합니다.그리고 모든 형태의 행동이 각기 다른/각각의 행동을 가리킵니다.아래 코드는 첫 번째 폼이 "Action1"에 게시하고 두 번째 폼이 "Action2"에 게시하는 것으로, 어떤 "Submit" 버튼을 클릭하느냐에 따라 달라집니다.

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

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

Ajax 방법:-

만약 당신이 아약스 애호가라면 이 두 번째 옵션은 당신을 더 흥분시킬 것이다.Ajax 방법에서는 Fun1과 Fun1의 두 가지 함수를 만들 수 있습니다.다음 코드를 참조해 주십시오.이러한 함수는 JQUERY 또는 다른 프레임워크를 사용하여 Ajax 콜을 발신합니다.이러한 각 기능은 "Submit(제출)" 버튼의 "OnClick(온클릭)" 이벤트와 바인딩됩니다.각 함수는 각각의 액션명을 호출합니다.

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

Action Name Selector Attribute 사용:-

이것은 훌륭하고 깨끗한 옵션입니다."ActionNameSelectorAttribute"는 실행할 수 있는 액션을 결정하는 의사결정 로직을 쓸 수 있는 단순한 속성 클래스입니다.

우선 HTML에서 서버상에서 식별하기 위해서 송신 버튼에 적절한 이름을 붙여야 합니다.

버튼명에 「Save(저장)」와「Delete(삭제)」가 붙어 있는 것을 알 수 있습니다.또, 액션에서는, 컨트롤러명 「Customer(고객)」를 붙였을 뿐, 특정의 액션명이 아닌 것을 알 수 있습니다.액션명은 "Action Name Selector Attribute"에 의해 결정됩니다.

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

따라서 [Submit]버튼을 클릭하면 먼저 [ActionNameSelector]속성에 도달하고 다음으로 어떤 전송이 실행되는지 여부에 따라 적절한 액션이 실행됩니다.

여기에 이미지 설명 입력

따라서 첫 번째 단계는 "ActionNameSelectorAttribute" 클래스에서 상속하는 클래스를 만드는 것입니다.이 클래스에서는 간단한 속성 "Name"을 만들었습니다.

또한 true 또는 flase를 반환하는 "IsValidName" 함수를 재정의해야 합니다.이 함수는 동작을 실행할 필요가 있는지 없는지에 대한 논리를 작성하는 곳입니다.따라서 이 함수가 true를 반환하면 액션이 실행되고 그렇지 않으면 실행되지 않습니다.

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;

        }
    }

위 기능의 중심은 아래 코드에 있습니다."ValueProvider" 컬렉션에는 폼에서 게시된 모든 데이터가 포함되어 있습니다.따라서 먼저 "Name" 값을 검색하고 HTTP 요청에서 값이 발견되면 true를 반환하거나 그렇지 않으면 false를 반환합니다.

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

이 속성 클래스는 각 액션에 장식할 수 있으며 각각의 "이름" 값을 제공할 수 있습니다.따라서 전송이 이 액션을 누르고 HTML 전송 버튼 이름의 이름과 일치하는 경우 해당 액션은 더 실행되고 그렇지 않으면 실행되지 않습니다.

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

이 스크립트를 사용하면 모든 브라우저에서 HTML5 폼액션 속성으로 동작하는 데이터 폼액션 속성을 지정할 수 있습니다(중요하지 않은 방법으로).

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

버튼을 포함하는 폼은 data-form-action 속성으로 지정된 URL에 게시됩니다.

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

jQuery 1.7입니다.이전 버전의 경우 다음을 사용해야 합니다.live()on().

David Findley는 이를 위해 사용할 수 있는 3가지 다른 옵션을 자신의 ASP에 기록합니다.넷 웹 로그

같은 형식의 여러 버튼을 읽어보고 솔루션과 각각의 장점과 단점을 확인하십시오.IMHO는 당신의 행동을 꾸미는 속성을 활용하는 매우 우아한 솔루션을 제공합니다.

이건 내가 쓰려고 했던 기술인데 아직 여기엔 안 보이는데요.이 솔루션에 영감을 주는 링크(Saajid Ismail)는 http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx) 입니다.딜런 비티의 답변에 맞춰 현지화를 문제없이 할 수 있도록 했다.

보기:

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

컨트롤러:

public class MyController : Controller 
{
    public ActionResult MyAction(string button)
    {
         switch(button)
         {
             case "send":
                 this.DoSend();
                 break;
             case "cancel":
                 this.DoCancel();
                 break;
         }
    }
}
[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>

    }

다음은 여러 이미지 및/또는 텍스트 버튼을 처리하기 위해 작성한 확장 방법입니다.

이미지 버튼의 HTML은 다음과 같습니다.

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

또는 텍스트 전송 버튼의 경우:

<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"  />

는 다음과 .form.GetSubmitButtonName() 버튼의 .이 파라미터를 찾습니다..x(이미지 버튼이 클릭되었음을 나타냅니다).이름을 추출합니다. 귤러의 input는 이름 을 찾습니다.Submit_이치노명령어를 결정하는 논리를 추상화하고 있기 때문에 서버 측 코드를 변경하지 않고 클라이언트의 이미지와 텍스트 버튼을 전환할 수 있습니다.

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

주의: 텍스트 버튼의 경우 이름 앞에 다음을 붙여야 합니다.Submit_코드 변경 없이 텍스트(표시) 값을 변경할 수 있기 때문에 이 방법을 선호합니다.★★★★★★★★★★★★★★★와 달리SELECT 요,, 요,, 、INPUT버튼에는 '값'만 있고 별도의 '텍스트' 속성은 없습니다.내 버튼은 다른 컨텍스트에서 다른 내용을 표시하지만 동일한 '명령어'에 매핑됩니다.을 보다 훨씬 .== "Add to cart"

정확한 장소에서 코멘트를 할 수 있는 충분한 평판은 없지만, 하루 종일 이 일에 몰두했기 때문에 공유하고 싶습니다.

Button Attribute" "Multiple Button Attribute" 중ValueProvider.GetValue(keyValue) 돌아오다null.

알고보니 제가 '시스템'을 참조하고 있었어요.Web.MVC 버전 3.0(기타 어셈블리는 4.0).프로젝트가 올바르게 업그레이드되지 않은 이유를 알 수 없으며 다른 명백한 문제는 없었습니다.

만약 의 ★★★★★★★★★★★★★★★★★★★★★★★★★.ActionNameSelectorAttribute확인해봐.

파티에 좀 늦었지만...구현은 @mkozicki에서 차용하고 있습니다만, 잘못하기 위해서는 하드 코드화된 문자열이 적게 필요합니다.Framework 4.5 이상이 필요합니다.기본적으로는 컨트롤러 방식명이 라우팅의 키여야 합니다.

마크업. 버튼 이름은 다음 기호로 입력해야 합니다."action:[controllerMethodName]"

(C#6 API 이름의 사용에 주의하여 기동하는 컨트롤러 메서드의 이름을 특정 유형으로 참조할 수 있습니다.

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

컨트롤러:

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

Attribute Magic.선한 것의 사용에 주목하라.

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

저는 모든 솔루션을 종합하여 폼의 여러 버튼을 쉽게 처리할 수 있는 [Butten Handler]속성을 만들었습니다.

ASP의 Code Project Multiple parameterized(로컬라이즈 가능) 버튼에 기재되어 있습니다.NET MVC

이 버튼의 간단한 케이스를 처리하려면:

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

다음과 같은 처리 방법이 있습니다.

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

버튼의 이름이 액션 메서드의 이름과 어떻게 일치하는지 주목하십시오.또한 이 문서에서는 값이 있는 버튼과 인덱스가 있는 버튼을 갖는 방법에 대해서도 설명합니다.

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

" " " " 의 HttpParamActionAttribute유효기간 만료/불필요한 세션 포스트백에서 오류를 발생시키지 않는 버그 수정이 필요합니다.을 열고 에 을 합니다.Save ★★★★★★★★★★★★★★★★★」Publish중복 창을 열고 로그아웃합니다.이제 첫 번째 창으로 돌아가서 두 버튼 중 하나를 사용하여 양식을 제출해 보십시오.저는 에러가 났기 때문에 이 변경으로 그 문제가 해결되었습니다.나는 간결하게 하기 위해 많은 것들을 생략하지만 너는 이해해야 한다.은 '하다' 입니다.ActionName인지 확인합니다.

속성 클래스

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

컨트롤러

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

보다

@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" />
}

이게 내가 찾은 가장 좋은 방법이야

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

코드는 다음과 같습니다.

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

코드 냄새가 없는 멀티 송신 버튼을 이용하세요.

감사해요.

나는 mkozicki의 답변을 바탕으로 조금 다른 해결책을 생각해냈다.도 쓰고 요.ActionNameSelectorAttribute하지만 '저장'과 '동기화' 버튼 두 개를 처리해야 했습니다.그들은 거의 똑같이 하기 때문에 나는 두 가지 행동을 하고 싶지 않았다.

속성:

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

보다

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

컨트롤러

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

또, 행동이 다르면, 아마 mkozicki 포스트에 팔로우 할 것이라고 지적하고 지적하고 싶습니다.

확장 방식을 사용하는 내 JQuery 접근 방식:

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

다음과 같이 사용할 수 있습니다.

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

그리고 다음과 같이 표현됩니다.

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

각 제출 버튼에 대해 다음을 추가하십시오.

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

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

});

HtmlHelper용 ActionButton 메서드를 만들었습니다.OnClick 이벤트에서 javascript가 포함된 일반 입력 버튼이 생성되어 지정된 컨트롤러/액션에 폼이 제출됩니다.

도우미를 그렇게 사용해요.

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

이것은 다음 HTML을 생성합니다.

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

확장 방식 코드는 다음과 같습니다.

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#(C# 코드는 VB DLL에서 디컴파일되어 있기 때문에 미화를 얻을 수 있습니다.시간이 너무 짧아요 :-)

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

이러한 메서드에는 다양한 파라미터가 있지만 사용하기 쉽도록 필요한 파라미터만 사용하는 오버로드를 생성할 수 있습니다.

언급URL : https://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework

반응형