2014-05-13 5 views
3

웹 API 메소드를 사용하려고하는데 많은 성공을 거두지 못했습니다. 내 컨트롤러에서웹 API가 작동하지 않습니다.

내가 가진 :

public class TestAPIController : ApiController 
{ 
public string Get() 
    { 
     return "Hello World"; 
    } 

    public Cours Get(int id) 
    { 
     using (SSDEntities Entity = new SSDEntities()) 
     return Entity.Courses.SingleOrDefault<Cours>(a => a.ID == id); 
    } 

를 내 Global.asax에에서 내가 가진 :

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
    } 

    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
    ); 
     routes.MapHttpRoute(
      name: "ApiWithAction", 
      routeTemplate: "api/{controller}/{action}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}", // URL with parameters 
      new { controller = "Home", action = "Index" } // Parameter defaults 
     ); 

    } 

    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 

    } 

을 문제는 내가/API/TestAPI를 입력하면 내가 성공적으로 "안녕하세요"를 참조입니다 그러나/api/TestAPI/7은 다음 예외 메시지를 표시합니다. 'ObjectContent`1'형식이 'application/xml; 콘텐츠 형식에 대한 응답 본문을 serialize하지 못했습니다. charset = utf-8 '.

데이터베이스에서 반환 한 ID "7"과 일치하는 결과가 1 개 있습니다. 내가 뭘 잘못하고 있는지 모르겠다. 누구든지 도울 수 있니?

+1

당신의 문제는 당신이 EF 객체를 반환한다는 것입니다 ... 그렇게하지 마십시오 ... 모델을 생성하고 그것을 매핑하십시오. – CrazyDart

답변

2

모델에 매핑. 활성 EF 객체를 직렬화하려고해서는 안됩니다. 실패 할 수있는 데에는 여러 가지 이유가 있습니다. 그것은 게으른 속성을 가지고 있기 때문에 발생할 수 있지만 개체에 루프가있을 수도 있습니다. 필요한 것을지도에 매핑하면됩니다.

public CoursModel Get(int id) 
{ 
    using (SSDEntities Entity = new SSDEntities()) 
    return Entity.Courses.SingleOrDefault<Cours>(a => a.ID == id) 
    .Select(x=> new CoursModel() 
     { MAP STUFF HERE }); 
} 
+0

당신의 대답이 나를 위해 정확히 작동하지는 않았지만 약간의 수정이있었습니다. 다음 코드는 내게 도움이되었습니다. 대답을 업데이트하여 위대하게 포함 시키려면 다음 코드를 사용하십시오. using (SSDEntities Entity = new SSDEntities()) return 새 APIModel() {MAP STUFF HERE} – GomuGomuZoro

2

여기서 적어도 두 가지 문제가있을거야 ... 엔티티 프레임 워크에 의해 제어됩니다 개체를 반환하는 :

  1. The 'ObjectContent1' type failed to serialize...가 발생 정확한 오류 엔티티 클래스가 어떤 IQueryable<T>이있는 경우/IEnumerable<T>/ICollection<T> EF에서 지연로드 된 속성입니다. 시리얼 라이저는 이것을 처리 할 수 ​​없습니다.
  2. 그 이상의 경우 데이터 컨텍스트도 삭제되므로 직렬화 기가 지연로드 된 다른 속성을 해결하려고하면 실패합니다.

WebAPI를 사용하여 개체를 밖으로 나가기 전에 필요한 속성 만 사용하여 개체를 바스 트 개체로 스트립합니다. 웹 프로젝트에서 EF 클래스 (see @CrazyDart's answer)를 앞뒤로 매핑하는 일련의 모델 클래스로이 작업을 수행 할 수 있습니다. 또는과 같이 익명의 객체를 프로젝트 :

return new 
{ 
    WantedProperty = entity.SomeProperty 
}; 

(. 당신이 작동하지 object에 WebAPI 반환 형식을 변경해야합니다 참고) 최근의 프로젝트에서

을 내가 본 개발자가 접근을 익명 객체를 반환하고 인수를 취하는 메서드에 대해 dynamic 인수를 사용하고 컨트롤러에서 JSON 분해를 처리하는 방법에 대해 설명합니다. 중소 규모 프로젝트의 경우 이것은 매우 효율적으로 보입니다. 좀 더 공식적인 프로젝트 나 더 큰 프로젝트의 경우 매핑이있는 적절한 프레임 워크가 더 적합 할 수 있습니다.

+0

익명 개체는 좋은 것입니다. way to go ...하지만 메소드의 리턴 타입을 변경해야합니다. 이점은 유지 보수하는 데 드는 코드가 적어 동일한 메소드에서 여러 개의 다른 객체를 반환 할 수 있다는 것입니다. 단점은 문서를 생성 할 수 없다는 것입니다. – CrazyDart

+0

@CrazyDart 옙 ... 나는 그것을 추가 할 것이다. –

관련 문제