title: TableAdapter and Unicode?
body: <p>Working with Microsoft Visual Studio 2010 Professional, using C#, with Microsoft SQL Server 2008.</p>
  
  <p>I have been tasked with taking an existing application, and making changes so that it can receive multiple languages in its text boxes without needing to configure ahead of time what language is to be used.</p>
  
  <p>To ensure that I am doing this correctly, I have created a new table in the database, called Language.  If I can get things working correctly with [Language], I should be able to get it all working.  The field in question is <code>MotherTongueLanguageName</code>:</p>
  
  <pre><code>CREATE TABLE [Language](
  [LanguageID] [tinyint] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
  [LanguageName] [varchar](30) NOT NULL,
  [MotherTongueLanguageName] [nvarchar](30) NOT NULL)
  </code></pre>
  
  <p>I preload the table with content:</p>
  
  <pre><code>TRUNCATE TABLE [dbo].[Language]
  SET NOCOUNT ON
  INSERT INTO [Language] VALUES ('English','English') -- 1
  INSERT INTO [Language] VALUES ('French','Français') -- 2
  INSERT INTO [Language] VALUES ('Spanish','Español') -- 3
  SET NOCOUNT OFF
  GO
  </code></pre>
  
  <p>And on my web page, it all looks perfect.  When I try to enter Russian and <code>русский</code> from the web page, it hits the database with <code>???????</code> in the <code>MotherTongueLanguageName</code>.  I want to be able to do this without setting a specific culture or uiCulture, if possible.</p>
  
  <p>I have already edited my MasterPage.master file and have added <code>&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;</code> to the <code>&lt;head&gt;</code>, and <code>accept-charset="utf-8"</code> to the <code>&lt;form&gt;</code> tag.</p>
  
  <p>I have even added <code>Content-Type: text/html; charset=utf-8</code> to the Custom HTTP headers in IIS, thought I'm hoping that's not actually necessary.</p>
  
  <p>The web page does use a TableAdapter to connect the grids and entry fields to the database, and I'm wondering if there's anything in there that's reverting my Unicode text back to ASCII.</p>
  
  <p>Any help would be appreciated.  I'm fresh out of guesses, and Google has helped me just about as much as it can with the search terms I've been using.</p>
  
  <p>-- New Info --</p>
  
  <p>All of my web page -> Database linkages are stored in a file called DBDataSet.xsd.  When I right-click on an empty area within this form, I get the option to Add -> TableAdapter...  When I do this, I get a wizard that walks me through <code>Choose Your Data Connection</code>, then <code>Choose a Command Type</code> (I choose <code>Use existing stored procedures</code>), then <code>Bind Commands to Existing Stored Procedures</code>.  I select my Select, Insert, Update and Delete sprocs, each of which accept as parameters both VarChar and NVarChar data for the appropriate columns.  It then takes me to <code>Choose Methods to Generate</code>, and I select both <code>Fill a DataTable</code> and <code>Return a DataTable</code>.</p>
  
  <p>All of this happens automatically, and a bunch of code is generated behind-the-scenes.  When I search the DBDataSet.Designer.cs file for references to <code>MotherTongueLanguageName</code>, I don't see any code that differentiates it from other columns that are just VarChars.  For example:</p>
  
  <pre><code>[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
      private void InitClass() {
          this.columnLanguageName = new global::System.Data.DataColumn("LanguageName", typeof(string), null, global::System.Data.MappingType.Element);
          base.Columns.Add(this.columnLanguageName);
          this.columnLanguageID = new global::System.Data.DataColumn("LanguageID", typeof(byte), null, global::System.Data.MappingType.Element);
          base.Columns.Add(this.columnLanguageID);
          this.columnLanguageAbbrev = new global::System.Data.DataColumn("LanguageAbbrev", typeof(string), null, global::System.Data.MappingType.Element);
          base.Columns.Add(this.columnLanguageAbbrev);
          this.columnMotherTongueLanguageName = new global::System.Data.DataColumn("MotherTongueLanguageName", typeof(string), null, global::System.Data.MappingType.Element);
          base.Columns.Add(this.columnMotherTongueLanguageName);
          this.columnLanguageColour = new global::System.Data.DataColumn("LanguageColour", typeof(string), null, global::System.Data.MappingType.Element);
          base.Columns.Add(this.columnLanguageColour);
          this.Constraints.Add(new global::System.Data.UniqueConstraint("Constraint1", new global::System.Data.DataColumn[] {
                          this.columnLanguageID}, true));
          this.columnLanguageName.AllowDBNull = false;
          this.columnLanguageName.MaxLength = 30;
          this.columnLanguageID.AllowDBNull = false;
          this.columnLanguageID.ReadOnly = true;
          this.columnLanguageID.Unique = true;
          this.columnLanguageAbbrev.AllowDBNull = false;
          this.columnLanguageAbbrev.MaxLength = 3;
          this.columnMotherTongueLanguageName.AllowDBNull = false;
          this.columnMotherTongueLanguageName.MaxLength = 30;
          this.columnLanguageColour.MaxLength = 10;
      }
  </code></pre>
  
  <p>Both <code>LanguageName</code> and <code>MotherTongueLanguageName</code> use <code>typeof(string)</code>, even though one is a VarChar, and the other is an NVarChar.  Is this correct?</p>
  
  <p>Also:</p>
  
  <pre><code>    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
      private void InitAdapter() {
          this._adapter = new global::System.Data.SqlClient.SqlDataAdapter();
          global::System.Data.Common.DataTableMapping tableMapping = new global::System.Data.Common.DataTableMapping();
          tableMapping.SourceTable = "Table";
          tableMapping.DataSetTable = "GetLanguages";
          tableMapping.ColumnMappings.Add("LanguageName", "LanguageName");
          tableMapping.ColumnMappings.Add("LanguageID", "LanguageID");
          tableMapping.ColumnMappings.Add("LanguageAbbrev", "LanguageAbbrev");
          tableMapping.ColumnMappings.Add("MotherTongueLanguageName", "MotherTongueLanguageName");
          tableMapping.ColumnMappings.Add("LanguageColour", "LanguageColour");
          this._adapter.TableMappings.Add(tableMapping);
          this._adapter.DeleteCommand = new global::System.Data.SqlClient.SqlCommand();
          this._adapter.DeleteCommand.Connection = this.Connection;
          this._adapter.DeleteCommand.CommandText = "dbo.DeleteLanguage";
          this._adapter.DeleteCommand.CommandType = global::System.Data.CommandType.StoredProcedure;
          this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@RETURN_VALUE", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.ReturnValue, 10, 0, null, global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@LanguageID", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.Input, 10, 0, "LanguageID", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.InsertCommand = new global::System.Data.SqlClient.SqlCommand();
          this._adapter.InsertCommand.Connection = this.Connection;
          this._adapter.InsertCommand.CommandText = "dbo.AddLanguage";
          this._adapter.InsertCommand.CommandType = global::System.Data.CommandType.StoredProcedure;
          this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@RETURN_VALUE", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.ReturnValue, 10, 0, null, global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@LanguageName", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@LanguageAbbrev", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageAbbrev", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@MotherTongueLanguageName", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "MotherTongueLanguageName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@LanguageColour", global::System.Data.SqlDbType.VarChar, 10, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageColour", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand = new global::System.Data.SqlClient.SqlCommand();
          this._adapter.UpdateCommand.Connection = this.Connection;
          this._adapter.UpdateCommand.CommandText = "dbo.EditLanguage";
          this._adapter.UpdateCommand.CommandType = global::System.Data.CommandType.StoredProcedure;
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@RETURN_VALUE", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.ReturnValue, 10, 0, null, global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@OldLanguageID", global::System.Data.SqlDbType.Int, 4, global::System.Data.ParameterDirection.Input, 10, 0, "LanguageID", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@OldLanguageName", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@OldLanguageAbbrev", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageAbbrev", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@OldMotherTongueLanguageName", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "MotherTongueLanguageName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@OldLanguageColour", global::System.Data.SqlDbType.VarChar, 10, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageColour", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@NewLanguageName", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@NewLanguageAbbrev", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageAbbrev", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@NewMotherTongueLanguageName", global::System.Data.SqlDbType.VarChar, 30, global::System.Data.ParameterDirection.Input, 0, 0, "MotherTongueLanguageName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
          this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@NewLanguageColour", global::System.Data.SqlDbType.VarChar, 10, global::System.Data.ParameterDirection.Input, 0, 0, "LanguageColour", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
      }
  </code></pre>
  
  <p>Shouldn't the generated code be referencing <code>global::System.Data.SqlDbType.NVarChar</code> instead of <code>global::System.Data.SqlDbType.VarChar</code>?  If I make these changes directly to the generated code, the changes get blown away as soon as I even refresh the DBDataSet.xsd file.</p>
  
  <p>This is an existing project, so I need to continue with the manner by which data is fetched from and put to the database.  What do I need to do to get the data from the webpage, through the TableAdapter, to the database correctly?</p>