2012-06-22 7 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. 

Я явно делаю что-то неправильно, я должен предположить, что я не первый, кто хочет сохранить данные json в поставщике профиля по умолчанию ASP.Net. Любая помощь будет принята с благодарностью.

ответ

0

После выполнения некоторых тестов, где я ввел код Utilities.Serialize ... в рабочий FullName, это сработало. Затем я переименовал FullName в FullNameXX и не получилось. После нескольких тестов я пришел к выводу, что все свойства, которые нужно сохранить в профиле, должны быть строками (или двоичными, я предполагаю, но я не использую поле данных PropertyValuesBinary в SQL.) Поэтому, когда у меня было сложное поле , как и в моем списке, тогда у меня было свойство для программистов, которые получают и задают список, а также строчную версию того же самого свойства, которое хранится. Итак, теперь у меня есть свойство SectionSettings и свойство SectionSettingsValue. Другая необходимая корректировка заключалась в том, чтобы сделать это только DataContract и NOT Serializable, или вы получите дополнительные значения, такие как k__backingField, которые IMHO выглядят плохо.

Ниже следует полный код ...

Вот мой 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».

Надеюсь, что это поможет кому-то там.