我正在构建一个与SQL Server数据库通信的简单ASP.NET应用程序。在一个单独的项目中,我有一个由Visual Studio生成的数据集。我正在尝试公开一个API,它将显示数据库中的所有用户,但我得到了一个例外。
以下是代码:
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元素。我认为有一种方法可以做到这一点,但我似乎无法找到它。
谢谢!
答案 0 :(得分:2)
这是因为您无法共享DataRow对象。它们不可序列化。如果要共享它,则应创建DTO对象。从服务,API等共享对象是一个很好的实践。将您的DataRow转换为DTO对象。尝试类似:
创建您的类作为此DTO,示例:
[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 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;
}
}
答案 1 :(得分:0)
离开Felipe的回答(在记住我需要处理可怕的DBNull之后),这是我构建的最终方法:
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;
}
}
这给了我一个输出:
<ArrayOfuser xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/GW.Entities">
<user>
<EmailAddress>seraieis@gmail.com</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>