How to pass values from service to ViewModel? - mvvm

I created service to get data from JSON file and now I'm trying to show them on page.
In service, variable model get correct values, but in ViewModel varibales as StationId, StationName, Message, DateText etc are null, so obvious nothing is showing on page.
(Currently I set some hardcoded values for test purpose)
Model
public class IrrigNetModel
{
public IrrigNetModelItem[] items { get; set; }
}
public class IrrigNetModelItem
{
public int ID { get; set; }
public string Message { get; set; }
public DateTime Date { get; set; }
public string DateText { get; set; }
public int StationId { get; set; }
public string StationName { get; set; }
public float StationLongitude { get; set; }
public float StationLatitude { get; set; }
public int ServiceId { get; set; }
public string ServiceName { get; set; }
}
Service
class IrrigNetService
{
public static async Task<IrrigNetModel> GetServices(string token, string lngCode)
{
IrrigNetModel model = new IrrigNetModel();
try
{
string URL = DataURL.BASE_URL + "agronetmobile/getlistnotifications?lngCode=" + lngCode;
string content = Newtonsoft.Json.JsonConvert.SerializeObject(model);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", token);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
//client.DefaultRequestHeaders.TryAddWithoutValidation("Culture", LocalData.Lang);
HttpResponseMessage result = await client.PostAsync(URL, new StringContent(content, Encoding.UTF8, "application/json"));
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{
string resultContent = await result.Content.ReadAsStringAsync();
model = (IrrigNetModel)Newtonsoft.Json.JsonConvert.DeserializeObject(resultContent, typeof(IrrigNetModel));
}
else if (result.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
//
}
}
}
catch (Exception ex)
{
model = null;
}
return model;
}
}
ViewModel:
public ObservableCollection<IrrigNetModelItem> IrrigNetCollection { get; set; } = new ObservableCollection<IrrigNetModelItem>
{
new IrrigNetModelItem
{
StationId = 1,
StationName = "Krakatosia",
Message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur scelerisque a lorem sit amet mattis.",
DateText = "21.07.2012."
}
};
public IrrigNetViewModel()
{
var token = LocalData.Token;
IrrigNetService.GetServices(token,"sr");
TabTappedCommand = new Command((tabName) => OnTapClicked(tabName.ToString()));
HideListOnTapCommand = new Command(HideListOnTap);
IrrigNetModelItem model = new IrrigNetModelItem();
var irrigNetModel = new IrrigNetModelItem
{
StationId = model.StationId,
StationName = model.StationName,
Message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur scelerisque a lorem sit amet mattis.",
DateText = model.DateText
};
IrrigNetCollection.Add(irrigNetModel);
}

you are calling the service but not storing the result
IrrigNetService.GetServices(token,"sr");
instead, try this
var data = await IrrigNetService.GetServices(token,"sr");
foreach (var d in data.items) {
IrrigNetCollection.Add(d);
}

Related

In C# mongodb, match the entire external List of Objects to the Child list of the Parent list

`Suppose, I've User list with list of order
User model
`public class User
{
public int Id { get; set; }
public string Name { get; set; }
public List<UserOrder> Orders { get; set; }
}`
User Order model
`public class UserOrder
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}`
Order model
`public class Order
{
public int Name { get; set; }
public decimal Price { get; set; }
}`
Here, I want to retrieve all user list that contain all element of List in UserOrder list. (Compare with Name and Price)`
I don't quite understand what you mean, do you want to include the current Orders list when querying User?
You need to link the two tables. For example, add a field UserId to the UserOrder model to associate with User; or add a List<int> to the User model to store the corresponding UserOrderId.
I made a simple test, you can refer to it. In order to facilitate maintenance, I will write the method of processing data from the database in a separate service:
User Model:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public List<int> UserOrderIds { get; set; }
public List<UserOrder> Orders { get; set; }
}
UserService:
public class UserService
{
private readonly IMongoCollection<User> _users;
public UserService(IUserDatabaseSettings settings)
{
var client = new MongoClient(settings.ConnectionString);
var database = client.GetDatabase(settings.DatabaseName);
_users = database.GetCollection<User>(settings.UserCollectionName);
}
public async Task<List<User>> GetAllAsync()
{
return await _users.Find(s => true).ToListAsync();
}
public async Task<User> GetByIdAsync(int id)
{
return await _users.Find<User>(s => s.Id == id).FirstOrDefaultAsync();
}
public async Task<User> CreateAsync(User user)
{
await _users.InsertOneAsync(user);
return user;
}
public async Task UpdateAsync(int id, User user)
{
await _users.ReplaceOneAsync(s => s.Id == id, user);
}
public async Task DeleteAsync(int id)
{
await _users.DeleteOneAsync(s => s.Id == id);
}
}
UserOrderService:
public class UserOrderService
{
private readonly IMongoCollection<UserOrder> _userOrders;
public UserOrderService(IUserDatabaseSettings settings)
{
var client = new MongoClient(settings.ConnectionString);
var database = client.GetDatabase(settings.DatabaseName);
_userOrders = database.GetCollection<UserOrder>(settings.UserOrderCollectionName);
}
public async Task<List<UserOrder>> GetAllAsync()
{
return await _userOrders.Find(s => true).ToListAsync();
}
public async Task<UserOrder> GetByIdAsync(int id)
{
return await _userOrders.Find<UserOrder>(c => c.Id == id).FirstOrDefaultAsync();
}
public async Task<UserOrder> CreateAsync(UserOrder userOrder)
{
await _userOrders.InsertOneAsync(userOrder);
return userOrder;
}
public async Task UpdateAsync(int id, UserOrder userOrder)
{
await _userOrders.ReplaceOneAsync(c => c.Id == id, userOrder);
}
public async Task DeleteAsync(int id)
{
await _userOrders.DeleteOneAsync(c => c.Id == id);
}
}
appsetting.json:
"UserDatabaseSettings": {
"UserCollectionName": "User",
"UserOrderCollectionName": "UserOrder",
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "TestDb"
}
IUserDatabaseSettings(Used to obtain database related information):
public interface IUserDatabaseSettings
{
string UserCollectionName { get; set; }
string UserOrderCollectionName { get; set; }
string ConnectionString { get; set; }
string DatabaseName { get; set; }
}
public class UserDatabaseSettings : IUserDatabaseSettings
{
public string UserCollectionName { get; set; }
public string UserOrderCollectionName { get; set; }
public string ConnectionString { get; set; }
public string DatabaseName { get; set; }
}
Registration service:
services.Configure<UserDatabaseSettings>(
Configuration.GetSection(nameof(UserDatabaseSettings)));
services.AddSingleton<IUserDatabaseSettings>(provider =>
provider.GetRequiredService<IOptions<UserDatabaseSettings>>().Value);
services.AddSingleton<UserService>();
services.AddSingleton<UserOrderService>();
Controller:
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly UserService _userService;
private readonly UserOrderService _userOrderService;
public UserController(UserService sService, UserOrderService cService)
{
_userService = sService;
_userOrderService = cService;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetAll()
{
var users = await _userService.GetAllAsync();
return Ok(users);
}
[HttpGet("{id}")]
public async Task<ActionResult<User>> GetById(int id)
{
var user = await _userService.GetByIdAsync(id);
if (user == null)
{
return NotFound();
}
if (user.UserOrderIds.Count > 0)
{
var tempList = new List<UserOrder>();
foreach (var userOrderId in user.UserOrderIds)
{
var userOrder = await _userOrderService.GetByIdAsync(userOrderId);
if (userOrder != null)
tempList.Add(userOrder);
}
user.Orders = tempList;
}
return Ok(user);
}
[HttpPost]
public async Task<IActionResult> Create(User user)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
await _userService.CreateAsync(user);
return Ok(user);
}
[HttpPut]
public async Task<IActionResult> Update(int id, User updatedUser)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
var queriedStudent = await _userService.GetByIdAsync(id);
if (queriedStudent == null)
{
return NotFound();
}
await _userService.UpdateAsync(id, updatedUser);
return NoContent();
}
[HttpDelete]
public async Task<IActionResult> Delete(int id)
{
var student = await _userService.GetByIdAsync(id);
if (student == null)
{
return NotFound();
}
await _userService.DeleteAsync(id);
return NoContent();
}
}
Test Result:
Complete example is here.

How to insert payload data in many-to-many relationships with EF Core 5

I have this relationship between Licitadores and Ofertas
public class Licitador
{
public int Id { get; set; }
public string Nombre { get; set; }
[StringLength(maximumLength: 15)]
public string CodigoSAP { get; set; }
public List<Oferta> Ofertas { get; set; } = new List<Oferta>();
}
public class Oferta
{
[StringLength(maximumLength:6)]
public string Id { get; set; }
[StringLength(maximumLength: 5)]
public string IdPresentada { get; set; }
....
public List<Licitador> Licitadores { get; set; } = new List<Licitador>();
}
And the join table in the context
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LicitacionesEnSolitario>().ToTable("LicitacionesSolitario");
modelBuilder.Entity<Licitador>()
.HasMany(o => o.Ofertas)
.WithMany(of => of.Licitadores)
.UsingEntity<LicitacionesEnSolitario>
(oo => oo.HasOne<Oferta>().WithMany(),
oo => oo.HasOne<Licitador>().WithMany())
.Property(oo => oo.Adjudicado)
.IsRequired();
}
I need this data in my entity/table LicitacionesEnSolitario in addition to PK y FK
public class LicitacionesEnSolitario
{
public int LicitadorId { get; set; }
public string OfertaId { get; set; }
public bool Adjudicado { get; set; }
public string Plazo { get; set; }
public decimal PresupuestoOfertado { get; set; }
public DateTime? FechaAdjudicacion { get; set; }
}
Here I insert the data importing them from another database
public int ImportarLicitacionesEnSolitario()
{
try
{
int registrosAñadidos = 0;
var registrosSAP = _contextSAP.LicitacionesEnSolitario
.FromSqlRaw("sql")
.ToList();
foreach (var registroSAP in registrosSAP)
{
var oferta = _contextBoletus.Ofertas.Find(registroSAP.OfertaId);
var licitador = _contextBoletus.Licitadores.Where(l => l.CodigoSAP == registroSAP.CodigoSAP).FirstOrDefault();
oferta.Licitadores.Add(licitador);
registrosAñadidos +=1;
}
_contextBoletus.SaveChanges();
return registrosAñadidos;
}
catch (Exception ex)
{
throw ex;
}
}
This works fine and insert data in "LicitacionesEnSolitario" but with this fields Adjudicado, Plazo, PresupuestoPfertado y FechaAdjudicacion with nulls.
I don't know how to insert them at the time I insert Licitadores and if I try to update after the Add method using the PKs I just added
foreach (var registroSAP in registrosSAP)
{
var oferta = _contextBoletus.Ofertas.Find(registroSAP.OfertaId);
var licitador = _contextBoletus.Licitadores.Where(l => l.CodigoSAP == registroSAP.CodigoSAP).FirstOrDefault();
oferta.Licitadores.Add(licitador);
var ls = _contextBoletus.Set<LicitacionesEnSolitario>()
.SingleOrDefault(ls => ls.OfertaId == oferta.Id & ls.LicitadorId == licitador.Id);
ls.Adjudicado = registroSAP.Adjudicado;
ls.PresupuestoOfertado = registroSAP.PresupuestoOfertado;
ls.FechaAdjudicacion = registroSAP.FechaAdjudicacion;
registrosAñadidos +=1;
}
_contextBoletus.SaveChanges();
return registrosAñadidos;
I get this error System.NullReferenceException: Object reference not set to an instance of an object.
Any idea, please?
Thanks
This is the best way I found
foreach (var registroSAP in registrosSAP)
{
var oferta = _contextBoletus.Ofertas.Find(registroSAP.OfertaId);
var licitador = _contextBoletus.Licitadores.Where(l => l.CodigoSAP == registroSAP.CodigoSAP).FirstOrDefault();
var ls = _contextBoletus.Set<LicitacionesEnSolitario>().Add(
new LicitacionesEnSolitario
{
LicitadorId = licitador.Id,
OfertaId = oferta.Id,
Adjudicado = registroSAP.Adjudicado,
Plazo = registroSAP.Plazo,
PresupuestoOfertado = registroSAP.PresupuestoOfertado,
FechaAdjudicacion = registroSAP.FechaAdjudicacion
});
registrosAñadidos += 1;
}
Thanks

How to consume an external api rest?

I need to consume a Rest API from an ERP Site, where I will list some items from this site, but I do not find anything useful that can help me to consume
I am using json and http client to perform, but the error in the process recognize the site path
public partial class ProdutoPage : ContentPage
{
ListView lv = new ListView();
public ProdutoPage()
{
InitializeComponent();
iniciar();
}
private async void iniciar()
{
//tinyapp API = new tinyapp();
//var lista = API.ListaCategorias("automacao");
var client = new HttpClient();
client.DefaultRequestHeaders.Add("token", "");
client.BaseAddress = new Uri("https://api.tiny.com.br/api2/pedidos.pesquisa.php/");
var resp = await client.GetAsync("pedidos.pesquisa.php/");
if (resp.IsSuccessStatusCode)
{
var respStr = await resp.Content.ReadAsStringAsync();
var l = JsonConvert.DeserializeObject<List<Pedido>>(respStr);
lv.ItemsSource = l;
}
}
}
}
I need a list of ERP site requests
in ASP.Net has no error, but in xamarim it does not have the using System.Web.Script.Serialization to enable javascript
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Script.Serialization;
using System.Xml.Linq;
namespace mia.Webservices
{
public class TinyAPI
{
private const string URL_PEDIDOS = "https://api.tiny.com.br/api2/pedidos.pesquisa.php/";
private const string URL_OBTER_PEDIDO = "https://api.tiny.com.br/api2/pedido.obter.php/";
private string parametros = "?formato=json";
private string token_solucoes = "";
private string token_automacao = "";
/// <summary>
/// ListaPedidos é um método que lista todos os pedidos do Tiny de acordo com os parâmetros data inicial e data final.
/// </summary>
public List<Pedido> ListaPedidos(string empresa, string situacao, string data_inicial, string data_final)
{
int pagina = 1;
string token = "";
if (empresa.Equals("automacao"))
{
token = token_automacao;
}
else
{
if (empresa.Equals("solucoes"))
{
token = token_solucoes;
}
}
HttpClient client = new HttpClient();
var baseAddress = new Uri(URL_PEDIDOS);
client.BaseAddress = baseAddress;
List<Pedido> pedidos = new List<Pedido>();
HttpResponseMessage response = null;
if (data_inicial != null && data_inicial != "" && data_final != null && data_final != "")
{
response = client.GetAsync(parametros + "&token=" + token + "&dataInicial=" + data_inicial + "&dataFinal=" + data_final + "&situacao=" + situacao).Result;
}
else
{
response = client.GetAsync(parametros + "&pagina=" + pagina + "&token=" + token).Result;
}
string json = response.Content.ReadAsStringAsync().Result;
Dictionary<string, object> userObject = new JavaScriptSerializer().DeserializeObject(json) as Dictionary<string, object>;
if (userObject.ContainsKey("retorno"))
{
Object meta = userObject["retorno"];
Dictionary<string, object> dic_meta = (Dictionary<string, object>)meta;
if (dic_meta.ContainsKey("numero_paginas"))
{
int total_count = (int)dic_meta["numero_paginas"];
while (total_count >= pagina)
{
HttpResponseMessage response_2 = null;
if (data_inicial != null && data_inicial != "" && data_final != null && data_final != "")
{
response_2 = client.GetAsync(parametros + "&token=" + token + "&dataInicial=" + data_inicial + "&dataFinal=" + data_final + "&situacao=" + situacao).Result;
}
else
{
response_2 = client.GetAsync(parametros + "&pagina=" + pagina + "&token=" + token).Result;
}
string json_2 = response_2.Content.ReadAsStringAsync().Result;
Dictionary<string, object> userObject_2 = new JavaScriptSerializer().DeserializeObject(json_2) as Dictionary<string, object>;
Dictionary<string, object> objetos = (Dictionary<string, object>)userObject_2["retorno"];
if (objetos.ContainsKey("pedidos"))
{
Object[] pedidos_list = (Object[])objetos["pedidos"];
foreach (var item in pedidos_list)
{
Dictionary<string, object> pre_lista_pedidos = (Dictionary<string, object>)item;
Dictionary<string, object> list_pedidos = (Dictionary<string, object>)pre_lista_pedidos["pedido"];
Pedido pedido = new Pedido();
pedido.situacao = (string)list_pedidos["situacao"];
pedido.id = (string)list_pedidos["id"];
pedido.numero = (string)list_pedidos["numero"];
pedido.numero_ecommerce = (string)list_pedidos["numero_ecommerce"];
pedido.data_pedido = (string)list_pedidos["data_pedido"];
pedido.data_prevista = (string)list_pedidos["data_prevista"];
pedido.nome = (string)list_pedidos["nome"];
pedido.valor = (string)list_pedidos["valor"].ToString();
pedido.id_vendedor = (string)list_pedidos["id_vendedor"];
pedido.nome_vendedor = (string)list_pedidos["nome_vendedor"];
pedido.codigo_rastreamento = (string)list_pedidos["codigo_rastreamento"];
pedido.url_rastreamento = (string)list_pedidos["url_rastreamento"];
pedidos.Add(pedido);
}
}
total_count -= 1;
}
}
}
return pedidos;
}
}
This works:
var client = new HttpClient();
client.DefaultRequestHeaders.Add("token", "0dbffc6cbb412c01a90431f07631c0e00f2889d4");
client.BaseAddress = new Uri("https://api.tiny.com.br/api2/");
var resp = client.GetAsync("pedidos.pesquisa.php").GetAwaiter().GetResult();
After a research I discovered your API requires POST to return data:
var client = new HttpClient();
client.BaseAddress = new Uri("https://api.tiny.com.br/api2/");
var parameters = new Dictionary<string, string> { { "token", "0dbffc6cbb412c01a90431f07631c0e00f2889d4" } };
var encodedContent = new FormUrlEncodedContent(parameters);
var resp = await client.PostAsync("pedidos.pesquisa.php", encodedContent);
var respStr = await resp.Content.ReadAsStringAsync();
> var client = new HttpClient();
client.BaseAddress = new Uri("https://api.tiny.com.br/api2/");
var resp = client.GetAsync("pedidos.pesquisa.php?token=********&formato=json").Result;
if (resp.IsSuccessStatusCode)
{
var respStr = resp.Content.ReadAsStringAsync().Result;
var l = JsonConvert.DeserializeObject<List<Pedido>>(respStr);
lv.ItemsSource = l;
}`
doing so he located the token, but an error in Json, follows an example of json from the Pedido list
{
"retorno": {
"status_processamento": 3,
"status": "OK",
"pagina": "1",
"numero_paginas": "1",
"pedidos": [
{
"pedido": {
"id": 123456,
"numero": 123456,
"numero_ecommerce": "12",
"data_pedido": "01/01/2013",
"data_prevista": "10/01/2013",
"nome": "Cliente Teste",
"valor": "100.25",
"id_vendedor": "123456",
"nome_vendedor": "Vendedor Teste",
"situacao": "Atendido"
}
},
{
"pedido": {
"id": 123456,
"numero": 123458,
"numero_ecommerce": "15",
"data_pedido": "01/01/2013",
"data_prevista": "10/01/2013",
"nome": "Cliente Teste 3",
"valor": "50.25",
"id_vendedor": "",
"nome_vendedor": "",
"situacao": "Aberto"
}
}
]
}
}
error Newtonsoft.Json.JsonSerializationException:
pedido class
public class Pedido
{
public string id { get; set; }
public string numero { get; set; }
public string numero_ecommerce { get; set; }
public string data_pedido { get; set; }
public string data_prevista { get; set; }
public string nome { get; set; }
public string valor { get; set; }
public string id_vendedor { get; set; }
public string nome_vendedor { get; set; }
public string situacao { get; set; }
public string codigo_rastreamento { get; set; }
public string url_rastreamento { get; set; }
public string data_faturamento { get; set; }
public Cliente cliente { get; set; }
public List<Produto_Servico> produtos_servicos { get; set; }
}
Class Pedidos
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace MacVendas.Models.API
{
public class Pedido
{
public class Pedido2
{
public string id { get; set; }
public string numero { get; set; }
public string numero_ecommerce { get; set; }
public string data_pedido { get; set; }
public string data_prevista { get; set; }
public string nome { get; set; }
public string valor { get; set; }
public string id_vendedor { get; set; }
public string nome_vendedor { get; set; }
public string situacao { get; set; }
public string codigo_rastreamento { get; set; }
public string url_rastreamento { get; set; }
}
public class Pedido1
{
public string pedido { get; set; }
}
public class Retorno
{
public string status_processamento { get; set; }
public string status { get; set; }
public string pagina { get; set; }
public string numero_paginas { get; set; }
public List<Pedido1> pedidos { get; set; }
}
public class RootObject
{
public Retorno retorno { get; set; }
}
}
}
I was able to read the list of categories that is smaller
using System;
using System.Collections.Generic;
using System.Text;
namespace MacVendas.Models.API
{
public class Categoria
{
public class Retorno
{
public string id { get; set; }
public string descricao { get; set; }
public List<object> nodes { get; set; }
}
public class RootObject
{
public List<Retorno> retorno { get; set; }
}
}
}
Produtopagexaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using MacVendas.Classes;
//using macvendas.services;
using MacVendas.Models.API;
using Newtonsoft.Json;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace MacVendas.Pages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ProdutoPage : ContentPage
{
public ProdutoPage()
{
InitializeComponent();
Iniciar();
}
private void Iniciar()
{
var client = new HttpClient();
var resp = client.GetAsync("https://api.tiny.com.br/api2/produtos.categorias.arvore.php?token=*****&formato=json").Result;
string respStr = resp.Content.ReadAsStringAsync().Result;
Categoria.RootObject ObjPedidotList = new Categoria.RootObject ();
if (respStr != "")
{
ObjPedidotList = JsonConvert.DeserializeObject<Categoria.RootObject>(respStr);
}
//Binding listview with server response
listviewConacts.ItemsSource = ObjPedidotList.retorno;
}
}
}
produto.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MacVendas.Pages.ProdutoPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Margin="10" Text="JSON Parsing" FontSize="25" />
<ListView x:Name="listviewConacts" Grid.Row="1" HorizontalOptions="FillAndExpand" HasUnevenRows="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding descricao}" HorizontalOptions="StartAndExpand" Grid.Row="0" TextColor="Blue" FontAttributes="Bold"/>
<!--<Label Text="{Binding numero}" HorizontalOptions="StartAndExpand" Grid.Row="1" TextColor="Orange" FontAttributes="Bold"/>
<Label Text="{Binding valor}" HorizontalOptions="StartAndExpand" Grid.Row="2" TextColor="Gray" FontAttributes="Bold"/>-->
<BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" Grid.Row="3" HorizontalOptions="FillAndExpand" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ContentPage>

Crystal Report Error: The data source object is invalid

Am Trying to Print out a student Identity Card using crystal report but all what i could get was this error popping up The data source object is invalid.
Guys please help me to check on this code if am making any mistake...
this is the model
public class CardModel
{
// Properties
public string Department { get; set; }
public string ExpiryDate { get; set; }
public string FirstName { get; set; }
public Sex Gender { get; set; }
public Guid Id { get; set; }
public string MiddleName { get; set; }
public string RegistrationNo { get; set; }
public byte[] SecuritySign { get; set; }
public byte[] StudentPhoto { get; set; }
public string Surname { get; set; }
}
public static class CardModelExtention
{
public static CardModel ToCardModel(this Student identity)
{
return new CardModel
{
Id = identity.Id,
FirstName = identity.FirstName,
MiddleName = identity.MiddleName,
Surname = identity.Surname,
StudentPhoto = identity.Photo.RawPhoto,
SecuritySign = identity.SecuritySignature.RawSignature,
Gender = identity.Sex,
ExpiryDate = identity.ExpiryDate,
Department = identity.Department.DepartmentName,
RegistrationNo = identity.RegistrationNo
};
}
}
and here is the service am using to pull the information from database
public class StudentService : IStudentService
{
ERMUoW _ow;
public StudentService()
{
_ow = new ERMUoW();
}
public CardModel GetStudentById(Guid id)
{
CardModel obj3 = new CardModel();
Student student = _ow.Students.GetAllIncluding(new Expression<Func<Student, object>>[] { st => st.Photo, st => st.Signature, st => st.SecuritySignature, st => st.Department }).Where(x => x.Id == id).SingleOrDefault();
var cardInfo = student.ToCardModel();
return cardInfo;
}
}
public interface IStudentService
{
CardModel GetStudentById(Guid id);
}
This is it and everything around here is working fine and am getting the data very well but when I send it to the method in my contrller that generate the identity card I get that error message
this is the code that generate the card using crytal report
public ActionResult PrintCard(Guid id)
{
var student = _studentCardService.GetStudentById(id);
ReportDocument read = new ReportDocument();
read.Load(Server.MapPath("~/Reports/rpt_StudentCard.rpt"));
read.SetDataSource(student);
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
try
{
Stream stream = read.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", "StudentIdentityCard.pdf");
}
catch (Exception ex)
{
throw ex;
}
}
I will really Appreciate your help thank you...
The data source have to be a List of elements... not a single element.

Custom RoleProvider and Custom Membership provider

I am working on an MVC4 application that has authentication completed by ADFS before the application is launched and will only be launched by successfully authenticated users. Within the application itself I have a list of users held within the following class:
public class MyAppUser : IPrincipal
{
[Key]
public int UserID { get; set; }
[StringLength(128)]
public string Username { get; set; }
public int ParticipationPoints { get; set; }
public DateTime JoinDate { get; set; }
public DateTime LastLogin { get; set; }
//1-to-1 Mappings
public int? CompanyID { get; set; }
public virtual Company Company { get; set; }
public int? ProfileID { get; set; }
public virtual Profile Profile { get; set; }
public int? SocialID { get; set; }
public virtual SocialMedia Social { get; set; }
public int? RoleID { get; set; }
public virtual Role Role { get; set; }
//1-to-many Mappings
public virtual ICollection<Block> Blocks { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<CategoryMap> CategoryMaps { get; set; }
public virtual ICollection<Feedback> Feedbacks { get; set; }
public virtual ICollection<Survey> Surveys { get; set; }
public virtual ICollection<Friend> Friends { get; set; }
public virtual ICollection<Participation> Participations { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual ICollection<Target> Targets { get; set; }
public virtual ICollection<CourseStatus> CourseStatuses { get; set; }
public virtual ICollection<Objective> Objectives { get; set; }
public virtual ICollection<UserCourseInfo> UserCourseInfos { get; set; }
public IIdentity Identity { get; set; }
public bool IsInRole(string role)
{
if (this.Role.Name == role)
{
return true;
}
return false;
}
}
I have created a custom role provider that is tied to my dbcontext as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration.Provider;
using MyApp.Data;
using MyApp.ViewModels;
namespace MyApp.Providers
{
public class MyAppProvider : System.Web.Security.SqlRoleProvider
{
private MyAppContext dbcontext = new MyAppContext(System.Configuration.ConfigurationManager.ConnectionStrings["MyAppContext"].ConnectionString);
private Repository<MyAppUser> userRepository;
private Repository<Role> roleRepository;
public MyAppProvider()
{
this.userRepository = new Repository<MyAppUser>(dbcontext);
this.roleRepository = new Repository<Role>(dbcontext);
}
public override string[] GetAllRoles()
{
IEnumerable<Role> dbRoles = roleRepository.GetAll();
int dbRolesCount = roleRepository.GetAll().Count();
string[] roles = new string[dbRolesCount];
int i = 0;
foreach(var role in dbRoles)
{
roles[i] = role.Name;
i++;
}
return roles;
}
public string[] GetAllUsers()
{
IEnumerable<MyAppUser> dbUsers = userRepository.GetAll();
int dbUsersCount = userRepository.GetAll().Count();
string[] users = new string[dbUsersCount];
int i = 0;
foreach (var user in dbUsers)
{
users[i] = user.Username;
i++;
}
return users;
}
public override bool RoleExists(string roleName)
{
string[] roles = { "Admin", "User", "BobsBusiness" };
if(roles.Contains(roleName))
return true;
else
return false;
}
public override void CreateRole(string roleName)
{
Role newRole = new Role();
newRole.Name = roleName;
roleRepository.Add(newRole);
roleRepository.SaveChanges();
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
foreach (var username in usernames)
{
MyAppUser user = userRepository.Get(u => u.Username == username).FirstOrDefault();
foreach (var rolename in roleNames)
{
Role role = roleRepository.Get(r => r.Name == rolename).FirstOrDefault();
user.RoleID = role.RoleID;
userRepository.Add(user);
userRepository.SaveChanges();
}
}
}
public override string[] GetRolesForUser(string username)
{
MyAppUser user = userRepository.Get(u => u.Username == username).FirstOrDefault();
if (user == null)
{
string[] roles = new string[1];
roles[0] = "Fail";
return roles;
}
else
{
Role role = roleRepository.Get(r => r.RoleID == user.RoleID).FirstOrDefault();
if (role == null)
{
string[] roles = new string[1];
roles[0] = "Fail";
return roles;
}
else
{
string[] roles = new string[1];
roles[0] = role.Name;
return roles;
}
}
}
public override bool IsUserInRole(string userName, string roleName)
{
MyAppUser user = userRepository.Get(u => u.Username == userName).FirstOrDefault();
if (user == null)
throw new ProviderException("Username cannot be empty or null.");
Role role = roleRepository.Get(r => r.Name == roleName).FirstOrDefault();
if (role == null)
throw new ProviderException("Role name cannot be empty or null.");
if (user.RoleID == role.RoleID)
return true;
else
return false;
}
}
}
Now I have tried to create a CustomMembershipProvider but I am unsure how to tie this to the dbcontext and the MyAppUser that I have created. Due to the authentication type we do not have an AccountController and so simpleMembership is not an option. I have created the abstract class for the custom membership provider as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MyApp.Data;
namespace MyApp.Providers
{
public class MyAppMembershipProvider : System.Web.Security.MembershipProvider
{
private MyAppContext dbcontext = new MyAppContext(System.Configuration.ConfigurationManager.ConnectionStrings["MyAppContext"].ConnectionString);
private Repository<MyAppUser> userRepository;
public MyAppUser User { get; private set; }
public MyAppMembershipProvider()
{
this.userRepository = new Repository<MyAppUser>(dbcontext);
User = userRepository.Get(u => u.Username == "jpmcfeely").FirstOrDefault();
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override System.Web.Security.MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out System.Web.Security.MembershipCreateStatus status)
{
throw new NotImplementedException();
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
throw new NotImplementedException();
}
public override bool EnablePasswordReset
{
get { throw new NotImplementedException(); }
}
public override bool EnablePasswordRetrieval
{
get { throw new NotImplementedException(); }
}
public override System.Web.Security.MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override System.Web.Security.MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override System.Web.Security.MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override int GetNumberOfUsersOnline()
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override System.Web.Security.MembershipUser GetUser(string username, bool userIsOnline)
{
//throw new NotImplementedException();
MyAppUser user = userRepository.Get(u => u.Username == username).FirstOrDefault();
return GetUser(username, true);
}
public override System.Web.Security.MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
throw new NotImplementedException();
}
public override string GetUserNameByEmail(string email)
{
throw new NotImplementedException();
}
public override int MaxInvalidPasswordAttempts
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredNonAlphanumericCharacters
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredPasswordLength
{
get { throw new NotImplementedException(); }
}
public override int PasswordAttemptWindow
{
get { throw new NotImplementedException(); }
}
public override System.Web.Security.MembershipPasswordFormat PasswordFormat
{
get { throw new NotImplementedException(); }
}
public override string PasswordStrengthRegularExpression
{
get { throw new NotImplementedException(); }
}
public override bool RequiresQuestionAndAnswer
{
get { throw new NotImplementedException(); }
}
public override bool RequiresUniqueEmail
{
get { throw new NotImplementedException(); }
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool UnlockUser(string userName)
{
throw new NotImplementedException();
}
public override void UpdateUser(System.Web.Security.MembershipUser user)
{
throw new NotImplementedException();
}
public override bool ValidateUser(string username, string password)
{
throw new NotImplementedException();
}
}
}
I would be very grateful for any tips anyone has in connecting the MyAppUser to the custom membership provider.
Assuming that the application authenticates users via ADFS, your role provider and membersh provider have nothing to do. Completely. The identity together with roles is passed to the application by the ADFS.
What you possibly could do is to have a custom ClaimsAuthenticationmanager. I've blogged on that some time ago:
http://netpl.blogspot.com/2012/09/sessionauthenticationmodule-and-dynamic.html
As I was already authenticated by ADFS I had gotten the username in the claims and held it in session variable. I then used this session variable to call my database user with the GetRolesForUser method that I had overriden. Works great not too much effort.