Korzystanie z zestawu danych z usługi internetowej XML
Został DataSet zaprojektowany z rozłączonym projektem, częściowo w celu ułatwienia wygodnego transportu danych przez Internet. Zestaw Danych jest "możliwy do serializacji", ponieważ można go określić jako dane wejściowe lub wyjściowe z usług sieci Web XML bez dodatkowego kodowania wymaganego do strumieniowego przesyłania zawartości zestawu danych z usługi sieci Web XML do klienta i z powrotem. Zestaw danych jest niejawnie konwertowany na strumień XML przy użyciu formatu DiffGram, wysyłanego przez sieć, a następnie rekonstruowanego ze strumienia XML jako elementu DataSet na końcu odbierania. Zapewnia to prostą i elastyczną metodę przesyłania i zwracania danych relacyjnych przy użyciu usług sieci Web XML. Aby uzyskać więcej informacji na temat formatu DiffGram, zobacz DiffGrams.
W poniższym przykładzie pokazano, jak utworzyć usługę sieci Web XML i klienta, która używa zestawu danych do transportu danych relacyjnych (w tym zmodyfikowanych danych) i usuwać wszystkie aktualizacje z powrotem do oryginalnego źródła danych.
Uwaga
DataSet
Przesyłanie wystąpień lub DataTable
w ramach wywołań usługi sieci Web XML nie jest bezpieczne, jeśli dane wejściowe nie są zaufane. Aby uzyskać więcej informacji, zobacz DataSet and DataTable security guidance (Wskazówki dotyczące zabezpieczeń zestawu danych i tabeli danych).
Zalecamy również, aby podczas tworzenia usługi sieci Web XML zawsze uwzględniać implikacje dotyczące zabezpieczeń. Aby uzyskać informacje na temat zabezpieczania usługi sieci Web XML, zobacz Zabezpieczanie usług sieci Web XML utworzonych przy użyciu ASP.NET.
Tworzenie usługi internetowej XML
Utwórz usługę sieci Web XML.
W tym przykładzie tworzona jest usługa sieci Web XML, która zwraca dane, w tym przypadku listę klientów z bazy danych Northwind i odbiera zestaw danych z aktualizacjami danych, które usługa sieci Web XML rozpoznaje z powrotem do oryginalnego źródła danych.
Usługa sieci Web XML uwidacznia dwie metody: GetCustomers, aby zwrócić listę klientów i UpdateCustomers, aby rozwiązać problemy z aktualizacjami ze źródłem danych. Usługa sieci Web XML jest przechowywana w pliku na serwerze sieci Web o nazwie DataSetSample.asmx. Poniższy kod przedstawia zawartość pliku DataSetSample.asmx.
<% @ WebService Language = "vb" Class = "Sample" %> Imports System Imports System.Data Imports System.Data.SqlClient Imports System.Web.Services <WebService(Namespace:="http://microsoft.com/webservices/")> _ Public Class Sample Public connection As SqlConnection = New SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind") <WebMethod( Description := "Returns Northwind Customers", EnableSession := False )> _ Public Function GetCustomers() As DataSet Dim adapter As SqlDataAdapter = New SqlDataAdapter( _ "SELECT CustomerID, CompanyName FROM Customers", connection) Dim custDS As DataSet = New DataSet() adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey adapter.Fill(custDS, "Customers") Return custDS End Function <WebMethod( Description := "Updates Northwind Customers", EnableSession := False )> _ Public Function UpdateCustomers(custDS As DataSet) As DataSet Dim adapter As SqlDataAdapter = New SqlDataAdapter() adapter.InsertCommand = New SqlCommand( _ "INSERT INTO Customers (CustomerID, CompanyName) " & _ "Values(@CustomerID, @CompanyName)", connection) adapter.InsertCommand.Parameters.Add( _ "@CustomerID", SqlDbType.NChar, 5, "CustomerID") adapter.InsertCommand.Parameters.Add( _ "@CompanyName", SqlDbType.NChar, 15, "CompanyName") adapter.UpdateCommand = New SqlCommand( _ "UPDATE Customers Set CustomerID = @CustomerID, " & _ "CompanyName = @CompanyName WHERE CustomerID = " & _ @OldCustomerID", connection) adapter.UpdateCommand.Parameters.Add( _ "@CustomerID", SqlDbType.NChar, 5, "CustomerID") adapter.UpdateCommand.Parameters.Add( _ "@CompanyName", SqlDbType.NChar, 15, "CompanyName") Dim parameter As SqlParameter = _ adapter.UpdateCommand.Parameters.Add( _ "@OldCustomerID", SqlDbType.NChar, 5, "CustomerID") parameter.SourceVersion = DataRowVersion.Original adapter.DeleteCommand = New SqlCommand( _ "DELETE FROM Customers WHERE CustomerID = @CustomerID", _ connection) parameter = adapter.DeleteCommand.Parameters.Add( _ "@CustomerID", SqlDbType.NChar, 5, "CustomerID") parameter.SourceVersion = DataRowVersion.Original adapter.Update(custDS, "Customers") Return custDS End Function End Class
<% @ WebService Language = "C#" Class = "Sample" %> using System; using System.Data; using System.Data.SqlClient; using System.Web.Services; [WebService(Namespace="http://microsoft.com/webservices/")] public class Sample { public SqlConnection connection = new SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind"); [WebMethod( Description = "Returns Northwind Customers", EnableSession = false )] public DataSet GetCustomers() { SqlDataAdapter adapter = new SqlDataAdapter( "SELECT CustomerID, CompanyName FROM Customers", connection); DataSet custDS = new DataSet(); adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; adapter.Fill(custDS, "Customers"); return custDS; } [WebMethod( Description = "Updates Northwind Customers", EnableSession = false )] public DataSet UpdateCustomers(DataSet custDS) { SqlDataAdapter adapter = new SqlDataAdapter(); adapter.InsertCommand = new SqlCommand( "INSERT INTO Customers (CustomerID, CompanyName) " + "Values(@CustomerID, @CompanyName)", connection); adapter.InsertCommand.Parameters.Add( "@CustomerID", SqlDbType.NChar, 5, "CustomerID"); adapter.InsertCommand.Parameters.Add( "@CompanyName", SqlDbType.NChar, 15, "CompanyName"); adapter.UpdateCommand = new SqlCommand( "UPDATE Customers Set CustomerID = @CustomerID, " + "CompanyName = @CompanyName WHERE CustomerID = " + "@OldCustomerID", connection); adapter.UpdateCommand.Parameters.Add( "@CustomerID", SqlDbType.NChar, 5, "CustomerID"); adapter.UpdateCommand.Parameters.Add( "@CompanyName", SqlDbType.NChar, 15, "CompanyName"); SqlParameter parameter = adapter.UpdateCommand.Parameters.Add( "@OldCustomerID", SqlDbType.NChar, 5, "CustomerID"); parameter.SourceVersion = DataRowVersion.Original; adapter.DeleteCommand = new SqlCommand( "DELETE FROM Customers WHERE CustomerID = @CustomerID", connection); parameter = adapter.DeleteCommand.Parameters.Add( "@CustomerID", SqlDbType.NChar, 5, "CustomerID"); parameter.SourceVersion = DataRowVersion.Original; adapter.Update(custDS, "Customers"); return custDS; } }
W typowym scenariuszu metoda UpdateCustomers zostanie napisana w celu przechwycenia optymistycznych naruszeń współbieżności. Dla uproszczenia przykład nie zawiera tego. Aby uzyskać więcej informacji na temat optymistycznej współbieżności, zobacz Optymistyczna współbieżność.
Utwórz serwer proxy usługi sieci Web XML.
Klienci usługi sieci Web XML wymagają serwera proxy protokołu SOAP w celu korzystania z uwidocznionych metod. Możesz wygenerować ten serwer proxy przez program Visual Studio. Ustawiając odwołanie sieci Web do istniejącej usługi sieci Web z poziomu programu Visual Studio, wszystkie zachowania opisane w tym kroku są wykonywane w sposób niewidoczny. Jeśli chcesz samodzielnie utworzyć klasę serwera proxy, kontynuuj tę dyskusję. W większości przypadków jednak utworzenie klasy serwera proxy dla aplikacji klienckiej przy użyciu programu Visual Studio jest wystarczające.
Serwer proxy można utworzyć przy użyciu narzędzia do opisu usług sieci Web. Jeśli na przykład usługa sieci Web XML jest uwidoczniona pod adresem URL
http://myserver/data/DataSetSample.asmx
, wydaj polecenie, takie jak poniżej, aby utworzyć serwer proxy platformy .NET języka Visual Basic z przestrzenią nazw WebData.DSSample i zapisać go w pliku sample.vb.wsdl /l:VB -out:sample.vb http://myserver/data/DataSetSample.asmx /n:WebData.DSSample
Aby utworzyć serwer proxy języka C# w sample.cs pliku, wydaj następujące polecenie.
wsdl -l:CS -out:sample.cs http://myserver/data/DataSetSample.asmx -n:WebData.DSSample
Serwer proxy można następnie skompilować jako bibliotekę i zaimportować do klienta usługi sieci Web XML. Aby skompilować kod serwera proxy platformy .NET języka Visual Basic przechowywany w sample.vb jako sample.dll, wydaj następujące polecenie.
vbc -t:library -out:sample.dll sample.vb -r:System.dll -r:System.Web.Services.dll -r:System.Data.dll -r:System.Xml.dll
Aby skompilować kod serwera proxy języka C# przechowywany w sample.cs jako sample.dll, wydaj następujące polecenie.
csc -t:library -out:sample.dll sample.cs -r:System.dll -r:System.Web.Services.dll -r:System.Data.dll -r:System.Xml.dll
Utwórz klienta usługi sieci Web XML.
Jeśli chcesz, aby program Visual Studio wygenerował klasę serwera proxy usługi sieci Web, po prostu utwórz projekt klienta, a następnie w oknie Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt, a następnie wybierz polecenie Dodaj>odwołanie do usługi. W oknie dialogowym Dodawanie odwołania do usługi wybierz pozycję Zaawansowane, a następnie wybierz pozycję Dodaj odwołanie do sieci Web. Wybierz usługę sieci Web z listy dostępnych usług sieci Web (może to wymagać podania adresu punktu końcowego usługi sieci Web, jeśli usługa sieci Web nie jest dostępna w bieżącym rozwiązaniu lub na bieżącym komputerze). Jeśli samodzielnie utworzysz serwer proxy usługi sieci Web XML (zgodnie z opisem w poprzednim kroku), możesz zaimportować go do kodu klienta i użyć metod usługi sieci Web XML.
Poniższy przykładowy kod importuje bibliotekę proxy, wywołuje metodę GetCustomers, aby uzyskać listę klientów, dodaje nowego klienta, a następnie zwraca element DataSet z aktualizacjami updateCustomers.
Przykład przekazuje element DataSet zwrócony przez element DataSet.GetChanges do elementu UpdateCustomers, ponieważ do elementów UpdateCustomers należy przekazać tylko zmodyfikowane wiersze. Funkcja UpdateCustomers zwraca rozpoznany zestaw danych, który można następnie scalić z istniejącym zestawem danych, aby uwzględnić rozwiązane zmiany i wszelkie informacje o błędzie wiersza z aktualizacji. Poniższy kod zakłada, że użyto programu Visual Studio do utworzenia odwołania do sieci Web i zmieniono nazwę odwołania do sieci Web na DsSample w oknie dialogowym Dodawanie odwołania do sieci Web.
Imports System Imports System.Data Public Class Client Public Shared Sub Main() Dim proxySample As New DsSample.Sample () ' Proxy object. Dim customersDataSet As DataSet = proxySample.GetCustomers() Dim customersTable As DataTable = _ customersDataSet.Tables("Customers") Dim rowAs DataRow = customersTable.NewRow() row("CustomerID") = "ABCDE" row("CompanyName") = "New Company Name" customersTable.Rows.Add(row) Dim updateDataSet As DataSet = _ proxySample.UpdateCustomers(customersDataSet.GetChanges()) customersDataSet.Merge(updateDataSet) customersDataSet.AcceptChanges() End Sub End Class
using System; using System.Data; public class Client { public static void Main() { Sample proxySample = new DsSample.Sample(); // Proxy object. DataSet customersDataSet = proxySample.GetCustomers(); DataTable customersTable = customersDataSet.Tables["Customers"]; DataRow row = customersTable.NewRow(); row["CustomerID"] = "ABCDE"; row["CompanyName"] = "New Company Name"; customersTable.Rows.Add(row); DataSet updateDataSet = new DataSet(); updateDataSet = proxySample.UpdateCustomers(customersDataSet.GetChanges()); customersDataSet.Merge(updateDataSet); customersDataSet.AcceptChanges(); } }
Jeśli zdecydujesz się samodzielnie utworzyć klasę serwera proxy, musisz wykonać następujące dodatkowe kroki. Aby skompilować przykład, podaj bibliotekę serwera proxy, która została utworzona (sample.dll) i powiązane biblioteki platformy .NET. Aby skompilować wersję przykładu programu Visual Basic dla platformy .NET, zapisaną w pliku client.vb, wydaj następujące polecenie.
vbc client.vb -r:sample.dll -r:System.dll -r:System.Data.dll -r:System.Xml.dll -r:System.Web.Services.dll
Aby skompilować wersję przykładu w języku C#, zapisaną w pliku client.cs, wydaj następujące polecenie.
csc client.cs -r:sample.dll -r:System.dll -r:System.Data.dll -r:System.Xml.dll -r:System.Web.Services.dll