Remote DateTime-Werte in ein DataSet-Objekt werden in die entsprechende Ortszeit eines Remotecomputers konvertiert, die sich in einer anderen Zeitzone befindet

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 842545 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

, wenn Sie ein Objekt der DataSet-Klasse an eine remote-Webdienst oder an einen Webdienst, übergeben in einer Zeitzone, die sich von der Zeitzone der aufrufenden Anwendung unterscheidet, die DateTime-Spalten in einer Tabelle enthaltenen werden an die entsprechende lokale Zeit konvertiert. Die DateTime-Spalten werden konvertiert, da der System.Data.DataSet-Code in die entsprechende lokale Zeit entsprechend an die Zeitzone des Remotecomputers passt. Wenn der Wert 5: 00 von einem Clientcomputer in Pacific an einen Webdienst in Eastern übergeben wird, ändert der Wert in das DataSet-Objekt beispielsweise 8: 00 Uhr in der empfangenden Methode den Webdienst. Dieser Artikel beschreibt wie Sie dieses Problem umgehen können, indem die Zeitzoneninformationen aus der Clientanwendung an den Webdienst übergeben und Anpassen der DateTime-Spalten auf dem Remotecomputer. Der System.Data ist der Namespace, die die DataSet-class. enthält

Problembeschreibung

Die Werte des DateTime-Spalten ändern, wenn Sie ein System.Data.DataSet -Objekt an einen Webdienst oder an einen remote-Webdienst übergeben. Dieses Problem tritt auf, wenn Ihr Webdienst oder remote-Webdienst in einer anderen Zeitzone als der Client-Anwendung ist. Die Werte in den DateTime-Spalten werden in die entsprechende lokale Zeit entsprechend an die Zeitzone des Remotecomputers konvertiert.

Ursache

Die Zeitzone der Client-Anwendung wird während der Serialisierung der DataSet -Objekt gespeichert. Das DataSet -Objekt wird am empfangenden Ende deserialisiert und der System.Data.DataSet -Code passt die DateTime-Spalten, die entsprechende lokale Zeit des Remotecomputers, die sich in einer anderen Zeitzone befindet.

Abhilfe

Um dieses Problem zu umgehen, müssen Sie Informationen über die Zeitzone übergeben, wenn das DataSet -Objekt in der Clientanwendung erstellt wird und anschließend Sie das DataSet -Objekt anpassen, müssen nach dem Eintreffen in dem aufgerufenen Prozess auf dem Remotecomputer. Gehen Sie hierzu folgendermaßen vor:
  1. Schreiben Sie in der Webdienstprojekt auf dem Remotecomputer Code, der die Werte DateTime entsprechend der Zeitzone der Clientanwendung passt. Gehen Sie hierzu folgendermaßen vor:
    1. Fügen Sie den folgenden Code in der Service1 -Klasse wie angegeben im Abschnitt "Erstellen ein Webdienstes":
      [WebMethod]
      public string AdjustDSTimeZone( DataSet dataSet ) 
      {
      
       // Obtains the time difference on the sender computer that
       //remoted this dataset to the Web service.
       string str;	
       string sourceTicksString = dataSet.ExtendedProperties["UTCDifference"].ToString();
       long sourceTicks = long.Parse( sourceTicksString );
       // Obtain the UTC offset for the remote computer.
       DateTime baseUTC = DateTime.Now;
       long UtcTickslocal = TimeZone.CurrentTimeZone.GetUtcOffset( baseUTC ).Ticks;
       // Obtain the time difference between the sender computer and the remote computer.
       long ticksDifference = sourceTicks - UtcTickslocal;
       TimeSpan timespan = new TimeSpan( ticksDifference );
       
       // The following code iterates through each table, and find all the columns that are 
       // DateTime columns. After identifying the columns that have to be adjusted,
       // it traverses the data in the table and adjusts the DateTime columns back to their 
       // original values. You must leave the RowState of the DataRow in the same state 
       //after making the adjustments.
       foreach( DataTable table in dataSet.Tables ) 
       {
        DataColumnCollection columns = table.Columns;
        int[] ColumnNumbers = new int[columns.Count];
        int   ColumnNumbersIndex = 0;
        for( int i = 0; i < columns.Count; i++ ) 
        {
         DataColumn col = columns[i];
         if ( col.DataType == typeof( DateTime ) ) 
         {	
       	ColumnNumbers[ColumnNumbersIndex] = i;
      	ColumnNumbersIndex++;
         }
       }
       foreach( DataRow row in table.Rows ) 
       {
        switch ( row.RowState ) 
        {
         case DataRowState.Unchanged:
          AdjustDateTimeValues( row, ColumnNumbers,
          ColumnNumbersIndex, timespan );
          row.AcceptChanges();	// This is to make sure that the
          // row appears to be unchanged again.
          Debug.Assert( row.RowState == DataRowState.Unchanged );
          break;
         case DataRowState.Added:
          AdjustDateTimeValues( row, ColumnNumbers, ColumnNumbersIndex, timespan );
          // The row is still in a DataRowState.Added state.
          Debug.Assert( row.RowState == DataRowState.Added );
           break;
         case DataRowState.Modified:
           AdjustDateTimeValues( row, ColumnNumbers, ColumnNumbersIndex, timespan );
          // The row is a still DataRowState.Modified.
          Debug.Assert( row.RowState == DataRowState.Modified );
          break;
         case DataRowState.Deleted:
          //   This is to make sure that you obtain the right results if 
          //the .RejectChanges()method is called.
          row.RejectChanges();	// This is to "undo" the delete.
          AdjustDateTimeValues( row, ColumnNumbers, ColumnNumbersIndex, timespan );	
          // To adjust the datatime values.
          // The row is now in DataRowState.Modified state.
          Debug.Assert( row.RowState == DataRowState.Modified );
          row.AcceptChanges();	// This is to mark the changes as permanent.
          Debug.Assert( row.RowState == DataRowState.Unchanged );
          row.Delete();			
          // Delete the row. Now, it has the same state as it started.
          Debug.Assert( row.RowState == DataRowState.Deleted );
          break;
          default:
          throw new ApplicationException
          ( "You must add a case statement that handles the new version of the dataset." );
         }
        }
       } 
       str=dataSet.Tables["MyTable"].Rows[0][1].ToString() ; 
       return str;
      }
      
      die AdjustDSTimeZone -Methode passt die DateTime -Werte, der Clientanwendung die ursprüngliche Uhrzeit widerspiegeln. Hier ExtendedProperties -Eigenschaft des DataSet -Klasse wird verwendet, um den Coordinated Universal Time (UTC)-Offset mit dem DataSet -Objekt zu speichern. Mit der ExtendedProperties -Eigenschaft können Sie benutzerdefinierten Informationen mit dem DataSet -Objekt speichern. Wenn das DataSet -Objekt Remote gesteuert werden soll, müssen Sie den UTC-Offset als Zeichenfolge in ExtendedProperties speichern-Auflistung.
    2. Fügen Sie folgenden Code unter AdjustDSTimeZone -Methode:
      void AdjustDateTimeValues( DataRow row, int[] ColumnNumbers, int columnCount, TimeSpan timespan) 
      {
        for ( int i = 0; i < columnCount; i++ ) 
        {
      	int columnIndex = ColumnNumbers[i];
      	DateTime original = (DateTime)row[columnIndex];
      	DateTime modifiedDateTime = original.Add(timespan);
      	row[columnIndex] = modifiedDateTime;
        }
      }
    3. Klicken Sie im Menü Datei auf Alles speichern , die Anwendung zu speichern.
    4. Klicken Sie im Erstellen auf Projektmappe , um die Anwendung zu erstellen.
    Die AdjustDateTimeValues -Methode macht die Anpassung an das DateTime -Objekt. Es erhält die ursprüngliche Uhrzeit aus der DateTime-Spalte einer bestimmten Zeile und dann entsprechend in die Ortszeit der Clientanwendung ändert.
  2. Schreiben Sie Code, der überprüft, dass der Webdienst die Zeitzoneninformationen angepasst hat, in der Clientanwendung. Gehen Sie hierzu folgendermaßen vor:
    1. Fügen Sie den folgenden Code in die Main -Funktion nach dem Code, der in den Abschnitt "Erstellen eine Clientanwendung" angegeben ist:
      str=myDatasetService.AdjustDSTimeZone(myDataset );
      Console.WriteLine (str);
      Console.ReadLine ();
    2. Erweitern Sie im Projektmappen-Explorer alle Ordner.
    3. Klicken Sie mit der rechten Maustaste auf WebReference1 , und klicken Sie dann auf Webverweis aktualisieren .
    4. Klicken Sie im Menü Datei auf Alles speichern , die Anwendung zu speichern.
    5. Klicken Sie im Erstellen auf Projektmappe , um die Anwendung zu erstellen.
    6. Klicken Sie im Debug auf Starten , um die Anwendung auszuführen.
Die Client-Anwendung verbindet sich mit der MyTable-Tabelle, die eine DateTime-Spalte enthält. Er erstellt ein Objekt des Webdienstes und übergibt ein Objekt der DataSet -Klasse an die AdjustDSTimeZone -Methode des Web Service. Die AdjustDSTimeZone -Methode im Webdienst aktualisiert die DateTime Spalte von der MyTable Tabelle entsprechend auf die Zeitzone des Client-Anwendung und dann gibt den DateTime-Wert der ersten Zeile der Tabelle "MyTable". Der DateTime -Wert, die von der Clientanwendung empfangen wird entspricht der Wert, durch die Clientanwendung im Web übergeben, Dienst.

Status

Es handelt sich hierbei um ein beabsichtigtes Verhalten.

Weitere Informationen

Schritte zum Reproduzieren des Problems

Erstellen Sie eine Datenbanktabelle

Zum Erstellen einer Datenbanktabelle in einer Instanz von Microsoft SQL Server, gehen Sie folgendermaßen vor:
  1. Starten Sie SQL Query Analyzer.
  2. Klicken Sie im Menü Datei auf neu .
  3. Klicken Sie auf Leeres Abfragefenster , und klicken Sie dann auf OK .
  4. Fügen Sie den folgenden Code in das Abfragefenster. Dieser Code erstellt die MyTable-Tabelle.
    CREATE  TABLE MyTable (
    
                [ID] [int] NOT NULL ,
    
                [DateTimeCol] [datetime] NOT NULL 
    
    ) ON [PRIMARY]
    
    Go
    Insert into MyTable Values (1, '2004-05-19 15:00:00.000')
    Go
    
    Insert into MyTable Values (2, '2004-05-19 13:00:00.000')
    Go
    
    
  5. Klicken Sie im Abfrage auf Ausführen , um die Abfrage auszuführen. Die MyTable Tabelle erstellt, und die Tabelle wird mit zwei Werten aktualisiert.

Erstellen Sie einen Webdienst

Erstellen Sie ein Webdienstprojekt auf einem Remotecomputer, der die DateTime -Werte von einer Clientanwendung empfängt. Gehen Sie hierzu folgendermaßen vor:
  1. Starten Sie Microsoft Visual Studio .NET.
  2. Zeigen im Menü Datei auf neu , und klicken Sie dann auf Projekt .
  3. Klicken Sie unter Projekttypen auf Visual C#-Projekte und klicken Sie dann unter Vorlagen auf ASP.NET-Webdienst .
  4. Geben Sie in das Feld Name MyWebService und klicken Sie dann auf OK . Standardmäßig ist die Datei Service1.asmx erstellt.
  5. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei Service1.asmx , und klicken Sie dann auf Code anzeigen .
  6. Fügen Sie den folgenden Code am Anfang der Datei:
    using System.Data.SqlClient;
    using System.Timers;
  7. Suchen Sie den folgenden Code in der Service1 -Klasse:
    public class Service1 : System.Web.Services.WebService
    {
  8. Fügen Sie den folgenden Code nach den Code, das Sie in Schritt 7:
    [WebMethod]
    public String DataSetReturn( DataSet clientDataSet )
    {
      string str;				
      str=clientDataSet.Tables["MyTable"].Rows[0][1].ToString() ;
      return str;	
    }
    die DataSetReturn -Methode empfängt ein Objekt für den DataSet , der durch die Clientanwendung übergeben wird. Diese Methode gibt den DateTime -Wert der ersten Zeile der Tabelle "MyTable" an die Clientanwendung zurück.
  9. Klicken Sie im Menü Datei auf Alles speichern , die Anwendung zu speichern.
  10. Klicken Sie im Menü Erstellen auf Erstellen Projektmappen zum Erstellen der Anwendung.

Erstellen einer Clientanwendung

Um eine Clientanwendung erstellen, die ein DataSet -Objekt an den remote-Webdienst übergeben wird, gehen Sie folgendermaßen vor:
  1. Starten Sie Microsoft Visual Studio .NET.
  2. Zeigen im Menü Datei auf neu , und klicken Sie dann auf Projekt .
  3. Klicken Sie unter Projekttypen auf Visual C#-Projekte und klicken Sie dann unter Vorlagen auf Konsolenanwendung .
  4. Geben Sie in das Feld Name MyDataSet und klicken Sie dann auf OK . Die Datei Class1.cs wird standardmäßig erstellt.
  5. Fügen Sie den folgenden Code am Anfang der Datei:
    using System.Data;
    using System.Data.SqlClient;
    using System.Timers;
    using System.Diagnostics;
  6. Fügen Sie den folgenden Code in die Main -Funktion:
    string auth="Server=YourServer;Database=YourDatabase;User ID=YourUserID;password=YourPassword";
    WebReference1.Service1 myDatasetService = new WebReference1.Service1();
    DataSet myDataset = new DataSet();
    SqlDataAdapter da = new SqlDataAdapter("Select * From MyTable",auth);
    da.Fill(myDataset, "MyTable");
    //Modify first row to have the current time.
    myDataset.Tables["MyTable"].Rows[0][1] = DateTime.Now;
    string str=myDataset.Tables["MyTable"].Rows[0][1].ToString() ;
    System.Console.WriteLine(str);
    //Store the ticks from UTC in the ExtendedProperties collection of the DataSet
    DateTime clientDateTime = DateTime.Now;
    myDataset.ExtendedProperties["UTCDifference"] = TimeZone.CurrentTimeZone.GetUtcOffset
    ( clientDateTime ).Ticks.ToString();    
    str= myDatasetService.DataSetReturn(myDataset );
    Console.WriteLine (str);
    Console.ReadLine ();
    
    Hinweis auf die MyTable zuzugreifen Tabelle, müssen Sie die Informationen des Servers und die Datenbankinformationen zusammen mit den Benutzernamen und das Kennwort für das Herstellen der Verbindung mit Microsoft SQL Server ändern.
  7. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Verweise , und klicken Sie die Hinzufügen .
  8. Geben Sie im Feld URL http:// RemoteServer /MyWebService/Service1.asmx , und klicken Sie dann auf OK . Standardmäßig in Visual Studio .NET 2002, ein Web Verweis mit dem Namen WebReference1 erstellt wird.

    Hinweis: RemoteServer ist ein Platzhalter für den Namen des Remoteservers, in dem der Webdienst erstellt wird.
  9. Geben Sie in Microsoft Visual Studio .NET 2003 WebReference1 im Webverweisname Feld. Hier wird WebReference1 verwendet, um die Codesyntax übereinstimmen.
  10. Klicken Sie auf Verweis hinzufügen .
  11. Klicken Sie im Menü Datei auf Alles speichern , die Anwendung zu speichern.
  12. Klicken Sie im Menü Erstellen auf Erstellen Projektmappen zum Erstellen der Anwendung.
  13. Klicken Sie im Debug auf Starten , um die Anwendung auszuführen.
Die Client-Anwendung ändert die DateTime-Spalte der ersten Zeile. Der Code legt den DateTime -Wert auf das aktuelle Datum und die Uhrzeit der Client-Anwendung fest. Ein DataSet -Objekt übergeben an den Webdienst. Der Webdienst empfängt das DataSet -Objekt, aus der ersten Zeile der Wert der DateTime-Spalte abgerufen und dann der Wert an die Clientanwendung zurückgegeben. Durch den Webdienst zurückgegebene DateTime -Wert wurde entsprechend, wird die Zeitzoneninformationen des Remoteservers als in "Problembeschreibung" Abschnitt.

.NET Framework remoting

Wenn Sie die .NET Framework Remoting-Dienste in Ihrer Anwendung implementieren, und Sie eine .NET Framework-Service-Methode nicht rufen, können Sie den Klassencode DataSetSurrogate .Weitere Informationen über die DataSetSurrogate-Klasse finden Sie die folgende KB-Artikelnummer:
829740Verbessern der Leistung Serialisierung und Remoting von DataSet
Die DataSetSurrogate -Klasse verhindert, dass die lokale Zeit Zone Regulierungen für die DateTime-Spalten. Diese Klasse bietet auch eine bessere Leistung bei .NET Framework Remoting. Die DataSetSurrogate -Klasse überschreibt die Standardserialisierung der DataSet -Klasse und der DataSetSurrogate -Klasse und Ihre enthaltenen Member in binärer Form serialisiert.

Informationsquellen

Informationen finden Sie auf den folgenden Websites von Microsoft Developer Network (MSDN):
System.Data.SqlClient-Namespace
http://msdn2.microsoft.com/en-us/library/system.data.sqlclient(vs.71).aspx
DataSet.ExtendedProperties-Eigenschaft
http://msdn2.microsoft.com/en-us/library/system.data.dataset.extendedproperties(vs.71).aspx

Eigenschaften

Artikel-ID: 842545 - Geändert am: Freitag, 18. Mai 2007 - Version: 1.5
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Keywords: 
kbmt kbtshoot kbwebservices kbremoting kbclient kbsystemdata kbsqlclient kbservice kbprb KB842545 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 842545
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.

Ihr Feedback an uns

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com