Neste artigo vou mostrar como podemos usar a serialização de objeto para conseguir passar parametros entre o Silverlight e o ASP.NET usuando o Query Strings, o Init Parameters e o HtmlPage.Document. Mas lembre-se que usar essa técnica também gera sérios problemas de desempenho, então use isso somente quando você realmente precisar deste cenário. Internamente, esta técnica usa somente o método HtmpPage.Document.
Apenas para dar uma ideia geral de como eu consigo fazer isso, vou criar um modelo da aplicação Silverlight usando o Visual Studio Web Developer 2010, e adicionar um arquivo de classe chamado Employee.cs. Este arquivo contém apenas algumas entidades de Employee e EmployeeDetails. Apenas para dar uma noção do cenário real, eu criei o Employee eEmployeeAddress como uma classe separada e escrevi um método para retornar os dados modelo a partir destas classes.
- EmployeeAddress Class
public class EmployeeAddress
{
[XmlAttribute]
public string Address { get; set; }
[XmlAttribute]
public string City { get; set; }
[XmlAttribute]
public string PinCode { get; set; }
}
- Employee Class
[XmlRoot("Employee")]
public class Employee
{
[XmlElement]
public string EmployeeName { get; set; }
[XmlElement]
public EmployeeAddress EmployeeAddresses { get; set; }
[XmlElement]
public int Age { get; set; }
public List<Employee> GetEmployeeData()
{
List<Employee> employees = new List<Employee>();
employees.Add(new Employee { EmployeeAddresses = new EmployeeAddress { Address = "V.B.Layout", City = "Bangalore", PinCode = "560076" }, Age = 33, EmployeeName = "Brij Mohan" });
employees.Add(new Employee { EmployeeAddresses = new EmployeeAddress { Address = "Beauty Layout", City = "Delhi", PinCode = "111111" }, Age = 33, EmployeeName = "Arun Dayal Udai" });
employees.Add(new Employee { EmployeeAddresses = new EmployeeAddress { Address = "Mumbai Filmcity Layout", City = "Mumbai", PinCode = "444444" }, Age = 33, EmployeeName = "Sarosh Kumar" });
employees.Add(new Employee { EmployeeAddresses = new EmployeeAddress { Address = "Dimna Road", City = "Jamshedpur", PinCode = "831018" }, Age = 33, EmployeeName = "Bharti Priyadarshini" });
return employees;
}
public string GetSerializedEmployeeData()
{
MemoryStream mem = new MemoryStream();
System.Xml.Serialization.XmlSerializer xs = new XmlSerializer(typeof(List<Employee>));
mem.Seek(0, SeekOrigin.Begin);
xs.Serialize(mem, GetEmployeeData());
byte[] data = mem.GetBuffer();
string xmlString = Encoding.UTF8.GetString(data, 0, data.Length);
return xmlString;
}
public List<Employee> GetDesializedEmployeeObject(string xmlData)
{
StringReader sr = new StringReader(xmlData);
XmlSerializer xs = new XmlSerializer(typeof(List<Employee>));
object employees = xs.Deserialize(sr);
return (List<Employee>)employees;
}
}
Na classe employee acima eu também escrevi alguns métodos auxiliáres para serializar e desserializar os objetos, usando o XMLSerializer.
Agora, voltando para o código por trás da minha página default.aspx… Eu estou apenas tentando simular o cenário real. Na página de carregamento eu peguei meus dados simples e coloquei-os em um arquivo escondido. No ambiente real você pode pegar estes dados a partir do banco de dados e, então, colocá-los em algum campo escondido.
protected void Page_Load(object sender, EventArgs e)
{
Employee emp = new Employee();
txtValue.Text = HttpUtility.HtmlEncode(emp.GetSerializedEmployeeData());
}
Server Error in ‘/’ Application
A potentially dangerous Request.Form value was detected from the client (txtValue=”<?xml version=”1.0″?…”).

Certo, agora meu ASP.NET está pronto para enviar dados para o Silverlight Control. Em seguida o Silverlight pega seus dados e os analisa nos formatos reconhecidos pelo Silverlight e que ele controla e compreende.
Primeiro, eu adicionarei algumas classes employee ao projeto Silverlight para a de-serialização dos dados serializados do ASP.NET. Para evitar a duplicação de dados, estou adicionando os mesmos arquivos de classe ao meu projeto Silverlight usando Add como uma opção de link, a partir do diálogo de arquivo.
O primeiro passo é clicar com o botão direito no seu projeto Silverlight e selecione Add –> Existing Item.

Depois, localize seu arquivo Employee.cs a partir do seu projeto ASP.NET, e selecione a opção Add As Link, localizada dentro de Add. Isto, basicamente, irá criar um atalho para o Employee.cs, a partir do seu aplicativo ASP.NET, para o seu projeto Silverlight. Ambos são basicamente copias, então, antes de fazer qualquer mudança específica só no ASP.NET, certifique-se que isso seja compilado na sua aplicação Silverlight também, ou vice-versa.

Uma vez que o atalho do Employee tenha sido criado na sua aplicação Silverlight, podemos usar esta classe como um arquivo de classe normal. Voltando para minha aplicação Silverlight, abra o MainPage.xaml e o XAML View. Para visualizar os dados, adicionei o DataGrid e o ListView, do item Address, na página XAML Page.
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" ItemsSource="{Binding}" Name="employeeDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="361" SelectionChanged="employeeDataGrid_SelectionChanged">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="ageColumn" Binding="{Binding Path=Age}" Header="Age" Width="SizeToHeader" />
<sdk:DataGridTextColumn x:Name="employeeNameColumn" Binding="{Binding Path=EmployeeName}" Header="Employee Name" Width="SizeToHeader" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<Grid x:Name="employeeDetailList" HorizontalAlignment="Left" Margin="454,19,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<sdk:Label Content="Address:" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="addressTextBox" Text="{Binding Path=EmployeeAddresses.Address, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
<sdk:Label Content="City:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="3" Name="cityTextBox" Text="{Binding Path=EmployeeAddresses.City, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
<sdk:Label Content="Pin Code:" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="3" Name="pinCodeTextBox" Text="{Binding Path=EmployeeAddresses.PinCode, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
</Grid>
</Grid>
No código por trás da MainPage.xaml, eu apenas adicionei algumas linhas de código para carregar e vincular os dados da página ASP.NET escondida, onde mantivemos nossos dados serializados employee.
public partial class MainPage : UserControl
{
List<Web.Employee> employees = null;
public MainPage()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
var result = HttpUtility.HtmlDecode(HtmlPage.Document.GetElementById("txtValue").GetProperty("value").ToString());
SLAppCommunication.Web.Employee employee = new Web.Employee();
employees = employee.GetDesializedEmployeeObject(result.ToString());
employeeDataGrid.ItemsSource = employees;
}
}
private void employeeDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Web.Employee emp = ((DataGrid)sender).SelectedItem as Web.Employee;
employeeDetailList.DataContext = emp;
}
}
Depois do carregamento do Silverlight Control, eu li os dados a partir da caixa de texto da página HTML e usei o HttpUtility.HtmlDecode para decodificar a string codificada a partir da caixa de texto. Isto vai me dar a string serializada, de fato. Como queremos nossos dados dentro do formato de objeto, estamos realmente fazendo o contrário do que já fizemos na aplicação ASP.NET. Iremos passar estes dados XML dentro da nossa função GetDesializedEmployeeObject, e esta função irá basicamente retornar a List<Employee>, que podemos ligar diretamente ao nosso controle DataGrid.

Isso me dá todos os dados que criamos na nossa aplicação ASP.NET. Eu apenas adicionei o evento employeeDataGrid_SelectionChanged para quando selecionarmos qualquer linha no nosso Grid, ele exiba as informações detalhadas das mesmas. E ao usar este método, podemos evitar qualquer chamado para o banco de dados diretamente do componente Silverlight. Aqui, o Silvelight é apenas um componente ligado no container da nossa página ASP.NET.
Espero que tenha gostado deste artigo! Para obter o exemplo propriamente formatado e com o código fonte rodando, você pode fazer o download aqui.
***
Texto original disponível em: http://www.dotnetglobe.com/2011/07/passing-objects-between-aspnet-and.html








