如何让 silverlight 从 MySQL 获取数据
-
01-07-2019 - |
题
我在 Silverlight 中编写了一个小型的 hello world 测试应用程序,我想将其托管在 Linux/Apache2 服务器上。我希望数据来自 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 应用程序托管在同一台服务器上。
编辑好的,我现在明白为什么在客户端应用程序中拥有数据库凭据是一个坏主意(显然)。那么人们如何做到这一点呢?如何保护代理 Web 服务的安全,以便它以安全的方式在客户端/数据库之间转发数据?网上有什么例子吗?
当然,我不可能是第一个想要使用数据库来支持 silverlight 应用程序的人吧?
解决方案
执行您想要的操作(现在已阅读您的编辑:))的最简单方法是公开可以使用的服务。Microsoft 目前真正推动的模式是公开 WCF 服务,但事实是您的 Silverlight 客户端可以使用 WCF 来使用许多不同类型的服务。
现在对您来说最简单的做法可能是使用 Web 服务器上的 .NET 服务或 PHP REST 服务,然后将您的 Silverlight 应用程序指向该服务。通过这样做,您不仅可以保护您的数据库免遭他人窥探,更重要的是,您可以限制人们可以对您的数据库执行的操作。如果您的数据应该是只读的,并且您的服务合同只允许读取操作,那么您就设置好了。或者,您的服务可以再次通过 WCF 设置与凭据协商会话。
WCF 可以是仅客户端、仅服务器或客户端-服务器连接器平台。您的选择将影响您编写的代码,但这一切都将独立于您的数据库。您的代码可以被结构化为与数据库表的一对一映射,也可以更加抽象(如果您选择,您可以设置代表完整逻辑视图的类)。
其他提示
虽然“官方”答案是使用 WCF 将服务推送到 Silverlight,但我认为任何使用 MySQL 的人可能都不会使用完整的 ASP.NET 解决方案。我的解决方案是构建一个 PHP Web 服务(就像 Rob 建议的那样)来与 MySQL 数据库交互,并让 Silverlight 以 RESTful 方式访问它。
以下是使用 Silverlight 通过 PHP Web 服务访问 MySQL 数据库的三部分教程的开头部分:
Silverlight 没有任何直接访问数据库服务器的能力。您可以做的是通过 Web 服务(ASMX 或 WCF,甚至非 .NET!)公开您的数据库操作,并使用 Silverlight 访问这些服务。
我刚刚开始工作;Linux Ubuntu 10 / Apache2 服务器上包含 Silverlight4 内容的 ASP.NET4 站点。内容是使用 Visual Studio 2010 开发的。VS2008应该也能正常工作。
服务器:
- 使用 Apache2 和 MySQL 设置 Linux 服务器,有大量关于这方面的指南。
- 确保 MySQL 可以从开发 PC 访问,也可以从 Internet 访问。详细信息请参见此处: 拒绝访问错误的原因.
- 设置数据库表结构并添加一些内容以供稍后测试。在我们的示例中,我们假设您有表“persons”,其中包含“name”列。
- 由于 Silverlight 是一种客户端技术,因此您非常容易使用,并且可以使用简单的 HTML 页面托管应用程序。
- Silverlight 和 MySQL 之间需要 Web 服务。Microsoft 的 WCF RIA 是一种风格,但需要 .NET。从好的方面来说,您还可以托管 ASP.NET4 页面。这是设置它的完整指南: 在具有 MySql 成员资格的 Ubuntu 上使用 Asp.Net 4.0 和 MVC2 设置 Mono 2.8
视觉工作室:
- 安装最新版本 MySQL 连接器/网络 并重新启动VS
- 添加您的 MySQL 数据库作为数据源
- 打开服务器资源管理器 -> 添加数据连接 -> 选择“MySQL 数据库”
- 填写凭据并测试连接
设置具有 MySQL 访问权限的站点:
这是我发现很有帮助的指南: 使用实体框架启用 WCF RIA 的 SL4 应用程序的分步指南
- 创建或打开 Silverlight 项目。
- 服务器端项目通常命名为“ProjectName.Web”
- 客户端项目通常命名为“ProjectName”
- 将“ADO.NET 实体数据模型”添加到服务器项目。这将是您的数据库结构的模型。
- 选择“从数据库生成”
- 选择您创建的MySQL数据库连接
- 选择您要访问的表
- 在继续之前立即构建您的解决方案。
- 将“域服务类”添加到服务器项目,f.ex。'FooDomain'。这将使数据库实体可供客户端 Silverlight 代码使用。
- 在“可用的 DataContext/ObjectContext 类:”中,选择您在上一步中创建的实体框架模型。
- 检查您要访问的实体,并在适当的情况下选中“启用编辑”
- 选中“为元数据生成关联类”
- 再次构建您的解决方案以基于服务器项目中的“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 服务来说是必需的。
从客户端直接到服务器的数据库连接通常是一个坏主意。我不知道反编译 Silverlight 应用程序有多容易,但我猜想以某种方式是可能的。那么您基本上就将数据库凭据泄露给了您的用户。
您可以使用 Web 服务从 MySQL 获取数据。
演练:
步骤1:创建网络服务
第2步:将服务引用添加到 Silverlight
步骤1:创建网络服务
添加一个新的 Silverlight 项目。
创建一个新的 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 Service能够连接到MySQL,我们需要将MySql.Data.DLL的引用添加到Web项目中,并在Web Service类的顶部添加Using语句:
using MySql.Data.MySqlClient;
你好世界() 是 Visual Studio 创建的初始示例方法。您可能想删除它,因为不需要它。我将创建 2 个简单的方法来演示如何使用 Web 服务在 SilverLight 和 MySQL 之间进行通信。
第一种方法: 执行标量()
这个方法很简单。从 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;
}
}
第二种方法: 执行非查询()
用于单个 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;
}
}
添加上述两个方法后,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 Service 仅允许与 Web Service 托管在同一域中的 Silverlight 进行访问。如果 Silverlight 应用程序托管在另一个网站/域上,Web 服务将拒绝通信。因此,我们必须配置托管在不同域的Silverlight访问Web服务的权限。
您必须创建两个附加文件: 客户端访问策略.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
将命名空间更改为您喜欢的名称,然后按[确定]。
Visual Studio 将分析 Web 服务、进行数据绑定并创建一个类。
在继续编码之前,让我们看看我们可以在新创建的类中使用哪些方法。右键单击新类并选择[在对象浏览器中查看]。
我们要使用的类是 WebService1SoapClient(在本例中)。命名基于服务名称。如果我们将服务类命名为 MyCoolWebService,则在 Silverlight 中将选择 MyCoolWebServiceSoapClient 作为该类的名称。在右侧面板中,突出显示了两个方法和两个事件。这些是用于调用 Web 服务的方法。
让我们通过添加一个文本框和两个按钮来创建一个简单的 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
- 创建两个方法的服务完成事件。
- 单击按钮时调用该服务。
- 显示服务结果:消息框.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 服务地址。
快乐编码。
阅读更多: