提问人:Isak Savo 提问时间:9/19/2008 最后编辑:Isak Savo 更新时间:12/29/2013 访问量:24230
如何让silverlight从MySQL获取其数据
How to have silverlight get its data from MySQL
问:
我在 Silverlight 中编写了一个小型的 hello world 测试应用程序,我想将其托管在 Linux/Apache2 服务器上。我希望数据来自 MySQL(或其他一些与 linux 兼容的数据库),以便我可以与数据库中的内容进行数据绑定。
我已经设法通过使用MySQL Connector / .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 应用程序的人吗?
答:
Silverlight 没有任何直接访问数据库服务器的功能。您可以做的是通过 Web 服务(ASMX 或 WCF,甚至 non-.NET!)公开数据库操作,并使用 Silverlight 访问这些服务。
评论
从客户端直接连接到服务器的数据库连接通常是一个坏主意。我不知道反编译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 数据库:
我刚刚开始工作;ASP中。在 Linux Ubuntu 10 / Apache2 服务器上具有 Silverlight4 内容的 NET4 站点。内容是使用 Visual Studio 2010 开发的。VS2008 也应该可以正常工作。
服务器:
- 使用 Apache2 和 MySQL 设置 Linux 服务器,有大量这方面的指南。
- 确保可以从开发电脑访问 MySQL,也可以从 Internet 访问。有关详细信息,请参阅此处:拒绝访问错误的原因。
- 设置数据库表结构并添加一些内容以供以后测试。在我们的示例中,我们假设您有表“persons”和“name”列。
- 由于 Silverlight 是一种客户端技术,因此您几乎可以上手,并且可以使用简单的 HTML 页面来承载应用程序。
- Silverlight 和 MySQL 之间需要 Web 服务。Microsoft 的 WCF RIA 是一种风格,但需要 .NET。从好的方面来说,您可以托管 ASP。NET4 页面也是如此。以下是设置它的完整指南: 使用 MySql 成员资格在 Ubuntu 上使用 Asp.Net 4.0 和 MVC2 设置 Mono 2.8
Visual Studio:
- 安装最新的 MySQL Connector/Net 并重新启动 VS
- 将 MySQL 数据库添加为数据源
- 打开服务器资源管理器 -> 添加数据连接 -> 选择“MySQL 数据库”
- 填写凭据并测试连接
设置具有 MySQL 访问权限的站点:
以下是我发现有用的指南:使用实体框架的 WCF RIA 启用 SL4 应用程序的分步指南
- 创建或打开 Silverlight 项目。
- 服务器端项目通常命名为“ProjectName.Web”
- 客户端项目通常命名为“ProjectName”
- 将“ADO.NET 实体数据模型”添加到服务器项目。这将是数据库结构的模型。
- 选择“从数据库生成”
- 选择您创建的 MySQL 数据库连接
- 选择要访问的表
- 在继续操作之前,请立即构建解决方案。
- 将“域服务类”添加到服务器项目,例如。“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 服务是必需的。
您可以使用 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;
HelloWorld() 是 Visual Studio 创建的初始示例方法。您可能需要删除它,因为它是不需要的。我将创建 2 个简单的方法来演示如何使用 Web 服务在 SilverLight 和 MySQL 之间进行通信。
第一种方法: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;
}
}
第二种方法:ExecuteNonQuery()
用于单个 SQL 执行。SQL 类型示例:INSERT、UPDATE、DELETE。
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;
}
}
}
}
您会注意到,[WebMethod] 属性已添加到方法中。
重新生成项目,让 Web 服务为下一步做好准备。
Web 服务访问权限
请注意,默认情况下,Web 服务只允许与 Web 服务托管在同一域中的那些 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>
如果只想允许特定域(例如:www.myanotherwebsite.com)访问 Web Service,则可以将其添加到 中。例:
<?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,则 MyCoolWebServiceSoapClient 将被选为 Silverlight 中的类的名称。在右侧面板中,突出显示了两种方法和两个事件。这些是用于调用 Web 服务的方法。
让我们通过添加一个文本框和两个按钮来创建一个简单的 Silverlight 应用程序。
在此示例中,用户将直接在文本框中键入 SQL 查询。
[ExecuteScalar] 的按钮会将 SQL 发送到 Web 服务并检索数据。(选择、显示等)
[ExecuteNonQuery] 的按钮会将 SQL 发送到 Web 服务,仅供执行。(INSERT、UPDATE、DELETE 等)
这是 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
- 创建两个方法的服务完成事件。
- 在单击按钮时调用服务。
- 显示服务结果:MessageBox.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 服务地址。
祝您编码愉快。
阅读更多:
评论