我正在为ASP.NET MVC编写自己的HtmlHelper扩展:
public static string CreateDialogLink (this HtmlHelper htmlHelper, string linkText,
string contentPath)
{
// fix up content path if the user supplied a path beginning with '~'
contentPath = Url.Content(contentPath); // doesn't work (see below for why)
// create the link and return it
// .....
};
我遇到问题时,请尝试从我的HtmlHelper定义中的 中访问UrlHelper
。问题是您通常访问HtmlHelper
(通过Html.MethodName(...)
)的方式是通过View上的属性。我自己的扩展课程显然无法使用此功能。
这是ViewMasterPage
(从Beta开始)的实际MVC源代码 - 定义Html
和Url
。
public class ViewMasterPage : MasterPage
{
public ViewMasterPage();
public AjaxHelper Ajax { get; }
public HtmlHelper Html { get; }
public object Model { get; }
public TempDataDictionary TempData { get; }
public UrlHelper Url { get; }
public ViewContext ViewContext { get; }
public ViewDataDictionary ViewData { get; }
public HtmlTextWriter Writer { get; }
}
我希望能够在HtmlHelper中访问这些属性。
我想出的最好的是(在CreateDialogLink
方法的开头插入)
HtmlHelper Html = new HtmlHelper(htmlHelper.ViewContext, htmlHelper.ViewDataContainer);
UrlHelper Url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
我是否错过了访问现有HtmlHelper
和UrlHelper
实例的其他方法 - 或者我是否真的需要创建一个新实例?我确信没有太多的开销,但如果可以的话,我宁愿使用已有的那些。
答案 0 :(得分:12)
在提出这个问题之前,我已经查看了一些MVC源代码,但显然我错过了这个,这就是他们为Image帮助器做的事情。
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(imageRelativeUrl)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
}
UrlHelper url = new UrlHelper(helper.ViewContext);
string imageUrl = url.Content(imageRelativeUrl);
return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
}
看起来像实例化一个新的UrlHelper
毕竟是正确的方法。这对我来说足够好了。
更新:来自ASP.NET MVC v1.0 Source Code的RTM代码略有不同,如评论中所述。
文件:MVC \ src \ MvcFutures \ Mvc \ ImageExtensions.cs
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(imageRelativeUrl)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
}
UrlHelper url = new UrlHelper(helper.ViewContext.RequestContext);
string imageUrl = url.Content(imageRelativeUrl);
return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
}
答案 1 :(得分:4)
我遇到了类似的问题,并决定在视图中调用UrlHelper并将输出传递给我的HtmlHelper扩展名会更容易。在你的情况下,它看起来像:
<%= Html.CreateDialogLink( "text", Url.Content( "~/...path.to.content" ) ) %>
如果要访问传递给您的类的现有HtmlHelper上的扩展方法,您只需要在源代码文件中导入System.Web.Mvc.Html,然后您就可以访问它们了(这就是扩展类已定义)。如果你想要一个UrlHelper,你需要实例化它,因为你得到的HtmlHelper没有它来自的ViewPage的句柄。
答案 2 :(得分:1)
如果您需要在实用程序类中创建UrlHelper,则可以执行以下操作:
string url =“〜/ content / images / foo.jpg”;
var urlHelper = new UrlHelper(new RequestContext(
new HttpContextWrapper(HttpContext.Current),
new RouteData()), RouteTable.Routes);
string absoluteUrl = urlHelper.Content(url);
这允许您使用路由或“〜扩展”远离MVC上下文。
答案 3 :(得分:0)
好吧,您始终可以将页面实例传递给扩展方法。我认为这比在方法中创建新实例要好得多。
您还可以在从MasterPage / ViewMasterPage派生的类上定义此方法,然后从该派生页面。这样,您就可以访问实例的所有属性,而不必传递它们。