C# 如何让silverlight从MySQL获取数据
我已经用Silverlight编写了一个小的hello world测试应用程序,我想将其托管在Linux/Apache2服务器上。我希望数据来自MySQL(或其他与linux兼容的数据库),这样我就可以将数据绑定到数据库中的内容 我已通过以下方法使其正常工作: 如果我对已发布的ClickOnce应用程序给予完全信任(或至少给予SocketPermission)并在本地运行该应用程序,则此操作非常有效 我想让它在服务器上运行,但我无法让它工作,结果总是出现权限异常(SocketPermission是不允许的) 该数据库与silverlight应用程序托管在同一台服务器上,如果这有任何区别的话 编辑 好了,我现在明白了为什么在客户端应用程序中使用db凭据是个坏主意(显然)。那么人们是如何做到这一点的呢?如何保护代理web服务,使其以安全的方式向客户机/db传递数据?网上有什么例子吗C# 如何让silverlight从MySQL获取数据,c#,.net,mysql,silverlight,data-binding,C#,.net,Mysql,Silverlight,Data Binding,我已经用Silverlight编写了一个小的hello world测试应用程序,我想将其托管在Linux/Apache2服务器上。我希望数据来自MySQL(或其他与linux兼容的数据库),这样我就可以将数据绑定到数据库中的内容 我已通过以下方法使其正常工作: 如果我对已发布的ClickOnce应用程序给予完全信任(或至少给予SocketPermission)并在本地运行该应用程序,则此操作非常有效 我想让它在服务器上运行,但我无法让它工作,结果总是出现权限异常(SocketPermission
当然,我不是第一个想使用数据库为silverlight应用程序供电的人?silverlight没有任何直接访问数据库服务器的功能。您可以通过web服务(ASMX或WCF,甚至非.NET!)公开数据库操作,并使用Silverlight访问这些服务。Silverlight没有任何直接访问数据库服务器的功能。您可以通过web服务(ASMX或WCF,甚至非.NET!)公开您的数据库操作,并使用Silverlight访问这些服务。从客户端直接与服务器建立数据库连接通常是个坏主意。我不知道对Silverlight应用程序进行反编译有多容易,但我想这在某种程度上是可能的。然后,您基本上是将您的DB凭据提供给您的用户。从客户端直接将DB连接到服务器通常是个坏主意。我不知道对Silverlight应用程序进行反编译有多容易,但我想这在某种程度上是可能的。然后,您基本上是将您的DB凭据提供给您的用户。做您想做的事情(现在已经阅读了您的编辑:)最简单的方法是公开可以使用的服务。微软目前真正推动的模式是公开WCF服务,但事实是,您的Silverlight客户端可以使用WCF使用许多不同类型的服务 现在最简单的方法是在web服务器上使用.NET服务或PHP REST服务,然后将Silverlight应用程序指向该服务。通过这样做,您不仅可以保护您的数据库不被他人窥探,更重要的是,您可以限制人们对您的数据库所做的事情。如果您的数据应该是只读的,并且您的服务合同只允许读取操作,那么您已经设置好了。或者,您的服务也可以使用通过WCF设置的凭据协商会话
WCF可以是仅客户端、仅服务器或客户端-服务器连接器平台。您选择的内容将影响您编写的代码,但这一切都将独立于您的数据库。您的代码的结构可以是与数据库表的一对一映射,也可以是更抽象的(如果您愿意,可以设置表示完整逻辑视图的类)。实现所需操作的最简单方法(现在阅读了您的编辑:)是公开可以使用的服务。微软目前真正推动的模式是公开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数据库的三部分教程的开始部分: 虽然“官方”答案是使用WCF将服务推送到Silverlight,但我认为任何使用MySQL的人都可能不会使用完整的ASP.NET解决方案。我的解决方案是构建一个PHP Web服务(如Rob所建议的)与MySQL数据库交互,并让Silverlight以RESTful方式访问它 以下是使用Silverlight通过PHP web服务访问MySQL数据库的三部分教程的开始部分:
我刚刚开始工作;Linux Ubuntu 10/Apache2服务器上具有Silverlight4内容的ASP.NET4站点。内容是使用VisualStudio2010开发的。VS2008也应该可以正常工作 服务器:
- 用Apache2和MySQL安装Linux服务器,这上面有很多指南。
- 确保MySQL可以从开发PC访问,也可以从Internet访问。详见此处
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(); }
<ListBox x:Name="TestList" Width="100" />
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"; } }
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"; } } }
using MySql.Data.MySqlClient;
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; } }
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; } }
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; } } } }
<?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>
<?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 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>
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) { } } }
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); } }
- 确保MySQL可以从开发PC访问,也可以从Internet访问。详见此处