1

SQL サーバー データベースと通信する単純な 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 要素が上書きされるのではないかと心配しています。これを行う方法があると思いますが、見つけられないようです。

ありがとう!

4

2 に答える 2

2

これは、DataRow オブジェクトを共有できないためです。それらはシリアライズ可能ではありません。共有したい場合は、DTO オブジェクトを作成する必要があります。これは、サービス、API などからオブジェクトを共有するための良い方法です。DataRow を DTO オブジェクトに変換する場合は True です。次のようなものを試してください:

サンプルとして、この 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;
    }
}
于 2012-12-22T21:48:56.700 に答える
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>
于 2012-12-23T14:19:02.837 に答える