4

データベースに XML ストリームを返すストアド プロシージャがあり、アプリケーションはそのストリームを対応するオブジェクトに逆シリアル化します。ストアド プロシージャは次のように定義されます (読みやすくするために簡略化しています)。

SELECT 
    usrs.FirstName AS 'FirstName',
    usrs.LastName AS 'LastName',
    usrs.Username AS 'Username',
    usrs.DateJoined AS 'DateJoined'
FROM USERS AS usrs
WHERE usrs.Username = @username
FOR XML PATH('UserProfile')

Usernameは主キーであるため、ストアド プロシージャは 1 つの結果のみを返すことに注意してください。サンプルのクエリ結果は次のようになります。

<UserProfile>
  <FirstName>Chuck</FirstName>
  <LastName>Norris</LastName>
  <Username>chuck.awesome</Username>
  <DateJoined>2013-07-22T06:58:00</DateJoined>
</UserProfile>

アプリケーションでは、データを取得して逆シリアル化する方法は次のとおりです。

internal static T GetData<T>(StoredProcedures storedProcedure, ParameterList parameters)
    {
        using (var connection = GetSqlConnection())
        {
            using (var command = new SqlCommand(storedProcedure.ToString(), connection))
            {
                command.CommandType = System.Data.CommandType.StoredProcedure;

                foreach (var parameter in parameters)
                {
                    command.Parameters.Add(new SqlParameter(parameter.Key.ToString(), parameter.Value));
                }

                connection.Open();

                var data = command.ExecuteScalar();

                return DeserializeXml<T>(data.ToString());
            }
        }
    }

そしてDeserializeXML<T>()方法:

private static T DeserializeXml<T>(string xmlStream, Type[] additionalTypes = null)
    {
        XmlSerializer serializer;

        if (additionalTypes == null)
        {
            serializer = new XmlSerializer(typeof(T));
        }
        else
        {
            serializer = new XmlSerializer(typeof(T), additionalTypes);
        }

        using (StringReader reader = new StringReader(xmlStream))
        {
            return (T)serializer.Deserialize(reader);
        }
    }

そして最後にUserProfileクラス:

[XmlRoot("UserProfile")]
[Serializable]
public class UserProfile
{
    public UserProfile()
    {
    }

    [XmlAttribute("Username")]
    public string Username { get; set; }

    [XmlAttribute("FirstName")]
    public string FirstName { get; set; }

    [XmlAttribute("LastName")]
    public string LastName { get; set; }

    [XmlAttribute("DateJoined")]
    public DateTime DateJoined { get; set; }
}

UserProfileアプリケーションを実行すると、ストアド プロシージャが期待値を返すことがわかりますが、シリアライザーはすべてのフィールドが設定されたオブジェクトを返しますnull(ただし、DateJoinedフィールドは null 許容ではないため、既定値に設定されています)。何がうまくいかないのでしょうか?XmlRoot()オブジェクトの属性である可能性があると思われますUserProfileが、シリアライザーは例外をスローしないため、混乱しています。何がうまくいかないのでしょうか?前もって感謝します。

4

2 に答える 2

1

逆シリアル化がnullとして返されるという同じ問題がありました。以下のように要素名を間違って入力してしまいました [XmlElement(ElementName = "fname")]

正しいものは - [XmlElement(ElementName = "firstname")] でした

参考までに、誰かがこの間違いを犯した場合。

于 2014-10-08T09:52:34.870 に答える