using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsistec.Domain;
using Microsistec.Client;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using Microsistec.Tools;
using System.Json;
using Microsistec.SystemConfig;
using System.Threading;
using Microsoft.Silverlight.Testing;
namespace Test
{
[TestClass]
public class SampleTest : SilverlightTest
{
[TestMethod, Asynchronous]
public void login()
{
List<PostData> data = new List<PostData>();
data.Add(new PostData("email", "xxx"));
data.Add(new PostData("password", MD5.GetHashString("xxx")));
WebClient.sendData(Config.DataServerURL + "/user/login", data, LoginCallBack);
EnqueueCallback(?????????);
EnqueueTestComplete();
}
[Asynchronous]
public void LoginCallBack(object sender, System.Net.UploadStringCompletedEventArgs e)
{
string json = Microsistec.Client.WebClient.ProcessResult(e);
var result = JsonArray.Parse(json);
Assert.Equals("1", result["value"].ToString());
TestComplete();
}
}
Im tring to set ???????? value but my callback is generic, it is setup on my WebClient .SendData, how i implement my EnqueueCallback to a my already functio LoginCallBack???
You have to take a different approach to make this work. Why do you want to enqueue LoginCallBack? It would get called asynchronously when sendData has ended, would it not?
Also, I see no point in having a TestComplete() in LoginCallBack and EnqueueTestComplete() in login. Would this not work:
[TestClass]
public class SampleTest : SilverlightTest
{
[TestMethod, Asynchronous]
public void login()
{
List<PostData> data = new List<PostData>();
data.Add(new PostData("email", "xxx"));
data.Add(new PostData("password", MD5.GetHashString("xxx")));
WebClient.sendData(Config.DataServerURL + "/user/login", data, LoginCallBack);
}
[Asynchronous]
public void LoginCallBack(object sender, System.Net.UploadStringCompletedEventArgs e)
{
string json = Microsistec.Client.WebClient.ProcessResult(e);
var result = JsonArray.Parse(json);
Assert.Equals("1", result["value"].ToString());
TestComplete();
}
}
I'm unsure of how LoginCallback gets called but if you make sure that that happens it should make the test pass!
Related
In Xamarin Forms 4.3, I'm following this "Local Databases" doc: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/data/databases
This doc explains how to create and use a new sqlite db, but how do I go about in loading and displaying data in an existing .db file with the end purpose of transferring it into a new local sqlite database?
using SQLite;
namespace TruckExample.Models
{
public class Truck
{
[PrimaryKey, AutoIncrement]
public int TruckNo { get; set; }
public string TruckName { get; set; }
}
}
//////////////////////////////////////////////
using System.Collections.Generic;
using System.Threading.Tasks;
using SQLite;
using TruckExample.Models;
namespace TruckExample.Data
{
public class TruckDatabase
{
readonly SQLiteAsyncConnection _database;
public TruckDatabase(string dbPath)
{
_database = new SQLiteAsyncConnection(dbPath);
_database.CreateTableAsync<Truck>().Wait();
}
public Task<List<Truck>> GetTrucksAsync()
{
return _database.Table<Truck>().ToListAsync();
}
}
}
////////////////////////////////////////////////
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TruckExample.Data;
using System.IO;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace TruckExample
{
public partial class App : Application
{
static TruckDatabase database;
public static TruckDatabase Database
{
get
{
if(database == null)
{
database = new TruckDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Truck.db"));
}
return database;
}
}
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
}
}
/////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TruckExample
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
public MainPage ()
{
InitializeComponent ();
}
protected override async void OnAppearing()
{
base.OnAppearing();
listView.ItemsSource = await App.Database.GetTrucksAsync();
Debug.Write(App.Database.GetTrucksAsync());
}
}
}
For others, helpful resources:
Implementation by Hameed Kunkanoor: "Creating a sqlite databse and storing your data in your android and ios application in Xamarin Forms" https://medium.com/#hameedkunkanoor/creating-a-sqlite-databse-and-storing-your-data-in-your-android-and-ios-application-in-xamarin-2ebaa79cdff0
(Refer to his git if needed)
Explanation/response by Matthewrdev: Use a local database in Xamarin
To improve the implementation -- Brandon Minnick: "Xamarin: Efficiently Using a SQLite Database" https://codetraveler.io/2019/11/26/efficiently-initializing-sqlite-database/
I was needing to make a post or put a validation on the server side to check if the email is unique.
In the research I have always done the example was a traditional MVC application and never an api.
In many cases I saw that the [Remote] https://learn.microsoft.com/pt-br/aspnet/core/mvc/models/validation?view=aspnetcore-2.2#remote-attribute . I tried to implement according to the documentation, but debugging verified that the function in the controller is neither called.
User.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Mvc;
namespace Base.Models
{
[Table("users")]
public partial class User
{
...
[Required]
[EmailAddress]
[Remote(action: "VerifyEmail", controller: "UserController",ErrorMessage="Email already in use")]
[Column("email", TypeName = "varchar(254)")]
public string Email { get; set; }
...
}
}
UserController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Base.Models;
namespace Base.Controllers
{
[Route("api/users")]
[ApiController]
public class UserController : Controller
{
...
[AcceptVerbs("Get")]
public IActionResult VerifyEmail(string email)
{
//forcing it to go wrong
return Json($"Email {email} is already in use.");
}
...
}
}
Anyone have any idea how to implement this?
Seeing that it was not progressing, I decided to do a personalized validation.
EmailUserUniqueAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using Base.Models;
namespace Core.Models
{
public class EmailUserUniqueAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
var _context = (AppDbContext)validationContext.GetService(typeof(AppDbContext));
var entity = _context.Users.SingleOrDefault(e => e.Email == value.ToString());
if (entity != null)
{
return new ValidationResult(GetErrorMessage(value.ToString()));
}
return ValidationResult.Success;
}
public string GetErrorMessage(string email)
{
return $"Email {email} is already in use.";
}
}
}
User.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Mvc;
namespace Base.Models
{
[Table("users")]
public partial class User
{
...
[Required]
[EmailAddress]
[EmailUserUnique]
[Column("email", TypeName = "varchar(254)")]
public string Email { get; set; }
}
}
...
It works, but I don't know if this is the best way to do this.
I cant comment cause I lack the sufficient reputation, and if I had time I would had gone and verified but I think your issue here is the [Route("api/users")].
You are giving your decorator the Controller name but that controller is behind a different route. Easy debug of that will be to remove the Route temporarily OR put the "VerifyEmail" action to another controller that you arent altering its route.
So i'm making a basic yahtzee program i c#, and im trying to make an actual gui and not just use the console. However i have a problem with the textbox. When i roll the dice, i want the textbox to display the number rolled. Now it shows nothing. I use two classes, one for the actual program and one for handling the gui. This is the yahtzee class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Yahtzee
{
class YahtzeeScorer {
Random rndm = new Random();
Form1 gui = new Form1();
String dice1, dice2, dice3, dice4, dice5;
public void rollDice()
{
String a = Console.ReadLine();
this.dice1 = rndm.Next(1, 7).ToString();
this.gui.tbDice_SetText(this.dice1);
}
static void Main(String[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
YahtzeeScorer ys = new YahtzeeScorer();
Application.Run(ys.gui);
ys.rollDice();
Console.WriteLine("The result was: " + ys.dice1 );
Console.Read();
}
}
}
And this is the gui class form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Yahtzee
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void tbDice_SetText(String s)
{
//this.ActiveControl = tbDice;
Console.WriteLine("SetText");
tbDice.Text = s;
}
public void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
tbDice is the name of the textbox component. Any ideas?
Examine the lines:
Application.Run(ys.gui);
ys.rollDice();
rollDice() will not be called until the application exits, because the thread running Main() will block on Application.Run() until it does.
Instead, try calling ys.rollDice() in something like a button event handler.
UPDATE
You are mixing your game logic and your presentation logic by putting both aspects in YahtzeeScorer. I would suggest that you move the game logic into a separate class like this:
public class YahtzeeGame
{
public string rollDice()
{
return rndm.Next(1, 7).ToString();
}
}
public partial class Form1 : Form
{
YahtzeeGame game = new YahtzeeGame();
public Form1()
{
InitializeComponent();
}
// You need to create a new Button on your form called btnRoll and
// add this as its click handler:
public void btnRoll_Clicked(object sender, EventArgs e)
{
tbDice.Text = game.rollDice();
}
}
I'm a beginner programmer in C#, so I think that the solution of my question might be easy, but after looking for it for days, I have not found anything that worked for me.
I have a WP7 app that contains a DB created with SQL CE.
CLASS PorniBD.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data.Linq.Mapping;
namespace PhoneClassLibrary1
{
[Table(Name = "Papilleros")]
public class PorniBD
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int Id { get; set; }
[Column(CanBeNull = false)]
public String Nombre { get; set; }
[Column(CanBeNull = false)]
public String FechaNac { get; set; }
[Column(CanBeNull = false)]
public Boolean Activo { get; set; }
[Column(CanBeNull = false)]
public String Icono { get; set; }
}
}
CLASS PorniContext.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data.Linq.Mapping;
using System.Data.Linq;
namespace PhoneClassLibrary1
{
public class PorniContext : DataContext
{
public PorniContext(string connectionString) : base(connectionString)
{
//
}
public Table<PorniBD> Papilleros
{
get
{
return this.GetTable<PorniBD>();
}
}
}
}
My app has a background agent created in another project like I have learned in this page: Link
Now, I need to read app DB from background agent, and this class contains following OnInvoke void:
protected override void OnInvoke(ScheduledTask task)
{
List<PorniBD> listapapilleros = new List<PorniBD>();
using (PorniContext basedatos = new PorniContext("Data Source='isostore:/basedatos.sdf'"))
{
listapornis = basedatos.Papilleros.ToList();
}
// Launch a toast to show that the agent is running.
// The toast will not be shown if the foreground application is running.
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(10));
NotifyComplete();
}
but it's impossible because DataSource isolated is different in each project (I think), and I suppose that it's necessary to fix something more...
Thanks a lot for your help, and sorry if my English level is makes my explanation a bit difficult to understand...
Simply create a third project, of type "Windows Phone Class Library". Move your database code in that third project, then reference it from both your main project and your background agent project.
I have created a very simple winform app that has a single form and a single button on it. Its click event is wired up as shown below. If you click the button, the app behaves as expected ie the ExecTasks exits. If you replace the lock statement by lock(this), ExecTasks will not exit and the debugger shows a thread in a sleep/wait/join at the code in Exec. Question why does the choice of locking object change this behaviour - why is the form instance not a valid choice ?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TestDeadlock
{
public partial class Form1 : Form
{
private object _lock = new object();
public Form1()
{
InitializeComponent();
}
private void Button1Click(object sender, EventArgs e)
{
Task.Factory.StartNew(ExecTasks);
}
private void ExecTasks()
{
lock (_lock) /* replace by lock(this) to see the blocked behavior */
{
var taskList = new List<Task>();
for (var i = 0; i < 2; ++i)
{
taskList.Add(Task.Factory.StartNew(Exec));
}
Task.WaitAll(taskList.ToArray());
}
}
private void Exec()
{
Invoke((Action)delegate{});
}
}
}
I see this blocking behavior. When you call the Invoke method, it result in calling the Control.FindMarshalingControl method which is implemented as follows:
private Control FindMarshalingControl()
{
lock (this)
{
Control parentInternal = this;
....
}
}
Here is a link on a similar issue:
Control.BeginInvoke will also be blocked