내 자신의 htmlhelper 내에서 htmlhelper 메소드에 어떻게 액세스합니까?
-
20-08-2019 - |
문제
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
// .....
};
내가 문제가있는 곳은 접근하려고합니다 UrlHelper
~에서 이내에 내 htmlhelper의 정의. 문제는 일반적으로 액세스하는 방식입니다 HtmlHelper
(을 통해 Html.MethodName(...)
)는보기의 속성을 통해입니다. 이것은 나 자신의 확장 클래스와 분명히 사용할 수 없습니다.
이것은 실제 MVC 소스 코드입니다 ViewMasterPage
(베타로) - 정의합니다 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
인스턴스 - 아니면 실제로 새로운 것을 만들어야합니까? 오버 헤드가 많지 않다고 확신하지만 가능하다면 기존의 것을 사용하는 것을 선호합니다.
해결책
이 질문을하기 전에 나는 MVC 소스 코드 중 일부를 살펴 보았지만 분명히 이것을 놓쳤다.
[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
결국 올바른 접근법입니다. 그것은 나에게 충분합니다.
업데이트: RTM 코드 ASP.NET MVC v1.0 소스 코드 주석에서 지적한대로 약간 다릅니다.
파일 : 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);
}
다른 팁
나는 비슷한 문제에 직면하여보기에서 UrlHelper를 호출하고 출력을 HTMLHELPER 확장으로 전달하는 것이 더 쉬울 것이라고 결정했습니다. 귀하의 경우에는 다음과 같습니다.
<%= Html.CreateDialogLink( "text", Url.Content( "~/...path.to.content" ) ) %>
클래스에 전달되는 기존 HTMLHELPER의 확장 메소드에 액세스하려면 소스 코드 파일에서 System.Web.mvc.html 만 가져와야하며 (확장 클래스에 액세스 할 수 있습니다. 정의됩니다). UrlHelper를 원한다면 HTMLHELPER가 오는 뷰 페이지에 대한 핸들이 없다는 것을 인스턴스화해야합니다.
유틸리티 클래스에서 UrlHelper를 만들어야하는 경우 다음을 수행 할 수 있습니다.
문자열 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 컨텍스트에서 라우팅 또는 '~ 확장'을 사용할 수 있습니다.
글쎄, 당신은 항상 페이지의 인스턴스를 확장 방법으로 전달할 수 있습니다. 나는 그것이 당신의 방법에서 새로운 인스턴스를 만드는 것보다 이것을하는 훨씬 더 좋은 방법이라고 생각합니다.
Mas 이런 식으로 인스턴스의 모든 속성에 액세스 할 수 있으며 전달할 필요가 없습니다.