Silverlight가 MySQL에서 데이터를 가져오도록 하는 방법
-
01-07-2019 - |
문제
저는 Linux/Apache2 서버에서 호스팅하고 싶은 작은 Hello World 테스트 앱을 Silverlight로 작성했습니다.DB에 있는 항목에 데이터 바인딩할 수 있도록 데이터를 MySQL(또는 다른 Linux 호환 DB)에서 가져오길 원합니다.
나는 그것을 사용하여 그것을 작동하게 만들었습니다. 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 자격 증명을 갖는 것이 왜 나쁜 생각인지 이해합니다(분명히).그러면 사람들은 이것을 어떻게 합니까?안전한 방식으로 클라이언트/DB와 데이터를 주고받을 수 있도록 프록시 웹 서비스를 보호하는 방법은 무엇입니까?웹에 어떤 예가 있나요?
물론, 저는 데이터베이스를 사용하여 Silverlight 응용 프로그램을 구동하려는 첫 번째 사람이 될 수 없습니까?
해결책
원하는 작업을 수행하는 가장 쉬운 방법(지금 편집 내용을 읽어보세요 :))은 사용할 수 있는 서비스를 노출하는 것입니다.Microsoft가 현재 실제로 추진하고 있는 패턴은 WCF 서비스를 노출하는 것입니다. 그러나 실제로 Silverlight 클라이언트는 WCF를 사용하여 다양한 유형의 서비스를 사용할 수 있습니다.
지금 당장 할 수 있는 가장 쉬운 일은 웹 서버에서 .NET 서비스나 PHP REST 서비스를 사용한 다음 Silverlight 앱이 해당 서비스를 가리키도록 하는 것입니다.이렇게 하면 데이터베이스를 엿보는 사람들로부터 데이터베이스를 보호할 수 있을 뿐만 아니라 더 중요하게는 사람들이 데이터베이스에 수행할 수 있는 작업을 제한할 수 있습니다.데이터가 읽기 전용이고 서비스 계약이 읽기 작업만 허용하는 경우 설정된 것입니다.또는 서비스에서 WCF를 통해 다시 설정된 자격 증명을 사용하여 세션을 협상할 수 있습니다.
WCF는 클라이언트 전용, 서버 전용 또는 클라이언트-서버 커넥터 플랫폼일 수 있습니다.선택한 내용은 작성하는 코드에 영향을 주지만 모두 데이터베이스와 독립적입니다.코드는 데이터베이스 테이블에 대한 일대일 매핑으로 구성될 수도 있고 훨씬 더 추상적일 수도 있습니다(원하는 경우 전체 논리적 뷰를 나타내는 클래스를 설정할 수 있음).
다른 팁
"공식적인" 대답은 WCF를 사용하여 Silverlight에 서비스를 푸시하는 것이지만 MySQL을 사용하는 사람이라면 누구나 완전한 ASP.NET 솔루션을 사용하지 않을 것이라고 생각합니다.내 솔루션은 MySQL 데이터베이스와 상호 작용하고 Silverlight가 RESTful 방식으로 데이터베이스에 액세스하도록 하는 PHP 웹 서비스(Rob이 제안한 것과 같은)를 구축하는 것이었습니다.
다음은 Silverlight를 사용하여 PHP 웹 서비스를 통해 MySQL 데이터베이스에 액세스하는 세 부분으로 구성된 자습서의 시작 부분입니다.
Silverlight에는 데이터베이스 서버에 직접 액세스하는 기능이 없습니다.당신이 할 수 있는 일은 웹 서비스(ASMX 또는 WCF, 심지어 .NET이 아닌 경우에도!)를 통해 데이터베이스 작업을 노출하고 Silverlight를 사용하여 해당 서비스에 액세스하는 것입니다.
방금 이 작업을 수행했습니다.Linux Ubuntu 10/Apache2 서버에 Silverlight4 콘텐츠가 포함된 ASP.NET4 사이트.콘텐츠는 Visual Studio 2010을 사용하여 개발되었습니다.VS2008도 잘 작동할 것입니다.
섬기는 사람:
- Apache2 및 MySQL을 사용하여 Linux 서버를 설정하는 방법에 대한 수많은 가이드가 있습니다.
- 개발 PC에서 MySQL에 액세스할 수 있는지 확인하고 선택적으로 인터넷에서도 액세스할 수 있는지 확인하십시오.자세한 내용은 여기를 참조하세요. 액세스 거부 오류의 원인.
- 데이터베이스 테이블 구조를 설정하고 나중에 테스트할 내용을 추가합니다.이 예에서는 'name' 열이 있는 'persons' 테이블이 있다고 가정합니다.
- Silverlight는 클라이언트 측 기술이므로 매우 쉽게 사용할 수 있으며 간단한 HTML 페이지로 응용 프로그램을 호스팅할 수 있습니다.
- Silverlight와 MySQL 사이에는 웹 서비스가 필요합니다.Microsoft의 WCF RIA는 하나의 버전이지만 .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 엔터티 데이터 모델'을 추가합니다.이는 데이터베이스 구조의 모델이 됩니다.
- '데이터베이스에서 생성'을 선택하세요.
- 생성한 MySQL 데이터베이스 연결을 선택하세요.
- 액세스하려는 테이블을 선택하세요.
- 계속하기 전에 지금 솔루션을 구축하세요.
- 서버 프로젝트 f.ex에 '도메인 서비스 클래스'를 추가합니다.'푸도메인'.이렇게 하면 클라이언트측 Silverlight 코드에서 데이터베이스 엔터티를 사용할 수 있게 됩니다.
- '사용 가능한 DataContext/ObjectContext 클래스:'에서 이전 단계에서 만든 Entity Framework 모델을 선택합니다.
- 액세스하려는 엔터티를 확인하고 해당하는 경우 '편집 활성화'를 선택하세요.
- '메타데이터에 대한 연관된 클래스 생성'을 선택하십시오.
- 서버 프로젝트의 'FooDomain'을 기반으로 'FooDomainContext'를 생성하려면 솔루션을 다시 빌드하세요.
테스트:
MySQL의 데이터를 Silverlight로 가져오겠습니다.열 이름이 'name'인 'persons'라는 테이블이 있다고 가정하면 목록 상자를 바인딩하여 사람의 이름을 표시할 수 있습니다.
먼저 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 웹 서비스에는 필수입니다.
클라이언트 측에서 서버에 직접 DB 연결을 갖는 것은 일반적으로 좋지 않은 생각입니다.Silverlight 앱을 디컴파일하는 것이 얼마나 쉬운지는 모르겠지만 어떤 면에서는 가능할 것 같습니다.그러면 기본적으로 DB 자격 증명을 사용자에게 제공하게 됩니다.
웹 서비스를 사용하여 MySQL에서 데이터를 가져올 수 있습니다.
연습:
1 단계:웹 서비스 생성
2 단계:Silverlight에 서비스 참조 추가
1 단계:웹 서비스 생성
새 Silverlight 프로젝트를 추가합니다.
새 웹 서비스를 만듭니다.웹 프로젝트 > 추가 > 새 항목을 마우스 오른쪽 버튼으로 클릭합니다.
"웹 서비스"를 선택하십시오.
새로운 웹 서비스의 초기 코드입니다.
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";
}
}
}
웹 서비스를 MySQL에 연결할 수 있으려면 MySql.Data.DLL 참조를 웹 프로젝트에 추가하고 웹 서비스 클래스 상단에 Using 문을 추가해야 합니다.
using MySql.Data.MySqlClient;
헬로월드() Visual Studio에서 만든 초기 샘플 메서드입니다.필요하지 않으므로 삭제하는 것이 좋습니다.SilverLight와 MySQL 간의 통신에 웹 서비스가 사용되는 방법을 보여주기 위해 2가지 간단한 방법을 만들겠습니다.
첫 번째 방법: 실행스칼라()
이 방법은 간단합니다.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;
}
}
두 번째 방법: 실행NonQuery()
단일 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;
}
}
위의 두 가지 메소드를 추가한 후의 웹 서비스 모습은 다음과 같습니다.
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;
}
}
}
}
당신은 [웹방법] 메서드에 추가됩니다.
프로젝트를 다시 빌드하고 웹 서비스가 다음 단계를 준비하도록 합니다.
웹 서비스 접근 권한
기본적으로 웹 서비스는 웹 서비스와 동일한 도메인에서 호스팅되는 Silverlight에만 액세스할 수 있도록 허용합니다.Silverlight 응용 프로그램이 다른 웹 사이트/도메인에서 호스팅되는 경우 웹 서비스는 통신을 거부합니다.따라서 다른 도메인에서 호스팅되는 Silverlight에서 웹 서비스에 액세스할 수 있도록 권한을 구성해야 합니다.
두 개의 추가 파일을 만들어야 합니다. 클라이언트액세스정책.xml 그리고 크로스도메인.xml.
이러한 파일은 웹 서비스가 호스팅되는 도메인의 루트에 있어야 합니다.
예: 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) 내에서 추가하시면 됩니다.예:
<?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에 서비스 참조를 추가합니다.
웹 서비스의 주소를 입력하고 [이동]을 누르세요.
주소 예: http://www.mywebsite.com/MyCoolWebService.asmx
네임스페이스를 원하는 대로 변경하고 [확인]을 누릅니다.
Visual Studio는 웹 서비스를 분석하고 데이터 바인딩을 수행하며 클래스를 만듭니다.
코딩을 계속하기 전에 새로 생성된 클래스에서 어떤 메서드를 사용할 수 있는지 살펴보겠습니다.새 클래스를 마우스 오른쪽 버튼으로 클릭하고 [객체 브라우저에서 보기]를 선택합니다.
우리가 사용할 클래스는 WebService1SoapClient입니다(이 예에서는).이름 지정은 서비스 이름을 기준으로 합니다.서비스 클래스 이름을 MyCoolWebService로 지정하면 MyCoolWebServiceSoapClient가 Silverlight의 클래스 이름으로 선택됩니다.오른쪽 패널에는 두 가지 방법과 두 가지 이벤트가 강조 표시되어 있습니다.이는 웹 서비스를 호출하는 데 사용되는 방법입니다.
텍스트 상자와 두 개의 단추를 추가하여 간단한 Silverlight 응용 프로그램을 만들어 보겠습니다.
이 예에서 사용자는 SQL 쿼리를 텍스트 상자에 직접 입력합니다.
[ExecuteScalar] 버튼은 SQL을 웹 서비스로 보내고 데이터를 다시 검색합니다.(선택, 표시 등)
[ExecuteNonQuery] 버튼은 실행만을 위해 SQL을 웹 서비스로 보냅니다.(삽입, 업데이트, 삭제 등)
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
- 두 가지 메소드의 서비스 완료 이벤트를 생성합니다.
- 버튼 클릭 시 서비스를 호출합니다.
- 서비스 결과를 표시합니다:메시지박스.쇼()
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 응용 프로그램을 실행하고 테스트합니다.
당신의 창의성과 함께, 나는 당신이 지금 이보다 더 많은 일을 할 수 있다고 믿습니다. :)
웹 서비스를 변경한 경우 새 서비스(새 웹 메서드)를 추가했을 수 있으며 Silverlight에서 서비스 참조를 업데이트하여 서비스를 다시 바인딩해야 합니다.파일을 다른 웹 호스팅에 업로드한 경우 웹 서비스 주소를 업데이트할 수 있습니다.
즐거운 코딩하세요.
더 읽어보기: