0

この記事に基づいて、FullNameをかなり簡単に機能させることができました。

子クラスもある次のクラスがあります。

[DataContract]
[Serializable]
public class SettingSection
{
    public SettingSection()
    {
        this.UserSettings = new List<UserSettingPair>();
    } // SettingSection - Constructor

    public SettingSection(List<UserSettingPair> UserSettings)
    {
        this.UserSettings = UserSettings;
    } // SettingSection - Constructor

    [DataMember(Name = "sectionName")]
    public string SectionName { get; set; }

    [DataMember(Name = "userSettings")]
    public List<UserSettingPair> UserSettings { get; set; }

} // SettingSection - Class

[DataContract]
[Serializable]
public class UserSettingPair
{
    [DataMember(Name = "key")]
    public string Key { get; set; }

    [DataMember(Name = "value")]
    public string Value { get; set; }
} // UserSettingPair - Class

次に、次のコードを使用してこれをJSonにシリアル化する方法があります。

public static string Serialize<T>(object input)
{
    string Result = "";
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));

    using (MemoryStream ms = new MemoryStream())
    {
        ser.WriteObject(ms, input);
        Result = Encoding.Default.GetString(ms.ToArray());
    }

    return Result;
}

上記の記事にあることを行うと、次のように機能します。

UserProfileContract.CurrentUser.FullName = "Testing";

List / Complexオブジェクト(現在はjsonフォーマット文字列)で試してみると...

base["sectionSettings"] = (Utilities.Serialize<List<SettingSection>>(Settings)).ToString();
Save();

次のエラーが発生します(上記の注では、.ToString()を使用して文字列に二重に強制しましたが、運がありません:

The settings property 'sectionSettings' is of a non-compatible type.

私は明らかに何か間違ったことをしています。ASP.Netのデフォルトのプロファイルプロバイダーにjsonデータを保存したいのは私が最初ではないと想定する必要があります。どんな助けでも大歓迎です。

4

1 に答える 1

0

Utilities.Serialize ...コードを機能するFullNameに配置するテストを行った後、機能しました。次に、FullNameの名前をFullNameXXに変更しましたが、失敗しました。さらにいくつかのテストを行った結果、プロファイルに保存するすべてのプロパティは文字列である必要があるという結論に達しました(または、SQLではPropertyValuesBinaryデータフィールドを使用していません)。 、私のリストのように、私はリストを取得および設定するプログラマー用のプロパティと、格納される同じプロパティの文字列バージョンを持っていました。これで、SectionSettingsプロパティとSectionSettingsValueプロパティができました。必要なもう1つの調整は、DataContractのみにし、Serializableではないようにすることでした。そうしないと、k__backingFieldのような追加の値が得られます。

以下は完全なコードである必要があります...

これが私のDataContractです:

[DataContract]
public class UserProfileContract : ProfileBase
{

    #region Constructors

    public UserProfileContract()
    {
    } // UserProfileContract - Constructor

    public UserProfileContract(List<SettingSection> SectionSettings)
    {
        this.SectionSettings = SectionSettings;
    } // UserProfileContract - Constructor

    #endregion Constructors

    public static UserProfileContract CurrentUser
    {
        get { return (UserProfileContract)(ProfileBase.Create(Membership.GetUser().UserName)); }
    }

    public string FullNameValue { get; set; }
    public string SectionSettingsValue { get; set; }

    [DataMember(Name = "FullName")]
    public string FullName
    {
        get { return ((string)(base["FullNameValue"])); }
        set {
            base["FullNameValue"] = value;
            Save();
        }
    } // FullName - Property

    [DataMember(Name = "SectionSettings")]
    public List<SettingSection> SectionSettings
    {
        get { return Utilities.Deserialize<List<SettingSection>>(base["SectionSettingsValue"].ToString()); }
        set
        {
            base["SectionSettingsValue"] = Utilities.Serialize<List<SettingSection>>(value);
            Save();
        }
    } // SectionSettings - Property

} // UserProfileContract - Class

[DataContract]
public class SettingSection
{
    public SettingSection()
    {
        this.UserSettings = new List<UserSettingPair>();
    } // SettingSection - Constructor

    public SettingSection(List<UserSettingPair> UserSettings)
    {
        this.UserSettings = UserSettings;
    } // SettingSection - Constructor

    [DataMember]
    public string SectionName { get; set; }

    [DataMember]
    public List<UserSettingPair> UserSettings { get; set; }

} // SettingSection - Class

[DataContract]
public class UserSettingPair
{
    [DataMember]
    public string Key { get; set; }

    [DataMember]
    public string Value { get; set; }
} // UserSettingPair - Class

これが私の静的ユーティリティクラスです:

public static T Deserialize<T>(string json)
{
    var obj = Activator.CreateInstance<T>();

    if (string.IsNullOrWhiteSpace(json))
        return obj;

    using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
    {
        var serializer = new DataContractJsonSerializer(obj.GetType());
        obj = (T)serializer.ReadObject(ms);

        return obj;
    } // using the memory stream
} // Deserialize - Method

public static string Serialize<T>(object input)
{
    string Result = "";
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));

    using (MemoryStream ms = new MemoryStream())
    {
        ser.WriteObject(ms, input);
        Result = Encoding.Default.GetString(ms.ToArray());
    }

    return Result;
} // Serialize - Method

FullNameプロパティだけでなく、複数のセクションにデータを保存する方法の例を次に示します。

// First Section
SettingSection s = new SettingSection();
s.SectionName = "ContractSearch";

UserSettingPair usp = new UserSettingPair();
usp.Key = "Default Control";
usp.Value = "txtFirstTextBox";

s.UserSettings.Add(usp);

usp = new UserSettingPair();
usp.Key = "Field1Choice";
usp.Value = "SchoolName";

s.UserSettings.Add(usp);

List<SettingSection> ss = new List<SettingSection>();
ss.Add(s);

// Second Section
s = new SettingSection();
s.SectionName = "Workflow Settings";

usp = new UserSettingPair();
usp.Key = "Primart Thing";
usp.Value = "Blabla bla";

s.UserSettings.Add(usp);

usp = new UserSettingPair();
usp.Key = "Allowable Tries";
usp.Value = "3";

s.UserSettings.Add(usp);

usp = new UserSettingPair();
usp.Key = "Extra Value";
usp.Value = "Gigity";

s.UserSettings.Add(usp);
ss.Add(s);

UserProfileContract.CurrentUser.FullName = "Grigsby";
UserProfileContract.CurrentUser.SectionSettings = ss;

SectionSetting値の抽出を簡単にするために作成した拡張メソッドは次のとおりです。

public static T GetSectionValue<T>(this UserProfileContract up, string Section, string Property)
{
    string value = (from ss in up.SectionSettings
                                        from us in ss.UserSettings
                                        where ss.SectionName == Section
                                        && us.Key == Property
                                        select us.Value).FirstOrDefault();

    try
    {
        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch (InvalidCastException)
    {
        return default(T);
    }
} // GetSectionValue - Extension Method

そして最後に、上記の拡張メソッドの例:

string k = x.GetSectionValue<string>("Workflow Settings", "Primary Thing");
string g = x.GetSectionValue<string>("Workflow Settings", "Extra Value");
int three = x.GetSectionValue<int>("Workflow Settings", "Allowable Tries");

これが私が入れた値の文字列バージョンです:

[{"SectionName":"ContractSearch","UserSettings":[{"Key":"Default Control","Value":"txtFirstTextBox"},{"Key":"Field1Choice","Value":"SchoolName"}]},{"SectionName":"Workflow Settings","UserSettings":[{"Key":"Primart Thing","Value":"Blabla bla"},{"Key":"Allowable Tries","Value":"3"},{"Key":"Extra Value","Value":"Gigity"}]}]Grigsby

上記の文字列k=...の例では、データが「PrimaryThing」ではなく「PrimartThing」であるため、nullが返されることに注意してください。

これが誰かを助けてくれることを願っています。

于 2012-06-22T20:23:36.133 に答える