c# - MVC Helper, Method with same parameters gives different results -


i creating helper class mvc , found problem when parameter "routevalues" passed in different ways. methods created define attributes default. code below snippet using explain problem is.

i have method "mybeginform()" not accept parameter "routevalues", "routevalues" parameter is passed directly "beginform" method null. other method "mybeginform(object routevalues)" accepts parameter "routevalues" , have passed "null" value through parameter. problem html generated different each other.

//custom class custom attributes public class myhtmlhelper<tmodel> {     private readonly htmlhelper<tmodel> htmlhelper;      internal myhtmlhelper(htmlhelper<tmodel> htmlhelper)     {         this.htmlhelper = htmlhelper;     }      //here routevalues parameter of begin form passed directly method null     public mvcform mybeginform()     {         var myattributes = new dictionary<string, object>(){             {"test", "value"},             {"test2", "value2"},         };          return htmlhelper.beginform("index", "home", null, formmethod.post, myattributes);     }      //here have passed null value through 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 used static call in html public static class myhtmlhelperkex {     public static myhtmlhelper<tmodel> myhtmlhelper<tmodel>(this htmlhelper<tmodel> htmlhelper)     {         return new myhtmlhelper<tmodel>(htmlhelper);     } } 

the following snippet used on html side

<h1>without parameter</h1> @using (html.myhtmlhelper().mybeginform()) { }  <h1>with parmeter</h1> @using (html.myhtmlhelper().mybeginform(null)) { } 

and following html generated. can see attributes generated differently.

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

can explain why happening , how can solve please.

you mixing types of routevalues , htmlattributes parameters.

there 2 overloads of beginform expect 5 parameters:

  • one routevalues , htmlattributes both declared anonymous objects. see msdn

  • another routevalues of type routevaluedictionary , htmlattributes of type idictionary<string, object>. see msdn

however in helper, have mixed types. htmlattributes declared dictionary , routevalues object.

the mybeginform overload without arguments works because pass null routevalues arguments, compiler uses type of other arguments decide overload of beginform should used. htmlattributes dictionary use second overload describe above. try changing method of yours force null routevalues of type object, force wrong overload picker , same unexpected html:

return htmlhelper.beginform("index", "home", (object)null, formmethod.post, myattributes); 

in same way, second mybeginform overload doesn´t work expected because have declared routevalues of type object, compiler first overload mentioned above (where both routevalues , htmlattributes treated anonymous objects).

now know what´s going, need make sure picking right overload fix issue. fix mybeginform overload allows routevalues specified, , update overload without parameters call 1 (avoiding duplicated code).

the easiest way fix define htmlattributes inside method anonymous object:

public mvcform mybeginform(object routevalues) {     var myattributes = new{         test = "value",         test2 = "value2",     };     return htmlhelper.beginform("index", "home", routevalues, formmethod.post, myattributes); } 

the other option consists in declaring routevalues parameter routevaluesdictionary, can keep defining htmlattributes dictionary.

public mvcform mybeginform(routevaluedictionary routevalues) {     var myattributes = new dictionary<string, object>(){         {"test", "value"},         {"test2", "value2"},     };     return htmlhelper.beginform("index", "home", routevalues, formmethod.post, myattributes); } 

in both cases, calling helper passing null parameter render expected html (although prefer using routevalues anonymous object):

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

you update first overload of helper this:

public mvcform mybeginform() {                 return mybeginform(null); } 

now both overloads of mybeginform should work expected.

hope helps!


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -