Pracuję nad pewnego rodzaju aplikacji "przechowywania i przekazywania" dla usług WCF. Chcę zapisać wiadomość w bazie danych jako surowy blob XML, tak jak XElement. Mam problem z konwertowaniem datacontract na typ XElement, którego potrzebuję do wywołania bazy danych. Jakieś pomysły?Trwałe DataContract jako XML w bazie danych
Odpowiedz
ta zwraca go jako ciąg znaków, który można umieścić w db do kolumny xml. Oto dobra ogólna metoda, której możesz użyć do serializowania danych na serwerze.
public static string Serialize<T>(T obj)
{
StringBuilder sb = new StringBuilder();
DataContractSerializer ser = new DataContractSerializer(typeof(T));
ser.WriteObject(XmlWriter.Create(sb), obj);
return sb.ToString();
}
btw, czy używasz linq do sql? Powód, dla którego pytam, jest spowodowany częścią XElement twojego pytania. Jeśli tak jest, możesz zmodyfikować to w projektancie .dbml, aby użyć ciągu znaków jako typu CLR, a nie domyślnego XElement.
To nie działa dla mnie. Zobacz odpowiedź użytkownika224125 poniżej. –
nie jestem pewien co najbardziej efektywny sposób, aby dostać się do Xelement, ale aby dostać się do łańcucha wystarczy uruchomić:
DataContractSerializer serializer = new DataContractSerializer(typeof(Foo));
using (MemoryStream memStream = new MemoryStream())
{
serializer.WriteObject(memStream, fooInstance);
byte[] blob = memStream.ToArray();
}
Jeśli baza danych jest SQL Server 2005 lub nowszy, można użyć typu danych XML:
private readonly DataContractToSerialize _testContract =
new DataContractToSerialize
{
ID = 1,
Name = "One",
Children =
{
new ChildClassToSerialize {ChildMember = "ChildOne"},
new ChildClassToSerialize {ChildMember = "ChildTwo"}
}
};
public void SerializeDataContract()
{
using (var outputStream = new MemoryStream())
{
using (var writer = XmlWriter.Create(outputStream))
{
var serializer =
new DataContractSerializer(_testContract.GetType());
if (writer != null)
{
serializer.WriteObject(writer, _testContract);
}
}
outputStream.Position = 0;
using (
var conn =
new SqlConnection(Settings.Default.ConnectionString))
{
conn.Open();
const string INSERT_COMMAND =
@"INSERT INTO XmlStore (Data) VALUES (@Data)";
using (var cmd = new SqlCommand(INSERT_COMMAND, conn))
{
using (var reader = XmlReader.Create(outputStream))
{
var xml = new SqlXml(reader);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@Data", xml);
cmd.ExecuteNonQuery();
}
}
}
}
}
Próbowałem użyć funkcji Jason w'Serialize który używa StringBuilder, ale zwraca pusty ciąg dla LingToSQL Designer wygenerowane klasy stół z [DataContract()] przypisują
jednak gdybym serialze do tablicy bajtów jak sugeruje AgileJon
a następnie użyć UTF7Encoding przekonwertować ciąg tworzy czytelnego ciągu XML.
static string DataContractSerializeUsingByteArray<T>(T obj)
{
string sRet = "";
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
using (MemoryStream memStream = new MemoryStream())
{
serializer.WriteObject(memStream, obj);
byte[] blob = memStream.ToArray();
var encoding= new System.Text.UTF7Encoding();
sRet = encoding.GetString(blob);
}
return sRet;
}
Nie wiem, dlaczego rozwiązanie StringBuilder nie działa.
Najbardziej głosowana na odpowiedź (Jason W. opublikowane) nie działa dla mnie. Nie wiem, dlaczego ta odpowiedź ma najwięcej głosów. Ale po poszukiwaniach wokół znalazłem to
http://billrob.com/archive/2010/02/09/datacontractserializer-converting-objects-to-xml-string.aspx
która pracowała dla mojego projektu. Właśnie miałem kilka klas i umieściłem dataceme i atrybuty datamemeber na klasach i właściwościach, a następnie chciałem uzyskać łańcuch XML, który mógłbym napisać do bazy danych.
kod z linku powyżej okrywać idzie 404:
Serializes:
var serializer = new DataContractSerializer(tempData.GetType());
using (var backing = new System.IO.StringWriter())
using (var writer = new System.Xml.XmlTextWriter(backing))
{
serializer.WriteObject(writer, tempData);
data.XmlData = backing.ToString();
}
Deserializes:
var serializer = new DataContractSerializer(typeof(T));
using (var backing = new System.IO.StringReader(data.XmlData))
using (var reader = new System.Xml.XmlTextReader(backing))
{
return serializer.ReadObject(reader) as T;
}
Dzięki za link. –
- 1. Użyj wspólny typ danych jako DataContract w WCF
- 2. Jak dodać atrybut XML za pomocą DataContract
- 3. WCF DataContract DataMember order?
- 4. Jak serializować/deserializować C# WCF DataContract do/z XML
- 5. DataContract, domyślna wartość DataMember
- 6. Porównaj daty (przechowywane jako ciąg) w bazie danych Android sqlite?
- 7. wstawienie null jako wartość całkowita w bazie danych
- 8. Zapisz ciąg dat w bazie danych MySQL jako sygnaturę czasową
- 9. Mapowanie klucza podstawowego jako klucza obcego w bazie danych
- 10. Przewidywanie brakujących wartości danych w bazie danych
- 11. Trwałe zapamiętywanie w Pythonie
- 12. Generowanie DataContract z XSD
- 13. WCF: MessageContract, DataContract ... Confused?
- 14. Wstawianie rekordów zbioru danych w bazie danych
- 15. Android istnieje() w bazie danych?
- 16. Html w mojej bazie danych!
- 17. MySQL typ danych w bazie
- 18. Kwerendy hibernacji w bazie danych
- 19. Zachowaj ustawienia w bazie danych
- 20. Zwiększanie licznika w bazie danych
- 21. Trwałe przechowywanie zaszyfrowanych danych przy użyciu .Net
- 22. Trwałe/buforowanie danych między żądaniami - wspólne podejście
- 23. Najlepszy sposób na przechowywanie danych XML w bazie danych MySQL, z określonymi wymaganiami
- 24. Zmień procedurę zdefiniowaną w bazie danych
- 25. Zapisywanie danych w języku arabskim w bazie danych MySQL
- 26. Aktualizacja pola bitowego sql w bazie danych
- 27. Trwałe listy ACL Zend Framework
- 28. Przechowywanie częściowych dat w bazie danych
- 29. DataContract i ServiceContract różnica
- 30. Dane URI vs. Binary w bazie danych
Xelement nie jest taka sama jak "surowego xml blob". Ten pierwszy jest typem, przydatnym do tego przy pomocy XML. Drugi to ciąg o określonym formacie. Możesz zapisać w dowolnym typie ozdobionym [DataContract] ciągiem XML. (Zobacz przykłady poniżej). XElement - możesz usiąść na swojej credenzie, nie potrzebujesz tego. – Cheeso