2014-04-13 3 views
2

"routeValues"매개 변수가 다른 방식으로 전달되면 MVC 용 도우미 클래스를 만들고 문제가 있음을 발견했습니다. 이 메서드는 기본적으로 일부 특성을 정의하기 위해 만들어집니다. 아래 코드는 내 문제가 무엇인지 설명하기 위해 사용하는 스 니펫입니다.MVC 도우미, 동일한 매개 변수가있는 메서드가 다른 결과를 나타냅니다.

"routeValues"매개 변수를 허용하지 않는 "MyBeginForm()"메서드가 있고 "routeValues"매개 변수는 "BeginForm"메서드에 null로 직접 전달됩니다. 다른 메소드 "MyBeginForm (object routeValues)"는 "routeValues"에 대한 매개 변수를 받아들이고 매개 변수를 통해 "null"값을 전달했습니다. 문제는 생성 된 html이 서로 다르다는 것입니다.

//Custom Class for custom attributes 
public class MyHtmlHelper<TModel> 
{ 
    private readonly HtmlHelper<TModel> htmlHelper; 

    internal MyHtmlHelper(HtmlHelper<TModel> htmlHelper) 
    { 
     this.htmlHelper = htmlHelper; 
    } 

    //Here the routeValues parameter of Begin Form is passed directly to the method as null 
    public MvcForm MyBeginForm() 
    { 
     var myAttributes = new Dictionary<string, object>(){ 
      {"test", "value"}, 
      {"test2", "value2"}, 
     }; 

     return htmlHelper.BeginForm("Index", "Home", null, FormMethod.Post, myAttributes); 
    } 

    //Here I have passed the null value through the parameter 
    public MvcForm MyBeginForm(object routeValues) 
    { 
     var myAttributes = new Dictionary<string, object>(){ 
      {"test", "value"}, 
      {"test2", "value2"}, 
     }; 

     return htmlHelper.BeginForm("Index", "Home", routeValues, FormMethod.Post, myAttributes); 
    } 
} 

//This class is used for static call in html 
public static class MyHtmlHelperkEx 
{ 
    public static MyHtmlHelper<TModel> MyHtmlHelper<TModel>(this HtmlHelper<TModel> htmlHelper) 
    { 
     return new MyHtmlHelper<TModel>(htmlHelper); 
    } 
} 

다음 코드는 HTML 측

<h1>Without Parameter</h1> 
@using (Html.MyHtmlHelper().MyBeginForm()) { } 

<h1>With parmeter</h1> 
@using (Html.MyHtmlHelper().MyBeginForm(null)) { } 

에 사용되며, 다음 생성되는 HTML이다. 속성이 다르게 생성 된 것을 볼 수 있습니다.

<h1>Without Parameter</h1> 
<form action="/" method="post" test="value" test2="value2"> 
    System.Web.Mvc.Html.MvcForm 
</form> 

<h1>With parmeter</h1> 
<form comparer="System.Collections.Generic.GenericEqualityComparer`1[System.String]" count="2" keys="System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]" values="System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object]" action="/" method="post"></form> 

누군가 이런 일이 일어나는 이유와 내가 어떻게 해결할 수 있는지 설명해 주실 수 있습니까?

답변

0

routeTypehtmlAttributes 매개 변수 유형을 혼합합니다.

5 개 매개 변수를 기대 BeginForm의 2 오버로드가 있습니다

routeValues와 htmlAttributes 모두 익명 객체로 선언
  • 하나. routeValues ​​유형 RouteValueDictionary이며 htmlAttributes 유형 IDictionary<string, Object>의입니다 msdn

  • 또 다른를 참조하십시오. 도우미에서 그러나 msdn

를 참조하십시오, 당신은 유형을 혼합했다. htmlAttributes는 사전으로 선언되고 routeValues는 객체로 선언됩니다.

routeValues ​​인수로 null을 전달하기 때문에 인수가없는 MyBeginForm 오버로드가 작동하므로 컴파일러에서 다른 인수 유형을 사용하여 BeginForm의 오버로드를 결정해야합니다. htmlAttributes는 사전이므로 위에서 설명한 두 번째 오버로드를 사용합니다. 빠르게 선택기로 잘못된 과부하를 강제 형 객체의 같은 널 routeValues을 강제로 당신의 방법을 변경 시도 할 수와 같은 예기치 않은 HTML을 얻을 것입니다 : 같은 방법으로

return htmlHelper.BeginForm("Index", "Home", (object)null, FormMethod.Post, myAttributes); 

을, 두 번째 MyBeginForm 오버로드는 object 유형의 routeValues를 선언했기 때문에 예상대로 작동하지 않으므로 컴파일러는 위에서 언급 한 첫 번째 오버로드 (routeValues ​​및 htmlAttributes가 익명 객체로 처리되는 곳)를 항상 가져옵니다.

이제 어떻게 될지 알았으므로 문제를 해결하기 위해 올바른 오버로드를 선택해야합니다. MyBeginForm 과부하를 수정하여 routeValues를 지정하고 매개 변수없이 오버로드를 업데이트하여이 코드를 호출하면됩니다 (중복 된 코드는 피함).

는 익명의 개체로 방법 내부 htmlAttributes을 정의하는 것입니다 해결하는 가장 쉬운 방법 : 당신이 htmlAttributes을 정의 유지할 수 있도록

public MvcForm MyBeginForm(object routeValues) 
{ 
    var myAttributes = new{ 
     test = "value", 
     test2 = "value2", 
    }; 
    return htmlHelper.BeginForm("Index", "Home", routeValues, FormMethod.Post, myAttributes); 
} 

다른 옵션은 RouteValuesDictionary로 routeValues ​​매개 변수 선언에있다 사전으로.

public MvcForm MyBeginForm(RouteValueDictionary routeValues) 
{ 
    var myAttributes = new Dictionary<string, object>(){ 
     {"test", "value"}, 
     {"test2", "value2"}, 
    }; 
    return htmlHelper.BeginForm("Index", "Home", routeValues, FormMethod.Post, myAttributes); 
} 
두 경우 모두

, (나는 익명의 개체로 routeValues를 사용하여 선호하지만) 예상되는 HTML을 렌더링 매개 변수로 null을 전달하는 도우미 전화 :

<form action="/" method="post" test="value" test2="value2"></form> 

당신은 다음의 첫 번째 오버로드를 업데이트 할 수 있습니다를 당신의 도우미는 다음과 같습니다 :

public MvcForm MyBeginForm() 
{    
    return MyBeginForm(null); 
} 

MyBeginForm의 과부하가 예상대로 작동해야합니다.

희망이 있습니다.

+0

고마워요. 나는 그것이 다른 오버로딩 방법을 선택하고 있다는 것을 깨닫지 못했습니다. 다시 한번 감사드립니다. –

관련 문제