HTTPPOST, 사전 또는에서 양식 값을 검색하는 방법은 무엇입니까?


112

이 작업 방법이있는 MVC 컨트롤러가 있습니다.

[HttpPost]
public ActionResult SubmitAction()
{
     // Get Post Params Here
 ... return something ...
}

양식은 단순한 텍스트 상자가있는 사소한 양식입니다.

질문

매개 변수 값에 어떻게 액세스합니까?

보기에서 게시하지 않고 게시물이 외부에서 제공됩니다. 액세스 할 수있는 키 / 값 쌍 모음이 있다고 가정합니다.

시도 Request.Params.Get("simpleTextBox");했지만 "죄송합니다. 요청을 처리하는 동안 오류가 발생했습니다."라는 오류가 표시됩니다.

답변:


155

컨트롤러 작업이 양식 입력 이름을 반영하는 개체를 취하도록 할 수 있으며 기본 모델 바인더가 자동으로이 개체를 생성합니다.

[HttpPost]
public ActionResult SubmitAction(SomeModel model)
{
    var value1 = model.SimpleProp1;
    var value2 = model.SimpleProp2;
    var value3 = model.ComplexProp1.SimpleProp1;
    ...

    ... return something ...
}

또 다른 (분명히 추악한) 방법은 다음과 같습니다.

[HttpPost]
public ActionResult SubmitAction()
{
    var value1 = Request["SimpleProp1"];
    var value2 = Request["SimpleProp2"];
    var value3 = Request["ComplexProp1.SimpleProp1"];
    ...

    ... return something ...
}

5
옵션 2의 컴파일러 백업이 손실된다는 점을 지적하고 싶습니다. 모델이 변경되면 컴파일러가 관련 컨트롤러의 변경 사항을 포착하지 못합니다. 옵션 2에 대한 좋은 사례가 있지만 널리 사용하는 것은 권장하지 않습니다.
Serguei Fedorov

1
때로는 추악한 물건이 필요합니다. 모범 사례가 무엇인지 이미 알고있을 때 선택하는 것이 좋습니다
Oscar Ortiz

아직도 닷넷을 배우는 사람으로서 두 번째 방법이 더 못 생기는 이유는 무엇입니까?
Goose

3
@Goose는 마법의 문자열이기 때문입니다. 컴파일 시간이 안전하지 않습니다. 변수 이름에 오타를 입력하면 런타임에 코드가 실패하지만 강력한 타이핑을 사용하는 경우 컴파일러가 친구가됩니다.
Darin Dimitrov

@DarinDimitrov 말이됩니다. 내가 태어난 세상과는 다릅니다. 아주 좋은 기능입니다.
Goose

104

간단히 다음 FormCollection과 같이 사용할 수 있습니다 .

[HttpPost] 
public ActionResult SubmitAction(FormCollection collection)
{
     // Get Post Params Here
 string var1 = collection["var1"];
}

Form 값으로 매핑 된 클래스를 사용할 수도 있으며 asp.net mvc 엔진이 자동으로 채 웁니다.

//Defined in another file
class MyForm
{
  public string var1 { get; set; }
}

[HttpPost]
public ActionResult SubmitAction(MyForm form)
{      
  string var1 = form1.Var1;
}

내가 클래스 솔루션을 자사의 쉽고 간단한 좋아
바시르 AL-MOMANI에게

36

대답은 매우 좋지만 MVC 및 .NET의 최신 릴리스에는 "오래된 학교"FormCollection 및 Request 키 대신 사용하고 싶은 또 다른 방법이 있습니다.


AJAX 또는 FORM POST를 수행하는 양식 태그 내에 포함 된 HTML 스 니펫을 고려하십시오.

<input type="hidden"   name="TrackingID" 
<input type="text"     name="FirstName"  id="firstnametext" />
<input type="checkbox" name="IsLegal"  value="Do you accept terms and conditions?" />

컨트롤러는 실제로 양식 데이터를 구문 분석하고 정의 된 유형의 매개 변수로 전달하려고합니다. 까다로운 체크 박스를 포함 시켰습니다. 선택하면 "on"텍스트를 반환하고 선택하지 않으면 null을 반환합니다. 그러나 요구 사항은 이러한 정의 된 변수가 반드시 존재해야한다는 것입니다 (nullable (nullable이더라도 기억 string)하지 않는 한) 그렇지 않으면 AJAX 또는 POST 백이 실패합니다.

[HttpPost]
public ActionResult PostBack(int TrackingID, string FirstName, string IsLegal){
    MyData.SaveRequest(TrackingID,FirstName, IsLegal == null ? false : true);
}

면도기 도우미를 사용하지 않고 모델을 다시 게시 할 수도 있습니다. 나는 이것이 몇 번 필요하다는 것을 알게되었습니다.

public Class HomeModel
{
  public int HouseNumber { get; set; }
  public string StreetAddress { get; set; }
}

HTML 마크 업은 단순히 ...

<input type="text" name="variableName.HouseNumber" id="whateverid" >

컨트롤러 (Razor Engine)는 양식 변수 "variableName"(이름은 원하는대로 유지하지만 일관성을 유지)을 가로 채서이를 빌드하고 MyModel로 캐스트합니다.

[HttpPost]
public ActionResult PostBack(HomeModel variableName){
    postBack.HouseNumber; //The value user entered
    postBack.StreetAddress; //the default value of NULL.
}

컨트롤러가 모델 (이 경우 HomeModel)을 예상 할 때 모든 필드를 정의 할 필요가 없습니다. 파서가 기본값 (일반적으로 NULL)으로두기 때문입니다. 좋은 점은 마크 업에서 다양한 모델을 혼합하고 일치시킬 수 있으며 포스트 백 구문 분석이 가능한 한 많이 채워질 것입니다. 페이지에서 모델을 정의하거나 도우미를 사용할 필요가 없습니다.

팁 : 컨트롤러의 매개 변수 이름은 HTML 마크 업 "name ="에 정의 된 이름입니다. 모델 이름이 아니라!에서 예상되는 변수의 이름입니다.


사용 List<>은 마크 업에서 조금 더 복잡합니다.

<input type="text" name="variableNameHere[0].HouseNumber" id="id"           value="0">
<input type="text" name="variableNameHere[1].HouseNumber" id="whateverid-x" value="1">
<input type="text" name="variableNameHere[2].HouseNumber"                   value="2">
<input type="text" name="variableNameHere[3].HouseNumber" id="whateverid22" value="3">

List <>의 인덱스는 항상 0부터 시작해야하며 순차적이어야합니다. 0,1,2,3.

[HttpPost]
public ActionResult PostBack(List<HomeModel> variableNameHere){
     int counter = MyHomes.Count()
     foreach(var home in MyHomes)
     { ... }
}

사용 IEnumerable<>비 제로를위한 것은 기반 및 비 순차적 인덱스 다시 게시 할 수 있습니다. 바인더를 돕기 위해 숨겨진 추가 입력을 추가해야합니다.

<input type="hidden" name="variableNameHere.Index" value="278">
<input type="text" name="variableNameHere[278].HouseNumber" id="id"      value="3">

<input type="hidden" name="variableNameHere.Index" value="99976">
<input type="text" name="variableNameHere[99976].HouseNumber" id="id3"   value="4">

<input type="hidden" name="variableNameHere.Index" value="777">
<input type="text" name="variableNameHere[777].HouseNumber" id="id23"    value="5">

그리고 코드는 IEnumerable을 사용하고 ToList()

[HttpPost]
public ActionResult PostBack(IEnumerable<MyModel> variableNameHere){
     int counter = variableNameHere.ToList().Count()
     foreach(var home in variableNameHere)
     { ... }
}

페이지 당 단일 모델 또는 ViewModel (다른 모델을 연결하여 복잡한 'View'모델을 생성하는 모델)을 사용하는 것이 좋습니다. 제안 된대로 믹싱 및 매칭은 나쁜 습관으로 간주 될 수 있지만 작동하고 읽을 수있는 한 나쁜 것은 아닙니다. 그러나 Razor 엔진의 힘과 유연성을 보여줍니다.

따라서 임의의 항목을 드롭하거나 Razor 도우미의 다른 값을 재정의해야하거나 비정상적인 데이터 조합을 사용하는 단일 양식에 대해 고유 한 도우미를 만들고 싶지 않은 경우 이러한 메서드를 사용하여 추가 데이터.


색인 옵션을 사용하는 것은 모호합니다. 하나님의 녹색 지구에서 누가 그것을 사용했거나 심지어 존재했음을 알았 을까요?! 하지만이 게시물을 찾아서 다행입니다. 그것은 많은 양의 네트워크 트래픽을 절약 할 것입니다.
Michael Silver

1
이것은 나를 위해 일했지만 <input type = "hidden"id = "myId">를 @ Html.Hidden ( "myId")로 변경 한 후에 만
radkan

@Piotr-MyModel 및 MyHomes의 참조 불일치를 수정하십시오. 현재 상태를 혼란스럽게합니다.
Spencer Sullivan

15

모델 바인딩없이 Http 요청에서 직접 양식 데이터를 가져 오려면 FormCollection다음을 사용할 수 있습니다.

[HttpPost] 
public ActionResult SubmitAction() {

    // This will return an string array of all keys in the form.
    // NOTE: you specify the keys in form by the name attributes e.g:
    // <input name="this is the key" value="some value" type="test" />
    var keys = Request.Form.AllKeys;

    // This will return the value for the keys.
    var value1 = Request.Form.Get(keys[0]);
    var value2 = Request.Form.Get(keys[1]);
}

2
이것은 잘못된 형식 (말장난이 아님) 일 수 있지만 때로는 형식 값만 원하고 함수 시그니처를 깨끗하게 변경할 수 없습니다. 이것은 내 특정 상황에 적합한 유일한 솔루션입니다.
Ryan

이러한 정적 참조로이 메서드를 단위 테스트하는 방법은 무엇입니까? FormCollection은 테스트와 관련하여 훨씬 더 바람직합니다.
Kees de Wit

@KeesdeWit 이전 의견을 읽으면 이것이 최선의 방법은 아니지만 때로는 해결 방법으로 사용합니다. 단위 테스트를 위해 아마도를 모의 Request하고 메서드에 주입 할 수 있습니다 .
A-Sharabiani
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.