2017-11-26 10 views
0

데이터를 게시 할 테이블 2 개 (학생 및 부모)가 있습니다. MVC 컨트롤러와 API 컨트롤러가 있습니다. mvc 컨트롤러에서 createStudent (StudentViewModel student) 동작 메서드를 API 컨트롤러의 PostStudent (StudentViewModel 학생)로, PostParent (ParentViewModel p)의 createParent (ParentViewModel p)로 각각 라우팅하려고합니다. 그러나 API 컨트롤러에서 두 가지 POST 메서드를 사용하면 모호한 결과를 초래합니다.MVC 컨트롤러 동작 메서드를 Web Api 컨트롤러 (여러 포스트 메서드가있는 Web API 컨트롤러)의 각 게시 메서드에 연결

mvc 컨트롤러를 통해 동일한 API 컨트롤러에서 두 가지 POST 메서드를 사용하는 방법을 찾을 수 없습니다.

이것은 MVC 컨트롤러에 내 코드입니다 (StudentController 이름)

public ActionResult createStudent() 
    { 
     return View(); 
    } 

[System.Web.Mvc.HttpPost] 
public ActionResult createStudent(StudentViewModel student) 
{ 
    using (var client = new HttpClient()) 
    { 
     client.BaseAddress = new Uri("http://localhost:39673/api/student"); 

     var postTask = client.PostAsJsonAsync<StudentViewModel>("student", student); 
     postTask.Wait(); 

     var result = postTask.Result; 
     if (result.IsSuccessStatusCode) 
     { 
      return RedirectToAction("Index"); 
     } 
    } 

    ModelState.AddModelError(string.Empty, "Server Error. Please contact administrator."); 

    return View(student); 
} 

public ActionResult createparent() 
{ 
    return View(); 
} 

[System.Web.Mvc.HttpPost] 
public ActionResult createparent(ParentViewModel p) 
{ 
    using (var client = new HttpClient()) 
    { 
     client.BaseAddress = new Uri("http://localhost:39673/api/Student"); 

     //HTTP POST 
     var postTask = client.PostAsJsonAsync<ParentViewModel>("parent", p); 
     postTask.Wait(); 

     var result = postTask.Result; 
     if (result.IsSuccessStatusCode) 
     { 
      return View(); 
     } 
    } 

    ModelState.AddModelError(string.Empty, "Server Error. Please contact administrator."); 

    return View(p); 
} 

이 기본으로 내 (StudentController 이름) API 컨트롤러

public class StudentController : ApiController 
    { 
     //POST Student 
     public IHttpActionResult PostStudent(StudentViewModel student) 
     { 
      if (!ModelState.IsValid) 
       return BadRequest("Invalid data."); 

      using (var ctx = new MyEntities()) 
      { 
       ctx.Students.Add(new Student() 
       { 
        Name = student.Name, 
        MobileNO = student.MobileNO 
       }); 

       ctx.SaveChanges(); 
      } 

      return Ok(); 
     } 

//POST Parent 
public IHttpActionResult PostParent(ParentViewModel p) 
     { 
      if (!ModelState.IsValid) 
       return BadRequest("Invalid data."); 

      using (var ctx = new MyEntities()) 
      { 
       ctx.Parents.Add(new Parent() 
       { 
        StudentID=p.StudentID, 
        ParentName = p.ParentName, 
       }); 

       ctx.SaveChanges(); 
      } 

      return Ok(); 
     } 
    } 

감사

답변

0

입니다 api 엔드 포인트를 등록하기위한 라우트 정의를 사용하면 en 형식은 api/controllername입니다. 기본적으로 메서드 서명 (기본 매개 변수)과 Http 동사 (GET/POST)의 조합을 사용하여 해당 메서드에 액세스합니다. 따라서 리소스 (학생/부모)에 대한 POST 메서드는 하나만 사용해야합니다.

학생용으로 하나의 Parent 컨트롤러를 만들고 Parent 용으로 하나의 Pio 컨트롤러를 만드는 것이 좋습니다. 각각은 자신의 Post 메소드를 가질 수 있습니다.

public class StudentController : ApiController 
{ 
    [HttpPost] 
    public IHttpActionResult Post(StudentViewModel student) 
    { 
     return Ok(); 
    } 
} 
public class ParentController : ApiController 
{ 
    [HttpPost] 
    public IHttpActionResult Post(ParentViewModel parent) 
    { 
     return Ok(); 
    } 
} 

지금 HttpPost 방법이 /api/student/api/parent를 호출합니다.

또 다른 옵션은 명시 적으로 경로 템플리트를 동일한 컨트롤러의 메소드에 제공하는 것입니다.

public class StudentController : ApiController 
{ 
    [HttpPost] 
    [Route("api/student/")] 
    public IHttpActionResult PostStudent(StudentViewModel student) 
    { 
     return Ok(); 
    } 

    [HttpPost] 
    [Route("api/parent/")] 
    public IHttpActionResult PostParent(ParentViewModel p) 
    { 
     return Ok(); 
    } 
} 

지금 HttpPost 방법이 /api/student/api/parent를 호출합니다. 이것이 작동하는 동안 나는 개인적으로 리소스에 대해 하나의 API 컨트롤러를 사용하는 첫 번째 방법을 선호합니다. 그게 내게 훨씬 깨끗해 보이는 군.

또한 코드를 보면 mvc 컨트롤러에서 웹 API 컨트롤러를 호출하는 것처럼 보입니다. MVC 컨트롤러와 웹 API 컨트롤러가 동일한 프로젝트에 있다면 http 호출을하는 대신 공통 헬퍼 메서드를 호출하면됩니다. 웹 API 컨트롤러와 mvc 컨트롤러에서 동일한 공통 헬퍼를 호출하여 저장 코드가 한 곳에서만 가능하도록 할 수 있습니다.

또한 교착 상태를 방지하기 위해 asyncawait까지 줄곧 시도해야합니다.

이 게시물을보십시오. await vs Task.Wait - Deadlock?

+0

감사합니다. 나는 이미 첫 번째 접근 방식으로 작업하고있다. 그러나 저는 두 번째 접근 방식을 시도하고 싶습니다. –