Razor 선언적 뷰에서 MVC HtmlHelper 확장 사용


121

MVC 3 RTM 프로젝트에 대한 App_Code 폴더에 Razor 선언적 도우미를 만들려고했습니다.

내가 만난 문제는 ActionLink와 같은 MVC HtmlHelper 확장을 사용할 수 없다는 것입니다. 이 컴파일 된 헬퍼에서 파생 때문이다 System.Web.WebPages.HelperPage, 그리고 그것이 노출하지만 Html속성을 해당 유형의 System.Web.WebPages.HtmlHelper것이 아니라 System.Web.Mvc.HtmlHelper.

내가받은 오류의 예는 다음과 같습니다.

'System.Web.Mvc.HtmlHelper'에 'ActionLink'에 대한 정의가 포함되어 있지 않으며 'System.Web.Mvc.HtmlHelper'유형의 첫 번째 인수를 허용하는 확장 메서드 'ActionLink'를 찾을 수 없습니다 (using 지시문이 누락 되었습니까? 또는 어셈블리 참조?)

내 유일한 해결책은 나만의 HelperPage를 만들고 Html 속성을 재정의하는 것입니다.

using System.Web.WebPages;

public class HelperPage : System.Web.WebPages.HelperPage 
{
    // Workaround - exposes the MVC HtmlHelper instead of the normal helper
    public static new HtmlHelper Html
    {
        get { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; }
    }
}

그런 다음 모든 도우미의 맨 위에 다음을 작성해야합니다.

@inherits FunnelWeb.Web.App_Code.HelperPage
@using System.Web.Mvc
@using System.Web.Mvc.Html

@helper DoSomething()
{
    @Html.ActionLink("Index", "Home")
}

MVC 3에서 이렇게 힘들다는 뜻인가요, 아니면 제가 뭔가 잘못하고 있나요?


4
Url 도우미도 필요하면 HelperPage에 다음 코드 줄을 추가합니다. public static UrlHelper Url {get {return new UrlHelper (Html.ViewContext.RequestContext); }}
— 마르코 Staffoli

답변:


42

이 질문에 대한 Marcind의 답변 을 살펴보십시오 . 경험하는 것은 App_Code폴더 에 선언적 뷰를 넣는 제한 사항입니다 .

도우미를 App_Code에 넣는 것은 작동하지만 특정 MVC 시나리오에 영향을주는 특정 제한 사항이 있습니다 (예 : 표준 MVC Html 도우미에 대한 액세스 권한 없음).


1
다른 독자에게 참고 :이 답변은 절대적으로 정확하지만 잠재적 인 해결 방법은 아래 Andrew Nurse의 추가 기여도를 확인하십시오.
— Jordan Gray

38

페이지 도우미에 액세스 할 수 있도록 WebPages 도우미에 대한 확장 메서드를 만들었습니다.

public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html)
{
 return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html;
}

4
사용법 :@Html.GetPageHelper().ActionLink("actioname")
— deerchao 2011

이 나를 위해 작동하지만 추가했다 @using System.Web.Mvc과 @using System.Web.Mvc.Html의 App_Code 내부 cshtml 헬퍼 파일로
— 토미노

1
별도의 HtmlHelper 클래스가있는 이유는 무엇입니까? App_Code에 있든 Views에 있든 동일해야합니다. 반 구현 된 에픽 디자인은 실패합니다.
— Triynko 2015

여기에서 weblogs.asp.net/scottgu/…에서 언급했습니다 . "글로벌"Razor 도우미를 만드는 방법을 잘 설명하고 있습니다. 당신은 단지 필요하면 그럼, HtmlHelper목적을 인코딩하는 클래스를, 나는 정적 클래스를 사용하는 것이이 작업을 수행하는 더 빠른 방법을 발견 Microsoft.Security.Application.Encoder: 같이Encoder.HtmlAttributeEncode(value)
— 매트 보르

11

Omar가 여기에 정답을 얻었지만 뭔가 추가하고 싶었습니다 (Omar의 응답을 답으로 표시해도됩니다).

우리는 v1에서 이것을 알고 있었고 제품에서 큰 수정을 할 수 없었지만 David Ebbo (ASP.Net 팀의 설계자)는 기본적으로 첫 번째 탐색 인 Visual Studio 코드 생성기 샘플을 게시했습니다. 이 작업이 제대로 작동하도록하기 위해 우리가보고있는 종류의 아이디어 : http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable-libraries .aspx

그것을 시도하고 당신이 생각하는 것을보십시오! 블로그에 댓글이 있으면 David에게 알려주세요.


2
다음 버전의 Razor에서이 문제를 해결할 계획이 있습니까? 나는 이것이 VS 11 베타에서 여전히 문제라는 것을 알았습니다.
— 오마르

9

@Jakes 답변과 유사합니다.

public static class MvcIntrinsics {
    public static System.Web.Mvc.HtmlHelper Html {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; }
    }

    public static System.Web.Mvc.AjaxHelper Ajax {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Ajax; }
    }

    public static System.Web.Mvc.UrlHelper Url {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Url; }
    }

}

용법:

@MvcIntrinsics.Html.Raw("test")

출처 : Dino Esposito-프로그래밍 Microsoft ASP.NET MVC


1
이것이 필요하다는 것은 말도 안되며 App_Code의 뷰에 대한 기본 클래스의 일부가 아니라는 것입니다.
— Triynko 2015

7

대체 솔루션 :

면도기 도우미 파일 위에 다음을 추가하십시오.

@functions {
    public static System.Web.Mvc.HtmlHelper<object> HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
}

다음과 같이 호출하십시오.

@HHtml.ActionLink("actionname")

이것은 처음에는 나를 위해 일한 것처럼 보였지만 도우미를 다시 호출하면 '값이 예상 범위에 속하지 않습니다'라는 메시지가 나타납니다.
— d219

3

이에 대한 나의 접근 방식은 단순히 페이지를 도우미 메서드에 매개 변수로 전달하는 것입니다. 따라서 귀하의 예에서는 다음과 같습니다.

@helper DoSomething(WebViewPage page)
{
    @page.Html.ActionLink("Index", "Home")
}

그런 다음 필요한 Razor 뷰에서 다음과 같이 호출합니다.

@YourHelperFilename.DoSomething(this)

이렇게하면 즉시 당신에게 같은 페이지 속성에 액세스 할 수 있습니다 Html또는 Url당신이 일반적으로 가지고 (그리고를 통해 그 HtmlHelper확장).

추가 혜택 (필요한 경우)으로 페이지의 ViewData.


3

검색 자의 이익을 위해 클래스 라이브러리의 일부로 MVC 뷰를 만들 때 (구성 요소 재사용을 위해) 동일한 오류가 발생했습니다. 부분적으로 위에서 언급 한 해결책은 .cshtml 파일의 맨 위에 다음 using 문을 추가하는 것입니다.

@using System.Web.Mvc
@using System.Web.Mvc.Html

추가 작업이 필요하지 않습니다.


App_Code의 .cshtml에있는 도우미가 Intellisense에서 인식되지 않았습니다. App_code 아래의 .cshtml 상단에 @using System.Web.Mvc.Html을 추가하면 작동합니다.

나는이 작업을 수행 할 때, 나는 얻을 "Could not load type 'System.Web.WebPages.Instrumentation.InstrumentationService' from assembly 'System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."유혹 할 때 @using System.Web.Mvc. 어떤 아이디어?
— JoeBrockhaus

그것은 나에게 아무런 차이가 없습니다
— mems

0

MVC 3에는 몇 가지 지능적인 문제가 있다는 것을 알고 있습니다. web.config에 네임 스페이스가 설정되어 있으면 도우미가 계속 작동 할 것이라고 생각합니다.

MVC 3 RTM이 방금 실현되었습니다. 이것을 사용하고 있습니까 아니면 베타를 사용하고 있습니까?


0

ASP.NET MVC가 VS 2013에서이 문제를 해결 한 것 같습니다.이 게시물 http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this-를 참조하십시오. htmlhelper-ht


아니, 전혀. Intellisense는 확장 메서드를 선택하지 않고 VS2013 업데이트 5가 @using System.Web.Mvc.Html있습니다. App_Code의 cshtml 파일 맨 위에 있지만 @Html ....을 작성하면 EditorFor. 이것이 구현되었다고 주장하는 2 개의 주요 릴리스와 블로그 게시물 이후에 이것이 작동하지 않는다는 것은 놀랍습니다. 그렇지 않습니다. 실제로 확장 메서드는 System.Web.WebPages.HelperPage 클래스에 의해 노출되는 System.Web.WebPages.HtmlHelper 클래스가 아닌 System.Web.Mvc.HtmlHelper 클래스를 대상으로하기 때문에 작동하지 않습니다.
— Triynko 2015
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.