WebApi 에 대한 몇 가지 기본 규칙을 다시 작성하는 방법
WebApi 에 대한 몇 가지 기본 규칙을 다시 작성하는 방법은 무엇입니까? 요즘 왜 SOA 프레임워크를 바꿔야 합니까? 회사가 이런 기술을 처음 접한 것은 이번이 처음이다. 기분이 좋으니 스스로 던져서 간단한 SOA 프레임워크를 실현하고 싶습니다.
저는 MVC 로 개발했는데, 마치 WebApi 와 Mvc 가 같은 것 같아요. 나는 이렇게 미리 설정해서 WebApi 를 하기 시작했고, 그 다음에는 학대를 당해서 북쪽을 찾을 수 없었다.
남용되는 이유는 Mvc 와 WebApi 가 여전히 세부적인 차이가 있기 때문입니다. 예를 들면 다음과 같습니다.
Mvc 에서 컨트롤러의 모든 공용 * * * 메서드는 일반적으로 POST 메서드에 응답할 수 있지만 WebApi 에서는 사용할 수 없습니다. Mvc 에서 Action 메서드의 매개 변수는 Url 이나 Form 에서 가져올 수 있지만 WebApi 에서는 가져올 수 없습니다. 구체적인 규칙은 매개 변수에 [FromBody] 를 추가하지 않으면 양식에서 이 매개 변수를 가져오지 않는 것 같습니다. 이것은 내가 아는 두 기술의 가장 큰 차이다. 다른 것들은 발견되거나 주목을 받지 못했다. 내가 사용하지 않기 때문에 이런 차이가 있을 수도 있다. 결국, 나는 WebApi 와 접촉한 지 얼마 되지 않았다. 만약 내가 약간의 잘못을 저질렀다면, 나를 바로잡아 주세요.
나는 이 두 가지 차이에 대한 자료를 많이 조사했지만 해결 방법을 찾지 못했다. 첫 번째는 괜찮습니다. 기능을 추가하면 되고, 두 번째는 [FromBody] 를 추가해도 안 되는 것 같아요. 한계인 것 같아요. 그리고, 나를 기분 나쁘게 하는 일이 그렇게 많으니, 내가 좀 개조해 볼게. (윌리엄 셰익스피어, 템페스트, 희망명언)
전환의 목표는 다음과 같습니다.
제한 없음 제어기는 제어기로 끝나야 합니다. 사실 그럴 필요는 없지만 정말 견디기 힘듭니다. 모든 메서드는 요청된 모든 메서드에 응답할 수 있습니다. 메서드 이름이 같은 메서드가 있는 경우 먼저 Url 에서 매개변수를 구분하고 바디의 매개변수를 구분해야 합니다. 주체로부터 획득할 때 주체의 데이터가 먼저 양식 매개변수라고 가정합니다. 만약 주체의 데이터를 얻기 위한 목표를 JSON 이나 XML 데이터로 정하지 않는다면, 마이크로소프트는 왜 이렇게 WebApi 를 설계합니까? 아마도 그 이유가 있을 것이다.
목표가 잘 정해져 있으니, 하면 정말 큰일이다. 처음에는 회사의 SOA 프레임 워크의 구현을 참고하고 싶었지만 OWIN 기술로 호스팅되었기 때문에 회사의 프레임 워크를 보면 소용이 없는 것 같습니다. 어쨌든 한참 동안 보면 어디서부터 손을 대야 할지 알 수 없지만 오히려 점점 혼란스러워지고 있다. 결국, 그것은 정확히 같은 기술이 아니에요.
좋아, 쓸데없는 말이 그렇게 많으니 본론으로 돌아가자. 우선, 링크를 만들어 봅시다. 이 문장 없이는 blogs.com/beginor/archive/2012/03/22/241/;
실제로 인터넷에는 많은 OWIN 호스트가 있습니다. 나는 주로 코드를 붙이는 것이다, 그렇지 않으면 다음 몇 절은 쓸 수 없다.
[assembly: owlstartup (type of (startup)]//IIS 를 호스팅할 때 이 말을 사용합니다. 기능은 다음과 같습니다. Net 은 시작 클래스를 찾아 전체 서비스 namespacexinchen.soa.server {public classstartup {public void configuration (IAPP 생성기 app builder) {hub 를 시작합니다 구성. Routes.maphttproute (name: "default API", route template: "{controller}/{action}"); 구성. Services.add (typeof (valueproviderfactory), new MyValueProviderFactory());); //사용자 지정 매개 변수 조회 세 번째 목표인 config.services.replace (type of (ihttpcontroller 선택기), new controller 선택기 (config));; //사용자 정의 컨트롤러 조회 첫 번째 목표인 config.services.replace (typeof (ihttpartitionselector), new httppartitionselector());) //사용자 정의 동작 조회 두 번째 목표 달성 appBuilder. Use webapi (구성) : }}} 중요하지 않은 일부 코드는 생략했습니다. 서비스. Add 와 Replace 는 글자 그대로 그들의 뜻을 이해할 수 있지만, 나는 이렇게 쓸 필요가 있는지 시험해 본 적이 없다.
제어기에 대한 제한 공용 클래스 제어기 선택기: ihttpcontroller 선택기 {httpconfiguration _ config 사전 & ltstring, httpcontrollerdescriptor & gt _ desriptor 일반 사례); 공용 컨트롤러 선택기 (http configuration config) {_ config = config; } voidinitcontrollers () {if (_ descriptors. 개수< = 0) {lock (_ descriptor) {if (_ descriptor. 개수<= 0) {var assemblies = AppDomain. CurrentDomain.GetAssemblies () 를 참조하십시오. 여기서 (x =>! X. 글로벌 어셈블리 캐시 및 & amp! X.is dynamic); Var controllerTypes = 신규 목록 <. 유형> (); Foreach (어셈블리의 변수 ass){ controller types. AddRange(ass). GetExportedTypes () 를 사용합니다. 여기서 (x = & gttypeof (API 컨트롤러). IsAssignableFrom(x)));); } var descriptors = 새 사전 & ltstring, HttpControllerDescriptor & gt (); Foreach(controllerTypes 의 var controller type) {var descriptor = new httpcontrollerdescriptor (_ config, controller 이름, controller type); _ 설명자. 추가 (설명자). 컨트롤러 이름, 설명자); }}}}} 공용 사전 & ltstring, httpcontrollerdescriptor & gtgetcontrollermapping () {initcontrollers (); Return _ desriptors} 공용 시스템. Web.http.controllers.httpcontrollerdescriptor select controller (system). Net.Http.HttpRequestMessage 요청) {initcontrollers (); Var routeData = request 입니다. Getroutedata (); Var controllerName = Convert 입니다. ToString(routeData). Values.get ("controller")); If (문자열. Isnullwhitespace {새 매개 변수 예외 발생 (문자열. Format ("라우팅 정보에서 컨트롤러를 찾을 수 없음"); } return _ desriptors. Get (컨트롤러 이름); }} 이것은 사실 비교적 간단하다. 테스트에서 WebApi 는 GetControllerMapping 메서드를 호출하지 않고 SelectController 메서드를 직접 호출한 것 같습니다. 마지막 메서드에는 두 개의 Get 메서드 호출이 있습니다. Get 은 사전에서 TryGetValue 를 시도하는 함수만 캡슐화합니다. InitControllers 메서드는 모든 현재 어셈블리에서 ApiController 를 상속하는 클래스를 찾아 찾은 후 캐시합니다. 이 코드는 전체적으로 비교적 간단하다.
작업에 대한 제한 사항 public class http actions elector: ihttpactionselector {public ilookup
깨뜨리다 기본값: var http method = controller context. Request. 방법 Var filterdMethods = 메소드. 여기서 (x => {varverb = X. getcustomattribute < AcceptVerbsAttribute & gt (); If (verb = = null) {throw new httpresponse exception (controller context). Request.createerrorresponse (시스템). 컨트롤러' +ControllerContext' 에서' +actionName+' 이라는 여러 가지 방법을 찾았습니다. 컨트롤러 설명자입니다. ControllerName+ ",이러한 메서드에 AcceptVerbsAttribute 속성 추가 고려"); } 동사를 반환합니다. Httpmethods.contains (httpmethod); }); If (filterdMethods). Count()& gt;; 1) {throw new httpresponse exception (controller context). Request.createerrorresponse (시스템). 컨트롤러' +ControllerContext' 에서' +actionName+' 이라는 여러 가지 방법을 찾았습니다. 컨트롤러 설명자입니다. ControllerName+ "및 이러한 메서드의 AcceptVerbsAttribute 에는 모두" +httpMethod "가 포함되어 있습니다. ToString()+ ",이것은 반복"); } else if (filterdMethods). Count()& lt;; = 0) {throw new httpresponseexception (controller context). Request.createerrorresponse (시스템). 컨트롤러' +ControllerContext' 에서' +actionName+' 이라는 여러 가지 방법을 찾았습니다. 컨트롤러 설명자입니다. ControllerName+ "이지만 둘 다" +httpMethod "에 응답하도록 구성되지 않았습니다. Tostring ()+"요청"); } method = filterdMethods. Firstordefault ();
깨뜨리다 } 새 reflectedhttpactiondescriptor (controllercontext) 를 반환합니다. ControllerDescriptor, 메소드); }} get action 매핑 방법은 간단합니다. 모든 동작 방법은 컨트롤러 유형에서 찾아 반환합니다.
SelectAction 메서드는 비교적 복잡하며 실제로는 두 번째 대상의 논리입니다. 코드에는 사실 많은 어려움이 있다.
행동의 매개변수를 제한하기 어렵다. 나는 성공하는데 오랜 시간이 걸렸는데, 지금도 구덩이가 있다.
공용 클래스 actionvaluebinder: defaultactionvaluebinder {protected override httpparametertbinding getparameter binding (httpparameter {parameterbindingattribute parameter attribute = parameter. Parameterbinderattributeif (parameterbinderattribute = = null) {parameter bindingrulescollection parameter binding rules 구성