ASP.NET Core 에서 표현 식 트 리 를 사용 하여 URL 을 만 드 는 방법 에 대한 자세 한 설명
표현 식 트 리 는 실행 할 수 없 는 코드 입 니 다.트 리 모양 의 데이터 구 조 를 표시 하 는 데 사 용 됩 니 다.트 리 의 모든 노드 는 특정한 표현 식 형식 으로 표시 되 며 약 25 가지 표현 식 형식 이 있 습 니 다.모두 Expression 류 에서 파생 됩 니 다.표현 식 트 리 를 만 드 는 데 는 두 가지 장점 이 있 습 니 다.
1.표현 식 트 리 의 코드 를 편집 하고 수정 하여 표현 식 트 리 의 코드 를 동적 코드 로 바 꾸 고 서로 다른 데이터 베이스 에 따라 트 리 의 코드 논 리 를 수정 하여 데이터 베이스 조회 문 구 를 동적 으로 전환 하 는 목적 을 달성 합 니 다.표현 식 트 리 로 서로 다른 데이터 라 이브 러 리 에 대한 조회 문 구 를 동적 으로 구축 할 수 있 습 니 다.
2.알 수 없 는 대상 에 반사 적 으로 접근 하 는 속성 을 완성 하고 동적 구조 표현 식 트 리 를 통 해 의뢰 를 생 성 합 니 다.
ASP.NET Core 에서 action 을 만 드 는 url 은 이렇게 씁 니 다.
var url=_urlHelper.Action("Index", "Home");
이러한 쓰기 에 존재 하 는 문 제 는 두 문자열 형식의 인 자 를 전달 하 는 것 입 니 다.action 과 contrller 에 대한 이름 바 꾸 기 동작 을 피 할 수 없습니다.예 를 들 어 index 를 default 로 바 꾸 는 것 입 니 다.IDE 를 통 해 action 을 바 꾸 는 과정 에서
_urlHelper.Action("Index", "Home");
재 구성
UrlHelper.Action("Default", "Home");
그래서 우리 의 목 표 는 정적 검 사 를 가 진 API 를 설계 하여 IDE 가 이 오 류 를 알려 주 고 심지어 이름 을 바 꿀 때 관련 코드 를 직접 이름 을 바 꿀 수 있 도록 하 는 것 입 니 다.목표.
유사 한 두 그룹의 API 를 설계 합 니 다:
var url = _urlHelper.Action((HomeController c) => c.Index());
// /home/index
var link = _urlHelper.Link((ProductController c) => c.Details(10));
// http://locahost/product/details/10
설계 API위의 요구 에 따라 두 그룹의 API 를 정의 합 니 다.
public static string Action<TController>(this IUrlHelper helper,
Expression<Action<TController>> action)
where TController : Controller
{
//
}
public static string Link<TController>(this IUrlHelper helper,
Expression<Action<TController>> action,
string protocal = null, string host = null)
where TController : Controller
{
//
}
API 구현우 리 는 결국 ASP.NET Core 가 제공 하 는 API 에 의존 해 야 한다.
var link = helper.Action(action: actionName, controller:
controllerName, values: routes);
그래서 문 제 는(HomeController c) => c.Index()
이러한 표현 식 에 따라 actionName,Controller Name,routeValues 를 어떻게 해석 하 느 냐 가 되 었 습 니 다.1.분석 컨트롤 러 Name
Controller Name 을 분석 하 는 것 은 간단 하고 거 칠 습 니 다.표현 식 트 리 에서 HomeController 라 는 종 류 를 얻 었 기 때문에 홈 문자열 을 직접 가 져 오 면 됩 니 다.
private static string GetControllerName(Type controllerType)
{
var controllerName = controllerType.Name.EndsWith("Controller")
? controllerType.Name.Substring(0,
controllerType.Name.Length - "Controller".Length)
: controllerType.Name;
return controllerName;
}
2.ActionName 분석표현 식
(HomeController c) => c.Index()
MethodCallExpression 형식 이기 때문에 Action 의 이름 은 방법 명 입 니 다.
private static MethodCallExpression
GetMethodCallExpression<TController>(
Expression<Action<TController>> actionSelector)
{
var call = actionSelector.Body as MethodCallExpression;
if (call == null)
{
throw new ArgumentException("You must call a method on " +
typeof(TController).Name, "actionSelector");
}
return call;
}
var methodCallExpression = GetMethodCallExpression(action);
var actionName = methodCallExpression.Method.Name;
3.RouteValues 분석위의 두 단 계 는 Controller Name 과 Action Name 을 분 석 했 습 니 다.즉,위의 분석 을 통 해 아래 호출 을 완료 할 수 있 습 니 다.
var action = helper.Action(action: "index", controller: "home", values: null);
//
var url = _urlHelper.Action((HomeController c) => c.Index());
// /home/index
하지만 다음 액 션 을 고려 해 보 자.
[HttpGet,Route("product/{id}")]
public IActionResult Details(int id)
{
//...
}
이 Action 은 int 형식의 id 가 들 어 오 기 를 기대 합 니 다.즉,이러한 방식 으로 url 을 생 성 하 겠 다 는 것 입 니 다.
var action = helper.Action(action: "details", controller:
"product", values: new { id = 10 });
그래서 우리 의 API 가 정상적으로 작 동 하려 면 object 형식 을 만들어 야 합 니 다new { id = 10 }
이 object 형식의 속성 은 표현 식 트 리 에서 인 자 를 호출 할 수 있 습 니 다.
var action = _urlHelper.Action((ProductController c) => c.Details(10));
이 익명 의 대상 을 만 들 려 면 표현 식 의 모든 인 자 를 옮 겨 다 니 며 속성 명,예 를 들 어 id 를 분석 해 야 합 니 다.값마지막 으로 분 석 된 매개 변수 사전 을 dynamic 형식의 대상 으로 생 성 합 니 다.표현 식 트 리 를 어떻게 해석 하 는 지 보 세 요expression-trees
public class RouteValueExtractor
{
public static object GetRouteValues(MethodCallExpression call)
{
var routes = new Dictionary<string, object>();
var parameters = call.Method.GetParameters();
var pairs = call.Arguments.Select((a, i) => new
{
Argument = a,
ParamName = parameters[i].Name
});
foreach (var item in pairs)
{
string name = item.ParamName;
object value = GetValue(item.Argument);
if (value != null)
{
var valueType = value.GetType();
if (valueType.IsValueType)
{
routes.Add(name, value);
}
else
{
throw new NotSupportedException("Unsupported parameter type {0}");
}
}
}
return DictionaryToObject(routes);
}
private static object GetValue(Expression expression)
{
if (expression.NodeType == ExpressionType.Constant)
{
return ((ConstantExpression) expression).Value;
}
throw new NotSupportedException("Unsupported parameter expression");
}
private static dynamic DictionaryToObject(IDictionary<string, object> dictionary)
{
var expandoObj = new ExpandoObject();
var expandoObjCollection = (ICollection<KeyValuePair<string, object>>) expandoObj;
foreach (var keyValuePair in dictionary)
{
expandoObjCollection.Add(keyValuePair);
}
dynamic eoDynamic = expandoObj;
return eoDynamic;
}
}
완전한 API 구현:
public static string Action<TController>(this IUrlHelper helper,
Expression<Action<TController>> action)
where TController : Controller
{
var controllerName = GetControllerName(typeof(TController));
var methodCallExpression = GetMethodCallExpression(action);
var actionName = methodCallExpression.Method.Name;
var routes = RouteValueExtractor.GetRouteValues(methodCallExpression);
var link = helper.Action(action: actionName, controller:
controllerName, values: routes);
return link;
}
총결산이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Tailwind를 ASP.NET Core 프로젝트에 통합우리는 을 사용합니다. 에서 코드를 찾을 수 있습니다. 면도기 페이지 구조를 추가합니다. "node_modules"가 설치되었습니다. "tailwind.config.js"파일이 생성되었습니다. 모든 .razor 및 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.