Asp.Net Core 에서 ModelConvention 를 사용 하여 전역 필터 격 리
이것 은 내 가 프로젝트 를 Asp.Net Core 로 옮 기 는 과정 에서 문제 에 부 딪 혔 기 때문이다.웹 프로그램 에 MVC 와 WebAPI 가 동시에 포함 되 어 있 습 니 다.이 제 는 WebAPI 부분 에 인터페이스 검증 필터
IActionFilter
를 따로 추가 해 야 합 니 다.일반적인 방법 은 필 터 를 작성 한 후에 필요 한 컨트롤 러 에 이 탭 을 걸 어 주 는 것 입 니 다.고급 방법 은 전체 필 터 를 등록 하 는 것 입 니 다.이렇게 하면 매번 수 동 으로 추가 되 는 것 을 피 할 수 있 고 코드 도 잘 관리 할 수 있 습 니 다.전역 필 터 를 등록 하 는 방법 은 다음 과 같 습 니 다.
services.AddMvc(options =>
{
options.Filters.Add(typeof(AccessControlFilter));
});
그러나 이렇게 하면 문 제 를 가 져 올 수 있다.바로 MVC 부분 컨트롤 러 도 영향 을 받는다 는 것 이다.필터 에서 어떤 것 이 MVC 컨트롤 러 이 고 어떤 것 이 API 컨트롤 러 인지 판단 할 수 있 지만 괜 히 MVC 에 이런 쓸모없는 Filter 를 추가 하 는 것 은 어차피 참 을 수 없 기 때문에 이 기능 을 실현 할 수 있 는 더 좋 은 방법 이 있 는 지 찾 아 보 자.그 러 자 모델 컨 벤 션 이 깜짝 등장 했다.
애플 리 케 이 션 모델 부터 알 아 보 겠 습 니 다.
공식 문서 에서 응용 프로그램 모델(ApplicationModel)을 어떻게 설명 하 는 지 보 세 요.
ASP.NET Core MVC defines an application model representing the components of an MVC app. You can read and manipulate this model to modify how MVC elements behave. By default, MVC follows certain conventions to determine which classes are considered to be controllers, which methods on those classes are actions, and how parameters and routing behave. You can customize this behavior to suit your app's needs by creating your own conventions and applying them globally or as attributes.
간단하게 말하자면 응용 프로그램 모델 은 MVC 응용 프로그램의 각종 대상 과 행 위 를 묘사 했다.이런 내용 은 응용 프로그램,컨트롤 러,Action,Parameter,Router,Page,Property,Filter 등 을 포함 하고 Asp.Net Core 프레임 워 크 자체 에 규칙(Convention)을 내장 하여 이 모델 들 을 처리한다.또한 인 터 페 이 스 를 제공 하여 우리 에 게 더욱 필요 한 응용 을 실현 하기 위해 모델 을 확장 하기 로 약속 했다.
응용 프로그램 모델 과 관련 된 클래스 는 네 임 스페이스
Microsoft.AspNetCore.Mvc.ApplicationModels
에 정의 되 어 있 으 며,이 모델 들 은IApplicationModelProvider
을 통 해 구축 되 었 으 며,Asp.Net Core 프레임 워 크 가 제공 하 는 기본 Provider 는DefaultApplicationModelProvider
입 니 다.우 리 는 이 모델 들 을 편집 하여 표현 행 위 를 바 꿀 수 있다.이것 은 모델 컨 벤 션 을 통 해 이 루어 져 야 한다.ModelConvention
ModelConvention 는 조작 모델 의 입 구 를 정의 하거나 계약 이 라 고 할 수 있 습 니 다.이 를 통 해 우 리 는 모델 을 수정 할 수 있 습 니 다.자주 사용 하 는 Convention 는 다음 과 같 습 니 다.
Apply
을 제공 합 니 다.방법 적 인 파 라 메 터 는 각자 의 응용 프로그램 모델 입 니 다.IControllerModelConvention
을 예 로 들 어 그 정 의 를 보 세 요.
namespace Microsoft.AspNetCore.Mvc.ApplicationModels
{
//
// :
// Allows customization of the Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel.
//
// :
// To use this interface, create an System.Attribute class which implements the
// interface and place it on a controller class. Microsoft.AspNetCore.Mvc.ApplicationModels.IControllerModelConvention
// customizations run after Microsoft.AspNetCore.Mvc.ApplicationModels.IApplicationModelConvention
// customizations and before Microsoft.AspNetCore.Mvc.ApplicationModels.IActionModelConvention
// customizations.
public interface IControllerModelConvention
{
//
// :
// Called to apply the convention to the Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel.
//
// :
// controller:
// The Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel.
void Apply(ControllerModel controller);
}
}
인터페이스 요약 을 통 해 알 수 있 듯 이 이 인 터 페 이 스 는 사용자 정의ControllerModel
대상 을 허용 합 니 다.사용자 정의 내용 은Apply
방법 으로 이 루어 집 니 다.이 방법 은 현재ControllerModel
대상 의 인 스 턴 스 를 제공 합 니 다.우 리 는 그 에 게 서 얻 을 수 있 는 것 이 너무 많 습 니 다.그것 이 무엇 을 포함 하 는 지 보 세 요.이러한 것들 이 있 으 면 우 리 는 매우 유연 한 조작 을 할 수 있다.예 를 들 어 설정
ControllerName
필드 를 통 해 컨트롤 러 의 이름 을 강제로 변경 하여 프로그램 에 죽은 컨트롤 러 이름 을 무효 화 할 수도 있 고Filters
필드 를 통 해 필터 집합 을 동적 으로 업데이트 할 수도 있 으 며RouteValues
을 통 해 경로 규칙 을 변경 할 수도 있다.여기까지 말 하면 많은 사람들 이 이 물건 과 사용자 정의 필터 가 별로 차이 가 나 지 않 는 다 고 생각 할 것 이다.처음에 나 도 그렇게 생각 했다.그러나 실제 코드 디 버 깅 을 통 해 나 는 그것 의 생명 주기 가 필터 보다 훨씬 빠 르 거나 비교 할 수 없다 는 것 을 알 게 되 었 다.이 녀석 은 시작 할 때 한 번 만 실행 해 야 하 며 매번 요청 에 따라 실행 하지 않 아 도 된다.즉,컨트롤 러 를 활성화 하 는 것 보다 더 일찍 실행 되 었 고 그 때 는 필터 가 전혀 없 었 으 며 호출 은
app.UseEndpoints()
에서 발생 했다.최초의 수요 로 돌아가다.위의 소 개 를 바탕 으로 다음 과 같은 약속 을 사용자 정의 할 수 있 습 니 다.
public class ApiControllerAuthorizeConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
if (controller.Filters.Any(x => x is ApiControllerAttribute) && !controller.Filters.Any(x => x is AccessControlFilter))
{
controller.Filters.Add(new AccessControlAttribute());
}
}
}
위의 주요 사고방식 은 컨트롤 러 자체 의 필터 집합 에 API 컨트롤 러 가 포함 되 어 있 는 지ApiControllerAttribute
를 판단 함으로써 API 컨트롤 러 가 표시 되 어 있 지 않 고AccessControlAttribute
표시 되 어 있 지 않 으 면 새로운 실례 를 추가 하 는 것 이다.그러면 어떻게 이 약속 을 응용 프로그램 에 등록 합 니까?Microsoft.AspNetCore.Mvc.MvcOptions 에서
Conventions
속성 을 제공 합 니 다.
//
// :
// Gets a list of Microsoft.AspNetCore.Mvc.ApplicationModels.IApplicationModelConvention
// instances that will be applied to the Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModel
// when discovering actions.
public IList<IApplicationModelConvention> Conventions { get; }
조작 을 통 해 사용자 정의 약속 을 주입 할 수 있 습 니 다:
services.AddMvc(options =>
{
options.Conventions.Add(new ApiControllerAuthorizeConvention());
})
세심 한 사람 은 Conventions 가 하나의IApplicationModelConvention
유형의 집합 이라는 것 을 알 게 될 것 이다.우리 가 정의 한 Convention 는 하나의IControllerModelConvention
이 므 로 정상적으로 잘못 보고 해 야 한다.왜냐하면 Asp.Net Core 의 DI 프레임 워 크 는 우리 에 게 일련의 확장 방법 을 제공 하여 Convention 의 추 가 를 간소화 하고 더 이상 전환 하지 않 아 도 되 기 때문이다.코드 디 버 깅 을 통 해 시작 할 때 시스템 의 모든 컨트롤 러 를 옮 겨 다 니 며 Apply 작업 을 수행 한 것 을 알 수 있 습 니 다.그러면
IApplicationModelConvention
을 통 해 도 이 기능 을 실현 할 수 있 습 니 다.컨트롤 러 집합 이 포함 되 어 있 기 때 문 입 니 다.
public class ApiControllerAuthorizeConvention : IApplicationModelConvention
{
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
if (controller.Filters.Any(x => x is ApiControllerAttribute) && !controller.Filters.Any(x => x is AccessControlFilter))
{
controller.Filters.Add(new AccessControlFilter());
}
}
}
}
좀 더 개선 하 다실제 개발 에서 나의 Access Control Filter 는 구조 함 수 를 통 해 업무 인 터 페 이 스 를 주입 해 야 합 니 다.이와 유사 합 니 다.
public class AccessControlFilter : IActionFilter
{
private IUserService _userService;
public AccessControlFilter(IUserService service)
{
_userService = service;
}
public void OnActionExecuting(ActionExecutingContext context)
{
//
//var user=_userService.GetById(996);
//.......
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
어떻게 하면 Convention 에서 DI 자동 주입 을 우아 하 게 사용 할 수 있 을까요?Asp.Net Core MVC 프레임 워 크 가 제공 하 는ServiceFilter
이 문 제 를 해결 할 수 있 습 니 다.ServiceFilter
자체 가 필터 입 니 다.그 차이 점 은 구조 함 수 를 통 해 Type 형식의 인 자 를 받 을 수 있 습 니 다.우 리 는 여기 서 진정 으로 사용 할 필 터 를 전송 할 수 있 습 니 다.그래서 위의 필터 등록 과정 은 다음 과 같 습 니 다.
controller.Filters.Add(new ServiceFilterAttribute(typeof(AccessControlFilter)));
물론 DI 에서 이 filter 인 스 턴 스 를 가 져 오 려 면 DI 용기 에 주입 해 야 합 니 다.
services.AddScoped<AccessControlFilter>();
이로써 큰 성 과 를 거 두 며 즐 거 운 CRUD 를 이 어 갔다.갑자기 제 가상편언급 한 확장 DI 속성 주입 기능 도 이 를 통 해 이 루어 질 수 있 을 것 같 습 니 다.eeeeee...시간 이 나 면 해 보 세 요.
총결산
전체적으로 볼 때 저 는 곡선 으로 나 라 를 구 하 는 방식 으로 전체 필터 격 리 를 실 현 했 습 니 다.목표 컨트롤 러 를 옮 겨 다 니 고 Filter 를 수 동 으로 추가 하 는 방식 은 한 줄 의 코드 로 실현 할 수 있 는 방식 이 우아 하지 않 지만 대체적으로 만 족 스 럽 고 현재 생각 할 수 있 는 가장 좋 은 방법 입 니 다.내 가 짐 작 컨 대
options.Filters.Add(xxx)
도 틀 에서 어느 때 한 명 씩 xxx 를 각자 주인 에 게 던 져 주 고 멋대로 추측 하 며 잘못 말 하면 책임 을 지지 않 는 다~hhh:seeno_evil::see_no_evil::see_no_evil:이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebAPI 원본 POST 요청 BODY 의 JSON 내용 가 져 오기controller 의 action 에 다음 코드 를 쓰 십시오: 그러나 이 코드 에서 얻 은 콘 텐 츠 는 비어 있 었 고 한참 동안 알 지 못 했 으 며 나중에 한 외국 포럼 에서 원인 을 찾 았 다. 그 이 유...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.