Pregunta

Escribí una pequeña aplicación de prueba de Hola Mundo en Silverlight que quiero alojar en un servidor Linux/Apache2.Quiero que los datos provengan de MySQL (o alguna otra base de datos compatible con Linux) para poder vincular datos a cosas en la base de datos.

He logrado hacerlo funcionar usando el Conector 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();
}

Esto funciona bien si le doy plena confianza a la aplicación ClickOnce publicada (o al menos SocketPermission) y ejecutarlo localmente.

Quiero que esto se ejecute en el servidor y no puedo hacerlo funcionar, y siempre termino con una excepción de permiso (SocketPermission no está permitido).

La base de datos está alojada en el mismo servidor que la aplicación Silverlight, si eso hace alguna diferencia.

EDITAROk, ahora entiendo por qué es mala idea tener credenciales de base de datos en la aplicación cliente (obviamente).¿Cómo hace la gente esto entonces?¿Cómo se protege el servicio web proxy para que transmita datos hacia y desde el cliente/base de datos de forma segura?¿Hay algún ejemplo en la web?

Seguramente no puedo ser la primera persona a la que le gustaría utilizar una base de datos para impulsar una aplicación Silverlight.

¿Fue útil?

Solución

La forma más sencilla de hacer lo que desea (después de haber leído sus ediciones ahora :)) será exponer los servicios que se pueden consumir.El patrón que Microsoft REALMENTE está impulsando en este momento es exponer los servicios WCF, pero la verdad es que su cliente Silverlight puede usar WCF para consumir muchos tipos diferentes de servicios.

Lo que podría resultarle más fácil en este momento sería utilizar un servicio .NET en un servidor web o tal vez un servicio PHP REST y luego apuntar su aplicación Silverlight a ese servicio.Al hacerlo, está protegiendo su base de datos no sólo de las personas que husmean en ella, sino que, lo que es más importante, está restringiendo lo que las personas pueden hacer con su base de datos.Si se supone que sus datos son de solo lectura y el contrato de su servicio solo permite operaciones de lectura, está listo.Alternativamente, su servicio puede negociar sesiones con credenciales, nuevamente configuradas a través de WCF.

WCF puede ser una plataforma de conector solo cliente, solo servidor o cliente-servidor.Lo que elijas afectará el código que escribas, pero todo será independiente de tu base de datos.Su código puede estructurarse de manera que sea una asignación uno a uno a la tabla de su base de datos, o puede ser mucho más abstracto (puede configurar clases que representen vistas lógicas completas si lo desea).

Otros consejos

Si bien la respuesta "oficial" es usar WCF para enviar un servicio a Silverlight, me imagino que cualquiera que use MySQL probablemente no estaría usando una solución ASP.NET completa.Mi solución fue crear un servicio web PHP (como sugirió Rob) para interactuar con la base de datos MySQL y hacer que Silverlight acceda a ella de manera REST.

Aquí comienza un tutorial de tres partes sobre cómo usar Silverlight para acceder a una base de datos MySQL a través de un servicio web PHP:

PHP, MySQL y Silverlight:El tutorial completo

Silverlight no tiene ninguna capacidad para acceder directamente a servidores de bases de datos.Lo que puede hacer es exponer las operaciones de su base de datos a través de servicios web (ASMX o WCF, ¡incluso que no sean .NET!) y usar Silverlight para acceder a esos servicios.

Acabo de hacer que esto funcione;Sitio ASP.NET4 con contenido Silverlight4 en servidor Linux Ubuntu 10/Apache2.El contenido se desarrolla utilizando Visual Studio 2010.VS2008 también debería funcionar bien.

Servidor:

  • Configure un servidor Linux con Apache2 y MySQL, hay toneladas de guías sobre esto.
    • Asegúrese de que se pueda acceder a MySQL desde la PC de desarrollo y, opcionalmente, desde Internet.Consulte aquí para obtener más detalles: Causas de errores de acceso denegado.
    • Configure las estructuras de las tablas de la base de datos y agregue contenido para probarlo más adelante.En nuestro ejemplo asumimos que tiene la tabla 'personas' con la columna 'nombre'.
  • Dado que Silverlight es una tecnología del lado del cliente, usted está prácticamente listo y puede alojar la aplicación con una simple página HTML.
  • Se requiere un servicio web entre Silverlight y MySQL.WCF RIA de Microsoft es una versión, pero requiere .NET.En el lado positivo, también puedes alojar páginas ASP.NET4.Aquí hay una guía completa para configurarlo: Configuración de Mono 2.8 con Asp.Net 4.0 y MVC2 en Ubuntu con membresía MySql

Estudio visual:

  • Instalar lo último Conector MySQL/Red y reinicia VS
  • Agregue su base de datos MySQL como fuente de datos
    • Abra Server Explorer -> Agregar conexión de datos -> Seleccione 'Base de datos MySQL'
    • Complete las credenciales y pruebe la conexión

Configurando el sitio con acceso MySQL:

Aquí hay una guía que encontré útil: Guía paso a paso para la aplicación SL4 habilitada para WCF RIA con Entity Framework

  • Cree o abra un proyecto Silverlight.
    • El proyecto del lado del servidor normalmente se denomina 'NombreProyecto.Web'
    • El proyecto del lado del cliente normalmente se denomina "Nombre del proyecto".
  • Agregue 'Modelo de datos de entidad ADO.NET' al proyecto del servidor.Este será un modelo de la estructura de su base de datos.
    • Seleccione 'Generar desde base de datos'
    • Elija la conexión de base de datos MySQL que creó
    • Selecciona las mesas a las que quieres acceder
  • Construya su solución ahora antes de continuar.
  • Agregue 'Clase de servicio de dominio' al proyecto del servidor, p.ej.'FooDominio'.Esto hará que las entidades de la base de datos estén disponibles para el código Silverlight del lado del cliente.
    • En 'Clases de DataContext/ObjectContext disponibles:' seleccione el modelo de Entity Framework que creó en el paso anterior.
    • Marque las entidades a las que desea acceder y marque 'Habilitar edición' cuando corresponda
    • Marque 'Generar clases asociadas para metadatos'
  • Cree su solución nuevamente para generar 'FooDomainContext', basado en 'FooDomain' en el proyecto del servidor.

Pruebas:

Llevemos datos de MySQL a Silverlight.Suponiendo que hay una tabla llamada 'personas' con el nombre de columna 'nombre', podemos vincular un cuadro de lista para mostrar los nombres de las personas.

Primero agregue una página de Silverlight, digamos "Inicio".En Home.xaml agregue:

<ListBox x:Name="TestList" Width="100" />

En el archivo Home.xaml.cs agregue:

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";
    }
}

Aquí asumimos que nombró su servicio de dominio 'FooDomain', y esto generaría la clase 'FooDomainContext' utilizada.

Con suerte, si todo está configurado correctamente, ahora verá una lista de nombres de personas cuando ejecute su proyecto Silverlight.

Editar: ASP.NET no es opcional, pero es necesario para el servicio web WCF RIA utilizado en mi ejemplo.

Tener conexiones de base de datos directamente al servidor desde el lado del cliente suele ser una mala idea.No sé qué tan fácil es descompilar una aplicación Silverlight, pero supongo que es posible de alguna manera.Entonces básicamente estás regalando tus credenciales de base de datos a tus usuarios.

Puede obtener datos de MySQL utilizando servicios web.

Tutorial:

Paso 1:Crear servicios web

Paso 2:Agregar referencia de servicio a Silverlight


Paso 1:Crear servicios web

Agregue un nuevo proyecto Silverlight.

Add a new Silverlight project

Cree un nuevo servicio web.Haga clic derecho en el proyecto web > Agregar > Nuevo elemento

Create a new Web Service

Seleccione "Servicio web".

enter image description here

Código inicial de un nuevo Servicio 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";
        }
    }
}

Para que el servicio web pueda conectarse a MySQL, necesitamos agregar una referencia de MySql.Data.DLL al proyecto web y agregar la declaración Usando en la parte superior de la clase del servicio web:

using MySql.Data.MySqlClient; 

Hola Mundo() es un método de muestra inicial creado por Visual Studio.Es posible que desees eliminarlo ya que no es necesario.Voy a crear dos métodos sencillos para demostrar cómo se utilizan los servicios web para comunicarse entre SilverLight y MySQL.

Primer método: EjecutarEscalar()

Este método es sencillo.Obtenga un solo objeto de 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;
    }
} 

Segundo método: EjecutarNonQuery()

Para ejecución de SQL único.Ejemplo de tipo SQL:INSERTAR, ACTUALIZAR, BORRAR.

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;
    }
}  

Así es como se ve el servicio web después de agregar los dos métodos anteriores:

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;
            }
        }  
    }
} 

Notarás que un atributo de [Método web] se agrega a los métodos.

Reconstruya el proyecto y deje que el servicio web esté listo para el siguiente paso.

Rebuild the project

Permiso de acceso al servicio web

Tenga en cuenta que, de forma predeterminada, el servicio web solo permite el acceso a Silverlight alojado en el mismo dominio que el servicio web.Si la aplicación Silverlight está alojada en otro sitio web/dominio, el Servicio Web denegará la comunicación.Por lo tanto, tenemos que configurar el permiso para que Silverlight acceda al servicio web, que está alojado en un dominio diferente.

Tienes que crear dos archivos adicionales: política de acceso al cliente.xml y dominio cruzado.xml.

Estos archivos deben colocarse en la raíz del dominio donde se alojan los Servicios Web.

Ejemplo: http://www.mywebsite.com/clientaccesspolicy.xml y http://www.misitioweb.com/crossdomain.xml

política de acceso al cliente.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>

Si solo desea permitir que el Servicio Web sea accedido por un dominio específico (ejemplo:www.myanotherwebsite.com), puedes agregarlo dentro de .Ejemplo:

<?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>

dominio cruzado.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>

Para comprender más sobre esto, lea: Hacer que un servicio esté disponible a través de los límites del dominio (MSDN)


Paso 2:Agregar referencia de servicio a Silverlight

Agregue una referencia de servicio a Silverlight.

Add a Service Reference to Silverlight

Escriba la dirección del Servicio Web y presione [Ir].

Ejemplo de dirección: http://www.mywebsite.com/MyCoolWebService.asmx

Cambie el espacio de nombres a su favor y presione [Aceptar].

Web Service Browser

Visual Studio analizará el servicio web, vinculará los datos y creará una clase.

Antes de continuar codificando, veamos qué métodos podemos usar en la nueva clase creada.Haga clic derecho en la nueva clase y seleccione [Ver en el Explorador de objetos].

View in Object Browser

La clase que vamos a utilizar es WebService1SoapClient (en este ejemplo).El nombre se basa en el nombre del Servicio.Si nombramos nuestra clase de servicio como MyCoolWebService, entonces se elegirá MyCoolWebServiceSoapClient como el nombre de la clase en Silverlight.En el panel derecho, se resaltan dos métodos y dos eventos.Esos son los métodos utilizados para llamar a los Servicios Web.

Object of WebService1SoapClient

Creemos una aplicación Silverlight simple agregando un cuadro de texto y dos botones.

En este ejemplo, el usuario ingresará la consulta SQL directamente en el cuadro de texto.

El botón de [ExecuteScalar] enviará el SQL al servicio web y recuperará los datos.(SELECCIONAR, MOSTRAR, etc.)

El botón de [ExecuteNonQuery] enviará el SQL al servicio web únicamente para su ejecución.(INSERTAR, ACTUALIZAR, BORRAR, etc.)

Design a simple SilverLight App

Este es el código inicial detrás de 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)
        {
        }
    }
}

Ahora, esto es lo que vamos a hacer aquí:

  • Declare el servicio como objeto estático a nivel de clase:ServiceReference1.WebService1SoapClient
  • Cree el evento de servicio completado de los dos métodos.
  • Llame al servicio en caso de hacer clic en el botón.
  • Mostrar el resultado del servicio:Cuadro de mensaje.Mostrar()


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);
    }
}

Presione [F5], ejecute y pruebe la aplicación Silverlight.

Testing

Testing

Testing

Junto con tu creatividad, creo que puedes hacer algo más que esto por ahora sonreír | :)

Si realizó algún cambio en el Servicio web, tal vez agregó un nuevo Servicio (nuevos métodos web), debe actualizar la Referencia del servicio en Silverlight para volver a vincular los Servicios.Es posible que desee actualizar la dirección del servicio web, si cargó los archivos en un alojamiento web diferente.

update the Service Reference

Feliz codificación.

Leer más:

  1. Publicación original: Conexión de MySQL desde SilverLight con servicios web - CodeProject.com (escrito por mí)
  2. Acceder a un servicio web desde una aplicación Silverlight
  3. CÓMO:Escriba un servicio web simple utilizando Visual C# .NET
  4. Cómo:Cree un servicio para clientes de Silverlight
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top