Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC助手,参数相同的方法会给出不同的结果_C#_Html_Asp.net Mvc 4_Generics_Form Helpers - Fatal编程技术网

C# MVC助手,参数相同的方法会给出不同的结果

C# MVC助手,参数相同的方法会给出不同的结果,c#,html,asp.net-mvc-4,generics,form-helpers,C#,Html,Asp.net Mvc 4,Generics,Form Helpers,我正在为MVC创建一个helper类,当参数“routeValues”以不同的方式传递时发现了一个问题。默认情况下,创建这些方法是为了定义某些属性。下面的代码是我用来解释问题所在的代码片段 我有一个方法“MyBeginForm()”不接受“routeValues”的参数,“routeValues”参数直接作为null传递给“BeginForm”方法。另一个方法“MyBeginForm(object routeValues)”接受“routeValues”的参数,我通过该参数传递了“null”值。

我正在为MVC创建一个helper类,当参数“routeValues”以不同的方式传递时发现了一个问题。默认情况下,创建这些方法是为了定义某些属性。下面的代码是我用来解释问题所在的代码片段

我有一个方法“MyBeginForm()”不接受“routeValues”的参数,“routeValues”参数直接作为null传递给“BeginForm”方法。另一个方法“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);
    }
}
//自定义属性的自定义类
公共类MyHtmlHelper
{
私有只读HtmlHelper HtmlHelper;
内部MyHtmlHelper(HtmlHelper HtmlHelper)
{
this.htmlHelper=htmlHelper;
}
//这里,Begin表单的routeValues参数作为null直接传递给方法
公共MvcForm MyBeginForm()
{
var myAttributes=newdictionary(){
{“测试”,“值”},
{“test2”,“value2”},
};
返回htmlHelper.BeginForm(“Index”,“Home”,null,FormMethod.Post,myAttributes);
}
//这里我通过参数传递了null值
公共MvcForm MyBeginForm(对象路由值)
{
var myAttributes=newdictionary(){
{“测试”,“值”},
{“test2”,“value2”},
};
返回htmlHelper.BeginForm(“索引”、“主页”、RouteValue、FormMethod.Post、myAttributes);
}
}
//此类用于html中的静态调用
公共静态类MyHtmlHelperkEx
{
公共静态MyHtmlHelper MyHtmlHelper(此HtmlHelper HtmlHelper)
{
返回新的MyHtmlHelper(htmlHelper);
}
}
以下代码段用于html端

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

<h1>With parmeter</h1>
@using (Html.MyHtmlHelper().MyBeginForm(null)) { }
不带参数
@使用(Html.MyHtmlHelper().MyBeginForm()){}
带参数
@使用(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>
不带参数
System.Web.Mvc.Html.MvcForm
带参数

有人能解释一下为什么会发生这种情况,以及我如何解决它。

您正在混合路由值htmlAttributes参数的类型

有两个
BeginForm
重载,需要5个参数:

  • RouteValue和htmlAttributes都声明为 匿名对象。看

  • routeValues的另一种类型为
    RouteValueDictionary
    和 htmlAttributes的类型为
    IDictionary
    。看见

但是,在助手中,您混合了这些类型。htmlAttributes声明为字典,RouteValue声明为对象

无参数的
MyBeginForm
重载有效,因为您将null作为routeValues参数传递,因此编译器使用其他参数的类型来决定应该使用哪个
BeginForm
重载。由于htmlAttributes是一个字典,它将使用我上面描述的第二个重载。 您可以快速尝试更改您的方法,以强制类型为object的null routeValues,这将强制错误的重载为picker,并且您将得到相同的意外html:

return htmlHelper.BeginForm("Index", "Home", (object)null, FormMethod.Post, myAttributes);
同样,您的第二个
MyBeginForm
重载也不能像您预期的那样工作,因为您已经声明了类型为object的RouteValue,因此编译器将始终获得我上面提到的第一个重载(其中RouteValue和htmlAttributes都被视为匿名对象)

现在,您知道发生了什么,您只需要确保选择了正确的重载来解决问题。我将修复允许指定RouteValue的
MyBeginForm
重载,然后在没有参数的情况下更新重载以调用此重载(避免重复代码)

修复此问题的最简单方法是将方法中的htmlAttributes定义为匿名对象:

public MvcForm MyBeginForm(object routeValues)
{
    var myAttributes = new{
        test = "value",
        test2 = "value2",
    };
    return htmlHelper.BeginForm("Index", "Home", routeValues, FormMethod.Post, myAttributes);
}
<form action="/" method="post" test="value" test2="value2"></form>
另一个选项包括将routeValues参数声明为RouteValuesDictionary,因此您可以继续将htmlAttributes定义为字典

public MvcForm MyBeginForm(RouteValueDictionary routeValues)
{
    var myAttributes = new Dictionary<string, object>(){
        {"test", "value"},
        {"test2", "value2"},
    };
    return htmlHelper.BeginForm("Index", "Home", routeValues, FormMethod.Post, myAttributes);
}
现在,
MyBeginForm
的两个重载都应该像您预期的那样工作


希望有帮助

非常感谢。我没有意识到它选择了不同的重载方法。再次感谢。
public MvcForm MyBeginForm()
{            
    return MyBeginForm(null);
}