질문에 대답하기 위해 실제로는 "설계대로"이며 WebAPI 및 MVC 클라이언트를 동일한 프로젝트 내에 두는 것이 좋습니다. 따라서 MVC 프로젝트 내에 RouteConfig.cs
과 WebApiConfig.cs
이 모두있는 것입니다. RouteConfig.cs
은 MVC 컨트롤러 용이고 WebApiConfig.cs
은 Api 컨트롤러 용입니다.
두 프로젝트를 같은 프로젝트에 포함시키는 것이 쉽습니다. 내가하는 일은 루트에 "API"라는 폴더를 추가하고 거기에 모든 WebAPI 컨트롤러를 배치하는 것입니다. 웹API 컨트롤러와 MVC 컨트롤러의 유일한 차이점은 이 System.Web.Http
(저는 믿습니다)의 일부분이라는 것입니다. MVC 컨트롤러가 일부인 Controller
을 상속하는 반면에, 저는 믿습니다. System.Web.MVC
.
다음은/GET/PUT을 POST가 MVC 프론트 엔드에서 WebAPI 을 TO 를 요청/삭제하는 적절한 방법입니다. 컨트롤러의 생성자에서 WebAPI URL을 지정하기 때문에 동일한 프로젝트에 있는지 여부는 중요하지 않습니다. WebAPI가 프런트 엔드 MVC 응용 프로그램과 다른 서버에있는 경우 WebAPI 버전 2 이상에서 사용할 수있는 CORS 지원을 활성화해야합니다.
프런트 엔드 MVC 클라이언트에서 WebAPI를 호출하는 적절한 방법입니다.
컨트롤러 페이지에서 DbContext, Entity Framework 등과 관련이있는 것은 제거하십시오. 기본적으로 컨트롤러는 DbContext를 호출하여 CRUD 작업을 수행하기를 원하므로이 작업을 원하지 않습니다. 우리는 이것을 대신 WebAPI를 호출하기를 원합니다. "컨트롤러"를 참조 할 때 WebAPI 컨트롤러가 아니라 MVC 컨트롤러를 참조합니다.
맨 먼저 MVC 컨트롤러에서 일부 멤버 변수를 선언하십시오. 같은 컨트롤러의 생성자를 만들고, 당신의 MVC 컨트롤러에서
HttpClient client = new HttpClient();
HttpResponseMessage response = new HttpResponseMessage();
Uri contactUri = null;
을 : 당신의 MVC 컨트롤러의 나머지 부분은 다음을 사용합니다
public ContactController()
{
// set base address of WebAPI depending on your current environment
// the URL below, if the API is in the same project, will be something
// like "http://server/YourProjectName" - replace server with either
// "localhost", etc.
client.BaseAddress = new Uri("http://server/YourAPI/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
뭔가 색인 작업의 코드를 바꿉니다 다음과 같이. 관련 부분은 client.GetAsync()
전화와 var contacts
지정 사항입니다. 이 문제의 맥락에서는 다른 모든 것이 필요하지 않습니다. client.GetAsync()
안의 값은 컨트롤러의 이름이어야하며 WebApiConfig에 설정 한 사용자 지정 라우팅이 앞에 추가되어야합니다.CS는 - 내 경우, 나는 API 호출과 정상 걸려 오는 전화를 구별 할 수 있도록 내 경로에 api
부분을 추가 :
public ActionResult Index()
{
response = client.GetAsync("api/contact").Result;
if (response.IsSuccessStatusCode)
{
var contacts = response.Content.ReadAsAsync<IEnumerable<Contact>>().Result;
return View(contacts);
}
else
{
// add something here to tell the user hey, something went wrong
return RedirectToAction("Index");
}
}
는 다음과 같은으로 활동 작성합니다 (HttpPost 조치)를 교체합니다. 합니다 (
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Contact contact)
{
// Create a new product
response = client.PostAsJsonAsync("api/contact", contact).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
else
{
// add something here to tell the user hey, something went wrong
return RedirectToAction("Index");
}
}
편집 작업을 바꾸기 :이 데이터베이스에 새 레코드를 삽입, 내 경우에는, 처리 걸리는 WebAPI의 POST 액션을 호출하는 것입니다 - 다시 말하지만, 유일한 중요한 부분은 client.PostAsJsonAsync()
부분은 비 HttpPost 조치)를 다음과 같이 사용하십시오. 이는 편집하기 위해 먼저 레코드를 검색해야했기 때문에 기본적으로 HttpPost 버전의 편집에는 POST (편집 POST)를 수행하는 추가 코드 줄이 포함 된 유사한 코드가 포함됩니다. 아래에서 우리는 특정 레코드 ID를 전달하여 WebAPI의 응답을 받고 있습니다. 따라서 Index (GET)와 마찬가지로 ID를 전달하는 것과 동일한 작업을 수행하므로 하나의 레코드 만 반환합니다.
public ActionResult Edit(int id = 0)
{
response = client.GetAsync(string.Format("api/contact/{0}", id)).Result;
Contact contact = response.Content.ReadAsAsync<Contact>().Result;
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
는 다음과 같은과 편집 작업을합니다 (HttpPost 동작을) 교체 : 그럼, 우리가보기에 수술을 할 수있는 실제 객체에 대한 응답을 캐스팅. 아래에서 우리는 client.GetAsync()
을 호출하고 기본 키를 매개 변수 (contact_id)로 전달하여 편집 할 레코드를 얻게됩니다. 그런 다음 해당 응답에서 RequestUri를 가져 와서 저장합니다. 그런 다음 client.PutAsJsonAsync()
을 호출하고 Uri.PathAndQuery (방금 저장 한 것)와 편집 할 개체를 전달합니다.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Contact contact)
{
response = client.GetAsync(string.Format("api/contact/{0}", contact.contact_id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.PutAsJsonAsync(contactUri.PathAndQuery, contact).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
else
{
// add something here to tell the user hey, something went wrong
return RedirectToAction("Index");
}
}
삭제 (비 HttpPost 작업) 동작을 다음과 같이 바꿉니다. 다시 한번 우리는 데이터베이스에서 레코드를 얻고 있습니다. client.GetAsync()
을 호출하고 내 앱이 아는 실제 객체로 캐스팅합니다.
public ActionResult Delete(int id = 0)
{
response = client.GetAsync(string.Format("api/contact/{0}", id)).Result;
Contact contact = response.Content.ReadAsAsync<Contact>().Result;
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
마지막으로 삭제 동작 (HttpPost 동작)을 다음과 같이 바꿉니다. 다시, 우리는 편집 동작과 비슷한 것을하고 있습니다. 레코드를 삭제하고 객체로 캐스팅 한 다음 해당 객체를 아래 그림과 같이 client.DeleteAsync()
호출로 전달합니다.
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
response = client.GetAsync(string.Format("api/contact/{0}", id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.DeleteAsync(contactUri).Result;
return RedirectToAction("Index");
}
오류 게시. 그러나 왜 응용 프로그램이 이미 서비스가 캡슐화하고있는 모든 코드에 액세스 할 수 있다고 가정 할 때 동일한 응용 프로그램에서 웹 API를 사용하려고합니까? 필요하지 않을 때 여분의 오버 헤드를 소비하는 이유는 무엇입니까? – Maess
전적으로 당신의 의견에 동의하지만 기술적 인 이유가 있습니까? 아니면 그것을 구현할 수없는 잘못된 방법일까요? – user1570094
@Maess, MVC 및 WebAPI는 동일한 응용 프로그램에 존재하도록 설계되었습니다. 원하는 경우 특정 API 컨트롤러를 별도의 폴더 (예 : "API")에 루트 디렉토리로 보내어 구분할 수 있습니다. 동일한 RouteConfig.cs와 WebApiConfig.cs가 동일한 App_Start 폴더에있는 이유입니다. 왜냐하면 같은 프로젝트에서 두 가지를 모두 활용할 것으로 예상되기 때문입니다. 그것은 필수는 아니지만. –