2012-06-22 68 views
0

基於this article我能夠使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數據的人。任何幫助將不勝感激。

回答

0

在做了一些測試後,我將Utilities.Serialize ...代碼放入FullName工作區。然後我將FullName重命名爲FullNameXX,失敗。經過幾次測試後,我得出結論:要保存在配置文件中的所有屬性都需要是字符串(或者我假設的二進制文件,但我沒有在SQL中使用PropertyValuesBinary數據字段。)所以,當我有一個複雜的字段,就像我的List那樣,我有一個程序員的屬性,它獲取並設置一個List以及一個存儲的相同屬性的字符串版本。所以我現在有一個SectionSettings和一個SectionSettingsValue屬性。需要做的另一個調整是使其只是一個DataContract和不可序列化,否則你會得到額外的值,如IM__看起來不好的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 = ...示例中,請注意它ret由於數據是「Primart Thing」而不是「Primary Thing」,因此請不填。

希望這可以幫助那裏的人。