【问题标题】:How to have silverlight get its data from MySQL如何让 silverlight 从 MySQL 获取数据
【发布时间】:2010-09-11 03:15:38
【问题描述】:

我在 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 应用程序相同的服务器上,如果这有什么不同的话。

编辑 好的,我现在明白为什么在客户端应用程序中拥有 db 凭据是一个坏主意(显然)。那么人们是如何做到这一点的呢?您如何保护代理 Web 服务,以便它以安全的方式将数据中继到客户端/db?网上有没有例子?

当然,我不可能是第一个想使用数据库来支持 silverlight 应用程序的人吗?

【问题讨论】:

    标签: c# .net mysql silverlight data-binding


    【解决方案1】:

    Silverlight 没有任何直接访问数据库服务器的能力。您可以做的是通过 Web 服务(ASMX 或 WCF,甚至非 .NET!)公开您的数据库操作,并使用 Silverlight 访问这些服务。

    【讨论】:

    • 但是我可以和数据库对话,只是我不被允许。为什么允许它与 Web 服务(我认为是通过 http?)而不是数据库通信?
    【解决方案2】:

    从客户端直接连接到服务器通常是个坏主意。我不知道反编译 Silverlight 应用程序有多么容易,但我想这在某种程度上是可能的。然后,您基本上是在将您的数据库凭据提供给您的用户。

    【讨论】:

      【解决方案3】:

      做你想做的最简单的方法(现在已经阅读了你的编辑:))是公开可以使用的服务。 Microsoft 现在真正推动的模式是公开 WCF 服务,但事实是您的 Silverlight 客户端可以使用 WCF 来使用许多不同类型的服务。

      您现在最容易做的事情是在 Web 服务器上使用 .NET 服务或 PHP REST 服务,然后将您的 Silverlight 应用程序指向该服务。通过这样做,您不仅可以保护您的数据库免受他人窥探,更重要的是,您可以限制人们可以对您的数据库执行的操作。如果您的数据应该是只读的,并且您的服务合同只允许读取操作,那么您已经设置好了。或者,您的服务可能会再次通过 WCF 设置使用凭据协商会话。

      WCF 可以是仅客户端、仅服务器或客户端-服务器连接器平台。您选择的内容会影响您编写的代码,但这一切都将独立于您的数据库。您的代码可以构造成一对一映射到您的数据库表,也可以更加抽象(如果您愿意,可以设置表示完整逻辑视图的类)。

      【讨论】:

        【解决方案4】:

        虽然“官方”的答案是使用 WCF 将服务推送到 Silverlight,但我认为任何使用 MySQL 的人都可能不会使用完整的 ASP.NET 解决方案。我的解决方案是构建一个 PHP Web 服务(如 Rob 建议的那样)来与 MySQL 数据库交互并让 Silverlight 以 RESTful 方式访问它。

        这是使用 Silverlight 通过 PHP Web 服务访问 MySQL 数据库的三部分教程的开头:

        PHP, MySQL and Silverlight: The Complete Tutorial

        【讨论】:

          【解决方案5】:

          我刚刚开始工作;在 Linux Ubuntu 10 / Apache2 服务器上具有 Silverlight4 内容的 ASP.NET4 站点。内容是使用 Visual Studio 2010 开发的。VS2008 也应该可以正常工作。

          服务器:

          • 使用 Apache2 和 MySQL 设置 Linux 服务器,这方面有大量指南。
            • 确保可以从开发 PC 访问 MySQL,也可以从 Internet 访问。详情请看这里:Causes of Access-Denied Errors
            • 设置数据库表结构并添加一些内容以供稍后测试。在我们的示例中,我们假设您有表 'persons' 和列 'name'。
          • 由于 Silverlight 是一种客户端技术,因此您非常适合使用,并且可以使用简单的 HTML 页面托管应用程序。
          • Silverlight 和 MySQL 之间需要 Web 服务。 Microsoft 的 WCF RIA 是一种风格,但需要 .NET。从好的方面来说,您还可以托管 ASP.NET4 页面。这是设置它的详尽指南:Setting up Mono 2.8 with Asp.Net 4.0 and MVC2 on Ubuntu with MySql Membership

          Visual Studio:

          • 安装最新的MySQL Connector/Net并重启VS
          • 将您的 MySQL 数据库添加为数据源
            • 打开服务器资源管理器 -> 添加数据连接 -> 选择“MySQL 数据库”
            • 填写凭据并测试连接

          设置具有 MySQL 访问权限的站点:

          这是一个我觉得很有帮助的指南:Step By Step Guide to WCF RIA enabled SL4 application with Entity Framework

          • 创建或打开 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 服务是必需的。

          【讨论】:

            【解决方案6】:

            您可以使用 Web 服务从 MySQL 获取数据。

            演练:

            第 1 步:创建 Web 服务

            第 2 步:向 Silverlight 添加服务引用


            第 1 步:创建 Web 服务

            添加一个新的 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,我们需要在 Web 项目中添加对 MySql.Data.DLL 的引用,并在 Web Service 类的顶部添加 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 Service的样子:

            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 Service 仅允许与 Web Service 托管在同一域中的 Silverlight 访问。如果 Silverlight 应用程序托管在另一个网站/域上,Web 服务将拒绝通信。因此,我们必须为托管在不同域的 Silverlight 配置 Web 服务的访问权限。

            您必须创建两个附加文件:clientaccesspolicy.xmlcrossdomain.xml

            这些文件必须放在托管 Web 服务的域的根目录中。

            示例:@987654321@@987654322@

            clientaccesspolicy.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>
            

            crossdomain.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>
            

            要了解更多信息,请阅读:Making a Service Available Across Domain Boundaries (MSDN)


            第 2 步:向 Silverlight 添加服务引用

            添加对 Silverlight 的服务引用。

            键入 Web 服务的地址并按 [Go]。

            地址示例:http://www.mywebsite.com/MyCoolWebService.asmx

            根据您的喜好更改命名空间,然后按 [OK]。

            Visual Studio 将分析 Web 服务,进行数据绑定并创建一个类。

            在继续编码之前,让我们看看我们可以在新创建的类中使用哪些方法。右键单击新类并选择[在对象浏览器中查看]。

            我们将要使用的类是 WebService1SoapClient(在本例中)。命名基于服务名称。如果我们将我们的服务类命名为 MyCoolWebService,那么 MyCoolWebServiceSoapClient 将被选为 Silverlight 中类的名称。在右侧面板中,突出显示了两个方法和两个事件。这些是用于调用 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
            • 创建两个方法的服务完成事件。
            • 在单击按钮时调用服务。
            • 显示服务结果: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 应用程序。

            加上你的创造力,我相信你现在可以做更多的事情 Smile | :)

            如果您对 Web 服务进行了任何更改,也许您添加了新服务(新的 Web 方法),您必须在 Silverlight 更新服务参考以重新绑定服务。如果您将文件上传到不同的虚拟主机,您可能需要更新网络服务地址。

            编码愉快。

            阅读更多:

            1. Original Post - Connecting MySQL From SilverLight With Web Services - CodeProject.com (written by me)
            2. Access a Web Service from a Silverlight Application
            3. HOW TO: Write a Simple Web Service by Using Visual C# .NET
            4. How to: Build a Service for Silverlight Clients

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-11-26
              • 1970-01-01
              • 1970-01-01
              • 2017-02-06
              • 1970-01-01
              • 1970-01-01
              • 2010-11-25
              相关资源
              最近更新 更多