带DataRow的ASP.NET控制器

时间:2012-12-22 21:13:26

标签: c# asp.net-mvc strongly-typed-dataset

我正在构建一个与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元素。我认为有一种方法可以做到这一点,但我似乎无法找到它。

谢谢!

2 个答案:

答案 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>