Silverlight に MySQL からデータを取得させる方法
-
01-07-2019 - |
質問
Linux/Apache2サーバーでホストしたい小さなHello WorldテストアプリをSilverlightで作成しました。データベース内のデータにデータバインドできるように、データを MySQL (または他の Linux 互換データベース) から取得したいと考えています。
を使用してなんとか動作させることができました MySQL コネクタ/.NET:
MySqlConnection conn = new MySqlConnection("Server=the.server.com;Database=theDb;User=myUser;Password=myPassword;");
conn.Open();
MySqlCommand command = new MySqlCommand("SELECT * FROM test;", conn);
using (MySqlDataReader reader = command.ExecuteReader())
{
StringBuilder sb = new StringBuilder();
while (reader.Read())
{
sb.AppendLine(reader.GetString("myColumn"));
}
this.txtResults.Text = sb.ToString();
}
これは、公開された ClickOnce アプリに完全な信頼 (または少なくとも SocketPermission) を与え、 ローカルで実行する.
これをサーバー上で実行したいのですが、動作させることができず、常にアクセス許可例外が発生します (SocketPermission は許可されていません)。
違いがある場合、データベースは Silverlight アプリと同じサーバー上でホストされます。
編集さて、クライアント アプリに db 認証情報を含めるのがなぜ悪い考えなのかがわかりました (当然です)。では人々はどうやってこれを行うのでしょうか?安全な方法でクライアント/データベースとの間でデータを中継できるように、プロキシ Web サービスをどのように保護しますか?ウェブ上に例はありますか?
Silverlight アプリケーションを強化するためにデータベースを使用したいと思うのは私が初めてではないでしょうか?
解決
やりたいことを実現する最も簡単な方法 (今編集内容を読んだ後:)) は、利用できるサービスを公開することです。Microsoft が現在本当に推進しているパターンは、WCF サービスを公開することですが、実際のところ、Silverlight クライアントは WCF を使用してさまざまな種類のサービスを利用できます。
現時点で最も簡単な方法は、Web サーバー上の .NET サービス、または PHP REST サービスを使用し、Silverlight アプリでそのサービスを指定することです。そうすることで、他人によるデータベースの覗き見からデータベースを保護できるだけでなく、さらに重要なことに、他人がデータベースに対してできることを制限することになります。データが読み取り専用であることが想定されており、サービスの契約で読み取り操作のみが許可されている場合は、準備完了です。あるいは、サービスは、WCF を通じてセットアップされた資格情報を使用してセッションをネゴシエートすることもできます。
WCF は、クライアント専用、サーバー専用、またはクライアント/サーバー コネクタ プラットフォームにすることができます。何を選択するかは、作成するコードに影響しますが、それはすべてデータベースから独立しています。コードは、データベース テーブルに 1 対 1 でマッピングするように構造化することも、より抽象的なものにすることもできます (必要に応じて、完全な論理ビューを表すクラスをセットアップできます)。
他のヒント
「公式」の答えは、WCF を使用してサービスを Silverlight にプッシュすることですが、MySQL を使用している人はおそらく完全な ASP.NET ソリューションを使用していないのではないかと私は考えています。私の解決策は、(Rob が提案したように) MySQL データベースと対話する PHP Web サービスを構築し、Silverlight が RESTful な方法でデータベースにアクセスできるようにすることでした。
ここは、Silverlight を使用して PHP Web サービス経由で MySQL データベースにアクセスするための 3 部構成のチュートリアルの始まりです。
Silverlight には、データベース サーバーに直接アクセスする機能がありません。できることは、Web サービス (ASMX または WCF、.NET 以外でも!) を通じてデータベース操作を公開し、Silverlight を使用してそれらのサービスにアクセスすることです。
これでうまくいくようになりました。Linux Ubuntu 10 / Apache2 サーバー上の Silverlight4 コンテンツを含む ASP.NET4 サイト。コンテンツは Visual Studio 2010 を使用して開発されています。VS2008でも問題なく動作するはずです。
サーバ:
- Apache2 と MySQL を使用して Linux サーバーをセットアップします。これに関するガイドはたくさんあります。
- MySQL が開発用 PC からアクセス可能であり、必要に応じてインターネットからもアクセスできることを確認してください。詳細については、こちらを参照してください。 アクセス拒否エラーの原因.
- データベースのテーブル構造をセットアップし、後でテストするためにコンテンツを追加します。この例では、列「name」を持つテーブル「persons」があると仮定します。
- Silverlight はクライアント側のテクノロジであるため、すぐに使用でき、単純な HTML ページでアプリケーションをホストできます。
- Silverlight と MySQL の間に Web サービスが必要です。Microsoft の WCF RIA は 1 つのフレーバーですが、.NET が必要です。プラスの面としては、ASP.NET4 ページもホストできるようになります。これを設定するための詳細なガイドは次のとおりです。 MySql メンバーシップを使用して Ubuntu 上で Asp.Net 4.0 および MVC2 を使用した Mono 2.8 をセットアップする
ビジュアルスタジオ:
- 最新のものをインストールする MySQL コネクタ/ネット そしてVSを再起動します
- MySQL データベースをデータ ソースとして追加します
- サーバー エクスプローラーを開く -> データ接続を追加 -> 「MySQL データベース」を選択します。
- 資格情報を入力して接続をテストします
MySQL アクセスを使用してサイトをセットアップする:
私が役に立ったガイドは次のとおりです。 Entity Framework を使用した WCF RIA 対応 SL4 アプリケーションのステップ バイ ステップ ガイド
- Silverlight プロジェクトを作成するか開きます。
- サーバー側プロジェクトの名前は通常、「ProjectName.Web」です。
- クライアント側プロジェクトの名前は通常「ProjectName」です。
- 「ADO.NET Entity Data Model」をサーバー プロジェクトに追加します。これはデータベース構造のモデルになります。
- 「データベースから生成」を選択します
- 作成した MySQL データベース接続を選択します
- アクセスしたいテーブルを選択します
- 続行する前に、今すぐソリューションを構築してください。
- 「ドメイン サービス クラス」をサーバー プロジェクトに追加します。「フードメイン」。これにより、データベース エンティティをクライアント側の Silverlight コードで使用できるようになります。
- 「使用可能な DataContext/ObjectContext クラス:」で、前の手順で作成した Entity Framework モデルを選択します。
- アクセスしたいエンティティをチェックし、必要に応じて「編集を有効にする」にチェックを入れます
- 「メタデータに関連するクラスを生成する」にチェックを入れます
- ソリューションを再度ビルドして、サーバー プロジェクトの「FooDomain」に基づいて「FooDomainContext」を生成します。
テスト:
MySQL から Silverlight にデータを取得してみましょう。「persons」という名前のテーブルがあり、列名が「name」であると仮定すると、人の名前を表示するリスト ボックスをバインドできます。
まず、Silverlight ページ (「ホーム」としましょう) を追加します。Home.xaml に以下を追加します。
<ListBox x:Name="TestList" Width="100" />
Home.xaml.cs ファイルに次を追加します。
public partial class Home : Page
{
public Home()
{
InitializeComponent();
Loaded += Home_Loaded;
}
void Home_Loaded(object sender, RoutedEventArgs e)
{
var context = new FooDomainContext();
var query = context.Load(context.GetPersonsQuery());
TestList.ItemsSource = query.Entities;
TestList.DisplayMemberPath = "name";
}
}
ここでは、ドメイン サービスに「FooDomain」という名前を付けたと仮定します。これにより、使用される「FooDomainContext」クラスが生成されます。
すべてが適切に設定されていれば、Silverlight プロジェクトを実行するときに人物名のリストが表示されることを願っています。
編集: ASP.NET はオプションではありませんが、この例で使用した WCF RIA Web サービスには必須です。
クライアント側からサーバーに直接 DB 接続を行うことは、通常、悪い考えです。Silverlight アプリを逆コンパイルするのがどれほど簡単かはわかりませんが、何らかの方法で逆コンパイルすることは可能だと思います。そうなると、基本的に DB 認証情報をユーザーに提供することになります。
Web サービスを使用して MySQL からデータを取得できます。
チュートリアル:
ステップ1:Webサービスの作成
ステップ2:Silverlight へのサービス参照の追加
ステップ1:Webサービスの作成
新しい Silverlight プロジェクトを追加します。
新しい Web サービスを作成します。Web プロジェクトを右クリック > [追加] > [新しい項目]
「Webサービス」を選択します。
新しい Web サービスの初期コード。
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
namespace SilverlightApplication1.Web
{
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
}
Web サービスが MySQL に接続できるようにするには、MySql.Data.DLL の参照を Web プロジェクトに追加し、Web サービス クラスの先頭に using ステートメントを追加する必要があります。
using MySql.Data.MySqlClient;
こんにちは世界() は、Visual Studio によって作成された初期のサンプル メソッドです。不要なので削除しても良いでしょう。Web サービスを使用して SilverLight と MySQL の間で通信する方法を示す 2 つの簡単なメソッドを作成します。
最初の方法: ExecuteScalar()
この方法は簡単です。MySQL から単一のオブジェクトを取得します。
public string ExecuteScalar(string sql)
{
try
{
string result = "";
using (MySqlConnection conn = new MySqlConnection(constr))
{
using (MySqlCommand cmd = new MySqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = sql;
result = cmd.ExecuteScalar() + "";
conn.Close();
}
}
return result;
}
catch (Exception ex)
{
return ex.Message;
}
}
2 番目の方法: ExecuteNonQuery()
単一の SQL 実行の場合。SQL タイプの例:挿入、更新、削除。
public string ExecuteNonQuery(string sql)
{
try
{
long i = 0;
using (MySqlConnection conn = new MySqlConnection(constr))
{
using (MySqlCommand cmd = new MySqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = sql;
i = cmd.ExecuteNonQuery();
conn.Close();
}
}
return i + " row(s) affected by the last command, no resultset returned.";
}
catch (Exception ex)
{
return ex.Message;
}
}
上記の 2 つのメソッドを追加した後の Web サービスは次のようになります。
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using MySql.Data.MySqlClient;
namespace SilverlightApplication1.Web
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class WebService1 : System.Web.Services.WebService
{
string constr = "server=localhost;user=root;pwd=1234;database=test;";
[WebMethod]
public string ExecuteScalar(string sql)
{
try
{
string result = "";
using (MySqlConnection conn = new MySqlConnection(constr))
{
using (MySqlCommand cmd = new MySqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = sql;
result = cmd.ExecuteScalar() + "";
conn.Close();
}
}
return result;
}
catch (Exception ex)
{
return ex.Message;
}
}
[WebMethod]
public string ExecuteNonQuery(string sql)
{
try
{
long i = 0;
using (MySqlConnection conn = new MySqlConnection(constr))
{
using (MySqlCommand cmd = new MySqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = sql;
i = cmd.ExecuteNonQuery();
conn.Close();
}
}
return i + " row(s) affected by the last command, no resultset returned.";
}
catch (Exception ex)
{
return ex.Message;
}
}
}
}
属性が [ウェブメソッド] メソッドに追加されます。
プロジェクトを再構築し、Web サービスを次のステップに向けて準備します。
Webサービスアクセス許可
デフォルトでは、Web サービスは、Web サービスと同じドメインでホストされている Silverlight のみにアクセスを許可することに注意してください。Silverlight アプリケーションが別の Web サイト/ドメインでホストされている場合、Web サービスは通信を拒否します。したがって、別のドメインでホストされている Silverlight から Web サービスにアクセスできるように、アクセス許可を構成する必要があります。
2 つの追加ファイルを作成する必要があります。 クライアントアクセスポリシー.xml そして クロスドメイン.xml.
これらのファイルは、Web サービスがホストされるドメインのルートに配置する必要があります。
例: http://www.mywebsite.com/clientaccesspolicy.xml
そして http://www.mywebsite.com/crossdomain.xml
クライアントアクセスポリシー.xml
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
特定のドメインによる Web サービスへのアクセスのみを許可したい場合 (例:www.myanotherwebsite.com) 内に追加できます。例:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="http://www.myanotherwebsite.com"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
クロスドメイン.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
</cross-domain-policy>
これについて詳しく理解するには、以下をお読みください。 ドメイン境界を越えてサービスを利用できるようにする (MSDN)
ステップ2:Silverlight へのサービス参照の追加
Silverlight にサービス参照を追加します。
Web サービスのアドレスを入力し、[Go] を押します。
住所の例: http://www.mywebsite.com/MyCoolWebService.asmx
ネームスペースを好みに変更し、[OK]を押します。
Visual Studio は Web サービスを分析し、データ バインディングを行ってクラスを作成します。
コーディングを続ける前に、新しく作成したクラスでどのようなメソッドが使用できるかを見てみましょう。新しいクラスを右クリックし、[オブジェクト ブラウザで表示]を選択します。
使用するクラスは WebService1SoapClient (この例では) です。命名はサービス名に基づいて行われます。サービス クラスに MyCoolWebService という名前を付けると、Silverlight のクラス名として MyCoolWebServiceSoapClient が選択されます。右側のパネルでは、2 つのメソッドと 2 つのイベントが強調表示されています。これらは、Web サービスを呼び出すために使用されるメソッドです。
テキスト ボックスと 2 つのボタンを追加して、単純な Silverlight アプリケーションを作成してみましょう。
この例では、ユーザーは SQL クエリをテキストボックスに直接入力します。
[ExecuteScalar] ボタンは SQL を Web サービスに送信し、データを取得します。(選択、表示など)
[ExecuteNonQuery]ボタンはSQLを実行専用のWebサービスに送信します。(挿入、更新、削除など)
これは MainPage.xaml の最初のコード ビハインドです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void btExecuteScalar_Click(object sender, RoutedEventArgs e)
{
}
private void btExecuteNonQuery_Click(object sender, RoutedEventArgs e)
{
}
}
}
さて、ここで行うことは次のとおりです。
- サービスをクラス レベルで静的オブジェクトとして宣言します。ServiceReference1.WebService1SoapClient
- 2つのメソッドのサービス完了イベントを作成します。
- ボタンをクリックしたときにサービスを呼び出します。
- サービス結果を表示します。メッセージボックス.Show()
public partial class MainPage : UserControl
{
ServiceReference1.WebService1SoapClient myService;
public MainPage()
{
InitializeComponent();
myService = new ServiceReference1.WebService1SoapClient();
myService.ExecuteScalarCompleted += myService_ExecuteScalarCompleted;
myService.ExecuteNonQueryCompleted += myService_ExecuteNonQueryCompleted;
}
void myService_ExecuteNonQueryCompleted(object sender,
ServiceReference1.ExecuteNonQueryCompletedEventArgs e)
{
MessageBox.Show(e.Result);
}
void myService_ExecuteScalarCompleted(object sender,
ServiceReference1.ExecuteScalarCompletedEventArgs e)
{
MessageBox.Show(e.Result);
}
private void btExecuteScalar_Click(object sender, RoutedEventArgs e)
{
myService.ExecuteScalarAsync(textBox1.Text);
}
private void btExecuteNonQuery_Click(object sender, RoutedEventArgs e)
{
myService.ExecuteNonQueryAsync(textBox1.Text);
}
}
[F5] を押して、Silverlight アプリケーションを実行してテストします。
あなたの創造性と一緒に、私はあなたが今のところこれ以上のことができると信じています| :)
Web サービスに何らかの変更を加えた場合 (新しいサービス (新しい Web メソッド) を追加した可能性があります)、Silverlight でサービス参照を更新してサービスを再バインドする必要があります。ファイルを別の Web ホスティングにアップロードした場合は、Web サービスのアドレスを更新することが必要になる場合があります。
コーディングを楽しんでください。
続きを読む: