문제

MVC를 실험 중인데 내 질문은 다음과 같습니다. WebForms가 포함된 마스터 페이지에서 Page_Load 논리가 있었던 위치는 MVC에서는 어디에 있어야 합니까? 비즈니스 사례는 다음과 같습니다.

  • 호스트 헤더가 다르면 사이트의 하나의 마스터 페이지, 즉 모든 페이지에 다른 페이지 제목이 표시되어야 합니다.예를 들어, 호스트 헤더가 hello.mydomain.com인 경우 페이지 제목은 모든 페이지/뷰에 대해 "Hello World"여야 하고, 모든 페이지/뷰에 대해 안녕.mydomain.com은 "Goodbye World"여야 합니다.
  • 호스트 헤더가 목록에 있는 것과 다른 경우 애플리케이션의 위치에 관계없이 /Error/NoHostHeader로 리디렉션되어야 합니다.

이전에는 이것을 MasterPage Load() 이벤트에 넣었는데 MVC에서는 모든 컨트롤러에서 이 작업을 수행할 수 있었습니다(모든 컨트롤러에서 이 기능을 호출해야 하는 것은 적절하지 않다고 생각합니다). Global.asax(너무...글로벌?).

편집하다: 실제로 데이터를 처리하기 위해 컨트롤러와 결합된 Global.asax 메서드를 사용하여 이것이 성공적으로 작동하도록 했습니다.이 시점에서 유일한 문제는 모든 호스트 헤더 정보가 데이터베이스에 있다는 것입니다.일반적으로 세션 변수에 "테넌트" 정보를 저장하고 해당 정보가 없을 때만 DB 호출을 수행합니다.더 좋은 방법이 있나요?

도움이 되었습니까?

해결책

이유 때문에 MVC에는 1:1 대응이 없습니다. MVC 방식으로 생각하는 방법을 요약해 보겠습니다.

모델:"이 사이트의 페이지는 항상 특정 컨텍스트에서 요청됩니다. 이를 테넌트(또는 사용자, 주제 또는 하위 도메인이 나타내는 모든 것)라고 부르겠습니다.도메인 모델에는 현재 요청의 테넌트를 나타내는 속성이 있습니다."

보다:"모델에 설정된 테넌트에 따라 페이지 제목을 렌더링합니다."

제어 장치:"호스트 헤더에 따라 모델에 테넌트를 설정합니다".

우리가 피하고 싶은 것은 혼입 컨트롤러, 뷰, 비즈니스 로직."컨트롤러"라고 불리지 않는 한 장소 또는 여러 장소에 컨트롤러 로직을 갖는 것은 분리된 상태로 유지되는 한 문제가 되지 않습니다.

이제 좋은 점은 다음과 같습니다. Web Forms에서도 이 "MVC 스타일"을 수행할 수 있습니다., 솔루션은 여전히 ​​ASP.NET MVC에서 작동합니다!

페이지 수명 주기가 아닌 요청 수명 주기가 여전히 있으므로 모든 요청에 ​​대한 컨트롤러 논리의 이 부분을 포함하는 사용자 지정 HttpModule을 구현할 수 있습니다.BeginRequest 이벤트를 처리하고, 호스트 헤더를 확인하고, HttpContext.Current.Items["tenant"]와 같은 항목에 테넌트를 저장합니다.(물론 이 사전 항목에 대해 정적이고 형식화된 래퍼가 있을 수 있습니다.)

그런 다음 모든 모델 개체(또는 모델 기본 클래스 또는 솔루션에 적합한 모든 것)가 HttpContext에 액세스하여 다음과 같이 이 정보에 대한 액세스를 제공할 수 있습니다.

public string Tenant
{
    get { return HttpContext.Current.Items["tenant"]; }
}

장점:

  • 원인(호스트 헤더)과 결과(렌더링 페이지 제목)가 분리되어 유지 관리 및 테스트 가능성이 향상됩니다.
  • 따라서 현재 테넌트에 따라 데이터베이스에서 콘텐츠를 로드하는 등 이 상태를 기반으로 도메인 모델에 추가 동작을 쉽게 추가할 수 있습니다.
  • 포함하는 CSS 파일, 로고 이미지 등과 같이 테넌트에 따라 보기의 더 많은 부분을 쉽게 만들 수 있습니다.
  • 나중에 컨트롤러 로직을 변경하여 하위 도메인뿐만 아니라 쿠키, 리퍼러, 검색어, 사용자 에이전트의 언어 또는 생각할 수 있는 모든 것을 수정하지 않고 모델에서 테넌트를 설정할 수 있습니다. 모델에 따라 코드가 달라집니다.

수정사항을 업데이트하세요.:특히 세션 쿠키가 각 하위 도메인뿐만 아니라 모든 도메인에 적용될 수 있는 경우 세션에서 상태를 유지한다는 아이디어가 마음에 들지 않습니다.이 경우 사용자가 이전에 다른 하위 도메인을 방문한 경우 일관성 없는 콘텐츠를 제공할 수 있습니다.호스트 헤더를 테넌트에 매핑하는 데이터베이스의 정보는 자주 변경되지 않으므로 이를 캐시할 수 있으며 모든 요청에 ​​대해 데이터베이스를 조회할 필요가 없습니다.

다른 팁

MVC 마스터 페이지보기에 올바른 뷰 데이터를 제공 한 기본 컨트롤러를 만들 수있는 다음 해당 실제 컨트롤러에서 각 컨트롤러를 도출 할 수 있습니다. 로직을 ActionExecuting 메소드에 넣으면 예외를 생성하거나 필요한 경우 오류 페이지로 리디렉션 할 수 있어야합니다.

당신은 너무 "웹 폼"이라고 생각하고 MVC가 충분하지 않습니다. 마스터 페이지는 시야의 래퍼 일 뿐이며 레이아웃 HTML 만 포함되어야합니다. 당신은 주인에게 물건을 보낼 수 있지만, 그것은 편도 도로이며, 당신은 불가지론적인 견해를 위해 노력해야합니다. 결론 : WebForms가 여기에서 사용하지 않을 때의 이벤트를 잊어 버리십시오.

당신이 호스트 헤더를 다루고 있기 때문에 나는 당신이 그것을 Global.asax에 넣을 수 있다고 생각합니다 ... 지금은 혼란 스러워요 : P

도난당한 코드 http://forums.asp.net/t/1226272.aspx

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            string host = string.Empty;

            if (this.Request.ServerVariables["HTTP_HOST"] == this.Request.Url.DnsSafeHost)
            {
                host = this.Request.Url.DnsSafeHost;
            }
            else
            {
                Regex regex = new Regex("http://[^/]*.host/([^/]*)(/.*)");
                Match match = regex.Match(this.Request.Url.AbsoluteUri);

                if (match.Success)
                {
                    host = match.Groups[1].Value;
                    Context.RewritePath(match.Groups[2].Value);
                }
            }

            // Match the host with the portal in the database
            ...
        } 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top