2012-12-22 1 views
1

SQL 서버 데이터베이스와 통신하는 간단한 ASP.NET 응용 프로그램을 구축하고 있습니다. 별도의 프로젝트에서 Visual Studio에 의해 생성 된 데이터 집합이 있습니다. 데이터베이스의 모든 사용자를 표시하는 API를 노출하려고하지만 예외가 발생합니다. 여기 DataRow가있는 ASP.NET 컨트롤러

코드입니다 :

public class UserController : ApiController { 

    public IEnumerable<GWDataSet.usersRow> GetAllUsers() { 
     GWDataSet gw = new GWDataSet(); 
     usersTableAdapter adapter = new usersTableAdapter(); 
     adapter.Fill(gw.users); 

     return gw.users.AsEnumerable(); 
    } 
} 

그리고 이것은 예외 :

Type 'System.Data.DataRow' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types. 

이 주위에 방법이 있나요 이외의 수동 시스템에서 생성 된 코드를 편집 할 수있는? 내 두려움은 다음에 데이터 세트를 변경하면 내가 추가 한 모든 datacontract 요소를 덮어 쓰게 될 것입니다. 이렇게 할 방법이 있다고 생각 하겠지만 찾지 못하는 것 같습니다.

감사합니다.

답변

2

DataRow 개체를 공유 할 수 없기 때문입니다. 이들은 직렬화 할 수 없습니다. 이를 공유하려면 DTO 객체를 만들어야합니다. 서비스, ​​API 등에서 객체를 공유하는 좋은 방법입니다. Tru는 DataRow를 DTO 객체로 변환합니다. 샘플이 DTO로 클래스를 생성

: 뭔가를 시도 펠리페의 대답 떨어져가는

public class UserController : ApiController { 

    public IEnumerable<UserDTO> GetAllUsers() { 
     GWDataSet gw = new GWDataSet(); 
     usersTableAdapter adapter = new usersTableAdapter(); 
     adapter.Fill(gw.users); 

     List<UserDTO> list = new List<UserDTO>(); 

     foreach(DataRow row in gw.users.Rows) 
     { 
      UserDTO user = new UserDTO(); 
      user.FirstName = row["Name"].ToString(); 
      // fill properties 

      list.Add(user); 
     } 

     return list; 
    } 
} 
+0

나는이 작업을 시작했는데, 나는 데이터베이스에 이것을 적용 할 때 (나는 이것에 대해 지금 배우 고있다.) 유지해야 할 것 같다. 두 영역의 코드는 기본적으로 같은 것입니다. DataRow는 데이터베이스에서 사용자 정보를 노출하므로 간단한 방법으로 재사용 할 수 있기를 바랍니다. –

+1

@DanChampagne Filipe가 맞습니다. API의 데이터를 나타 내기 위해 별도의 클래스를 만들고 싶을 것입니다. 비록 당신이 일을 복제하고있는 것처럼 느낄지라도 정말로 그렇지 않습니다. API를 통해 데이터베이스의 모든 것을 절대 공개하고 싶지는 않을 것입니다. DB와는 별도로 디자인을 생각하고 싶을 것입니다. 또한 자동 생성 코드를 수동으로 편집하면 항상 혈액으로 끝납니다. :) –

0

을 (이후 :

[Serializable] 
public class UserDTO 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Address { get; set; } 
    public string Birthday { get; set; } 
    /* other properties you need */ 
} 

을 그리고 당신의 웹 API에, 이것을 시도 줄

public IEnumerable<GW.Entities.user> GetAllUsers() { 
     try { 
      GWDataSet gw = new GWDataSet(); 
      List<GW.Entities.user> users = new List<user>(); 
      usersTableAdapter adapter = new usersTableAdapter(); 

      adapter.Fill(gw.users); 

      foreach (GWDataSet.usersRow row in gw.users.Rows) { 
       users.Add(new GW.Entities.user { 
        UserId = row.IsNull("UserId") ? 0 : row.UserId, 
        UserName = row.IsNull("UserName") ? "" : row.UserName, 
        EmailAddress = row.IsNull("EmailAddress") ? "" : row.EmailAddress, 
        UserPasswordLastChange = row.IsNull("UserPasswordLastChange") ? DateTime.MinValue : row.UserPasswordLastChange, 
        LastLogin = row.IsNull("LastLogin") ? DateTime.MinValue : row.LastLogin, 
        StatusCd = row.IsNull("StatusCd") ? "" : row.StatusCd, 
        LastTimestamp = row.IsNull("LastTimestamp") ? null : row.LastTimestamp 
       }); 
      } 

      return users; 
     } catch (Exception ex) { 
      Debug.WriteLine(ex.ToString()); 
      return null; 
     } 
    } 

: 여기에 내가 만든 마지막 방법이다) 나는 지칠대로 지친 DBNull이 다룰 필요가 있음을 기억 나 출력 :

<ArrayOfuser xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/GW.Entities"> 
    <user> 
     <EmailAddress>[email protected]</EmailAddress> 
     <LastLogin>2012-12-19T20:48:26.41</LastLogin> 
     <LastTimestamp>AAAAAAAARlI=</LastTimestamp> 
     <StatusCd>A</StatusCd> 
     <UserId>1</UserId> 
     <UserName>seraieis</UserName> 
     <UserPasswordLastChange>0001-01-01T00:00:00</UserPasswordLastChange> 
    </user> 
</ArrayOfuser>