Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.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 HtmlHelper扩展方法_C#_Asp.net_Asp.net Mvc_Asp.net Mvc 5 - Fatal编程技术网

C# 如何重载MVC HtmlHelper扩展方法

C# 如何重载MVC HtmlHelper扩展方法,c#,asp.net,asp.net-mvc,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 5,我正在尝试注册一个自定义MVC HtmlHelper扩展 我已经为扩展方法创建了相应的静态类和静态方法,但是如何在视图中注册/导入/使用该名称空间,以便它显示为某个给定方法的扩展方法,例如@Html.SomeMethod 在Asp.Net WebForms中,我可以简单地添加: <%@ Import Namespace="MyExtensionNamespace.MyExtensionClassName" %> 但是VS告诉我,我的调用下仍然有一个错误,表示无法推断类型参数: 以

我正在尝试注册一个自定义MVC HtmlHelper扩展

我已经为扩展方法创建了相应的静态类和静态方法,但是如何在视图中注册/导入/使用该名称空间,以便它显示为某个给定方法的扩展方法,例如
@Html.SomeMethod

在Asp.Net WebForms中,我可以简单地添加:

<%@ Import Namespace="MyExtensionNamespace.MyExtensionClassName" %>
但是VS告诉我,我的调用下仍然有一个错误,表示无法推断类型参数:

以下是我的分机代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Reflection;
using System.Linq.Expressions;
namespace EFWCF.Extensions
{
    public static class LabelExtensions
    {
        public static MvcHtmlString LabelFor<PropertyInfo, TValue>(this HtmlHelper<PropertyInfo> html, Expression<Func<PropertyInfo, TValue>> expression)
        {
            var type = expression.Type;
            MvcHtmlString result = new MvcHtmlString(type.FullName);
            return result;
        }
    }
}

但是我希望能够为其他类型调用现有的@Html方法。

您可以通过以下两种方式引用名称空间:

直接在视图中:

@using YourProject.HtmlHelpers;
或者,您可以在
视图/web.config
文件中添加对该命名空间的引用,这样就不需要使用
添加到视图的顶部:

<system.web.webPages.razor>
  <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
    <namespaces>
      <add namespace="System.Web.Mvc" />
      <add namespace="System.Web.Mvc.Ajax" />
      <add namespace="System.Web.Mvc.Html" />
      <add namespace="System.Web.Routing" />
      <!-- Reference here -->
      <add namespace="YourProject.HtmlHelpers" />
    </namespaces>
  </pages>
</system.web.webPages.razor>

无法从用法中推断类型参数,这意味着在将标识符指定为方法类型参数期间发生了泛型类型不匹配。这里,您的自定义扩展方法将
System.Reflection.PropertyInfo
定义为
TModel
的替代:

public static MvcHtmlString LabelFor<PropertyInfo, TValue>(this HtmlHelper<PropertyInfo> html, Expression<Func<PropertyInfo, TValue>> expression)
{
    var type = expression.Type;
    MvcHtmlString result = new MvcHtmlString(type.FullName);
    return result;
}
根据我的观察,Razor似乎使用
HtmlHelper.LabelFor
而不是使用其自定义扩展方法重载,因此在视图页面中,您试图将
PropertyInfo
指定为标准
LabelFor
上的
expression
参数,该参数需要lambda表达式,从而导致CS0411错误

要解决此问题,请将自定义扩展方法名称更改为另一个有效名称(避免命名冲突),或通过对
System.Reflection.PropertyInfo
进行类型检查,为标准
LabelFor
创建重载,如下例所示:

// note that you still require to insert PropertyInfo as a lambda expression here
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
    var modelType = typeof(TModel);
    var propertyInfo = typeof(System.Reflection.PropertyInfo);
    if (modelType.IsAssignableFrom(propertyInfo))
    {
        var type = expression.Type;
        var tag = new TagHelper("label");
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        tag.MergeAttributes(attributes);
        tag.SetInnerText(type.FullName); // set inner text between label tag
        return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
    }
    else
    {
        // return another value, e.g. return MvcHtmlString.Empty
    }
}
然后,在
视图
目录中的web.config中引用您的助手名称空间,这样您就不需要在视图页面中使用
@using
指令:

<system.web.webPages.razor>
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.UI.WebControls" />
        ...
        <add namespace="EFWCF.Extensions.LabelExtensions" /> <-- add this line
      </namespaces>
    </pages>
</system.web.webPages.razor>


在Razor中,您可以使用MyExtensionNamespace.MyExtensionClassName使用
。请注意,您的扩展方法需要是静态的
MvcHtmlString
方法。是的,让我试试。不行,我会更新我的问题。使用EFWCF.Extensions.LabelExtensions在图片中的
@红色下划线上会出现什么错误文本?谢谢@TetsuyaYamamoto First error First fixed,正在使用
Namespace.ClassName
,而导入时它应该是
Namespace
+我同意你的回答。但我再次更新了这个问题。无法推断其投诉类型,应显式定义。感谢提供信息。奇怪的是我的web.config甚至没有这个部分。我目前正在使用第一种方法,但我似乎无法过载。@AlexanderHiggins它是web.config。在视图中,Folder不知道这一点。好消息。至于潜在的问题,我现在明白我无法完成我所尝试的。很棒的更新。我知道您可以在文件夹级别添加
.config
文件,但不知道
MVC
这样注册了导入。是的,您可以在视图文件夹中使用webconfig…:)。非常感谢@Nkosi指出这一点。快乐分享。:)
public static MvcHtmlString LabelFor<PropertyInfo, TValue>(this HtmlHelper<PropertyInfo> html, Expression<Func<PropertyInfo, TValue>> expression)
{
    var type = expression.Type;
    MvcHtmlString result = new MvcHtmlString(type.FullName);
    return result;
}
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
   ...
}
// note that you still require to insert PropertyInfo as a lambda expression here
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
    var modelType = typeof(TModel);
    var propertyInfo = typeof(System.Reflection.PropertyInfo);
    if (modelType.IsAssignableFrom(propertyInfo))
    {
        var type = expression.Type;
        var tag = new TagHelper("label");
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        tag.MergeAttributes(attributes);
        tag.SetInnerText(type.FullName); // set inner text between label tag
        return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
    }
    else
    {
        // return another value, e.g. return MvcHtmlString.Empty
    }
}
public static MvcHtmlString PropertyLabelFor<TModel>(this HtmlHelper<TModel> html, PropertyInfo propertyInfo, object htmlAttributes)
{
    var type = propertyInfo.GetType();
    var tag = new TagHelper("label");
    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    tag.MergeAttributes(attributes);
    tag.SetInnerText(type.FullName); // set inner text between label tag
    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}
<system.web.webPages.razor>
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.UI.WebControls" />
        ...
        <add namespace="EFWCF.Extensions.LabelExtensions" /> <-- add this line
      </namespaces>
    </pages>
</system.web.webPages.razor>