I want to declare the following things:
var simlBot = new SimlBot();
var botUser = simlBot.CreateUser();
var packageString = File.ReadAllText("SIMLPackage.simlpk");
simlBot.PackageManager.LoadFromString(packageString);
If I declare it directly in the class I get: "The contextual keyword 'var' may only appear within a local variable declaration or in script code"
I can't declare it inside an if statement because I can't access it from outside.
if (hasBotBeenCreated == false)
{
var simlBot = new SimlBot();
var botUser = simlBot.CreateUser();
var packageString = File.ReadAllText("SIMLPackage.simlpk");
simlBot.PackageManager.LoadFromString(packageString);
}
I need to use the following form inside a function:
var chatRequest = new ChatRequest(textReceived, botUser);
var chatResult = simlBot.Chat(chatRequest);
What can I do? The problem is that the last snippet of code can't access botUser and simlBot. The way I have it working now is recreating the object every time the function is called, but that takes a lot of time.
My complete code is
public partial class Form1 : Form
{
string textEntered = "";
string response = "";
SpeechSynthesizer synth = new SpeechSynthesizer();
bool hasBotBeenCreated = false;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textEntered = textBox1.Text;
textBox1.Text = "";
if (textEntered != "")
{
sendToAI(textEntered);
}
}
void sendToAI(string textReceived)
{
listBox1.Items.Add(textEntered);
response = getResponse(textEntered);
listBox1.Items.Add(response);
synth.Speak(response);
}
string getResponse(string textReceived)
{
if (hasBotBeenCreated == false)
{
var simlBot = new SimlBot();
var botUser = simlBot.CreateUser();
var packageString = File.ReadAllText("SIMLPackage.simlpk");
simlBot.PackageManager.LoadFromString(packageString);
}
var chatRequest = new ChatRequest(textReceived, botUser);//These two can't access the objects created above
var chatResult = simlBot.Chat(chatRequest);
if (chatResult.Success)
{
var botMessage = chatResult.BotMessage;
return botMessage;
}
else
{
return "I don't have a response for that";
}
}
}
Revision 2:
string getResponse(string textReceived)
{
SimlBot simlBot;
BotUser botUser;
if (hasBotBeenCreated == false)
{
simlBot = new SimlBot();
botUser = simlBot.CreateUser();
var packageString = File.ReadAllText("SIMLPackage.simlpk");
simlBot.PackageManager.LoadFromString(packageString);
}
var chatRequest = new ChatRequest(textReceived, botUser); //These get the error
var chatResult = simlBot.Chat(chatRequest);
if (chatResult.Success)
{
var botMessage = chatResult.BotMessage;
return botMessage;
}
else
{
return "I don't have a response for that";
}
}
Add the members:
SimlBot simlBot;
WhatEverTypeOfCreateUserIs botUser;
Then initialize them:
if (hasBotBeenCreated == false)
{
simlBot = new SimlBot();
botUser = simlBot.CreateUser();
....
}
---------- Full Code ----------
public partial class Form1 : Form
{
string textEntered = "";
string response = "";
SpeechSynthesizer synth = new SpeechSynthesizer();
bool hasBotBeenCreated = false;
SimlBot simlBot;
BotUser botUser;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textEntered = textBox1.Text;
textBox1.Text = "";
if (textEntered != "")
{
sendToAI(textEntered);
}
}
void sendToAI(string textReceived)
{
listBox1.Items.Add(textEntered);
response = getResponse(textEntered);
listBox1.Items.Add(response);
synth.Speak(response);
}
string getResponse(string textReceived)
{
if (hasBotBeenCreated == false)
{
simlBot = new SimlBot();
botUser = simlBot.CreateUser();
var packageString = File.ReadAllText("SIMLPackage.simlpk");
simlBot.PackageManager.LoadFromString(packageString);
}
var chatRequest = new ChatRequest(textReceived, botUser);//These two can't access the objects created above
var chatResult = simlBot.Chat(chatRequest);
if (chatResult.Success)
{
var botMessage = chatResult.BotMessage;
return botMessage;
}
else
{
return "I don't have a response for that";
}
}
}
Related
Why textBox3.text do not shows value _TextBoxRequestMsg. MessageBox opens and shows _TextBoxRequestMsg value OK, console prints too.
public partial class F_Main : Form
{
private string _TextBoxRequestMsg;
public string TextBoxRequestMsg
{
get { return textBox3.Text; }
set
{
_TextBoxRequestMsg = value;
MessageBox.Show(_TextBoxRequestMsg);
Console.WriteLine(_TextBoxRequestMsg);
textBox3.Text = _TextBoxRequestMsg;
}
}
public F_Main()
{
InitializeComponent();
}
}
public class CdataController : ApiController
{
F_Main mainForm = new F_Main();
public async Task<HttpResponseMessage> PostPayloadEventsOp(string SN, string table, string OpStamp)
{
using (var contentStream = await this.Request.Content.ReadAsStreamAsync())
{
contentStream.Seek(0, SeekOrigin.Begin);
using (var sr = new StreamReader(contentStream))
{
string results = sr.ReadToEnd();
mainForm.TextBoxRequestMsg = results;
}
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("OK", System.Text.Encoding.UTF8);
response.Headers.CacheControl = new CacheControlHeaderValue()
{
MaxAge = TimeSpan.FromMinutes(2)
};
return response;
}
}
Your question states that your goal is to change textBox.Text control value in Winform and your code indicates that you want to do this by processing an HttpResponseMessage. Consider that the Form that owns the textBox3 control could await the response so that it can meaningfully process its content and assign the value to the text box.
For a minimal example, mock the API request:
public class MockCdataController : ApiController
{
public async Task<HttpResponseMessage> MockPostPayloadEventsOp(string SN, string table, string OpStamp)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync("https://stackoverflow.com/q/75310027/5438626");
response.Content = new StringContent("OK", System.Text.Encoding.UTF8);
response.Headers.CacheControl = new CacheControlHeaderValue()
{
MaxAge = TimeSpan.FromMinutes(2)
};
return response;
}
}
}
The Form that is in possession of textBox3 could invoke something like this:
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
buttonPost.Click += onPost;
}
private async void onPost(object? sender, EventArgs e)
{
try
{
UseWaitCursor = true;
buttonPost.BackColor = Color.LightGreen;
var response = await _controller.MockPostPayloadEventsOp("38D6FF5-F89C", "records", "Asgard");
if((response.Headers != null) && (response.Headers.CacheControl != null))
{
textBox3.Text = $"{response.Headers.CacheControl.MaxAge}";
}
}
finally
{
UseWaitCursor = false;
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
}
}
MockCdataController _controller = new MockCdataController();
}
I've implemented what I think is a pretty vanilla usage of Realm:
public class MyObj : RealmObject
{
[PrimaryKey]
public string Key { get; set; }
public bool Value { get; set; }
}
then, in my app:
using(Realm r = Realm.GetInstance()) {
var c1 = r.All<MyObj>().Count();
}
which returns zero, as expected.
Then I add an object:
using(Realm r = Realm.GetInstance()) {
r.Write(() =>
{
var obj = new MyObj() { Key = "test", Value = true };
r.Add(obj);
});
}
then reopen it and get the count:
using(r = Realm.GetInstance()) {
var c2 = r.All<MyObj>().Count();
}
and c2 is one, as expected. So far, so good.
But when I close my app, and restart, c1 (the initial count) is zero, not one.
Any idea why?
Sorry,we couldn't see the other code of your app.
But you can refer to an article by entering key words Xamarin.Forms - Working With Realm Database in your browser. It works properly even after restarting the app.
You can also check the full sample here.
The main code is:
public partial class MainPage : ContentPage
{
List<OptionItems> optionItems = new List<OptionItems>();
Student editStudent;
public MainPage()
{
InitializeComponent();
imgBanner.Source = ImageSource.FromResource("XamarinFormsRelam.images.banner.png");
var realmDB = Realm.GetInstance();
List<Student> studentList = realmDB.All<Student>().ToList();
listStudent.ItemsSource=studentList;
}
private void btnAdd_Clicked(object sender, EventArgs e)
{
var realmDB = Realm.GetInstance();
var students= realmDB.All<Student>().ToList();
var maxStudentId = 0;
if (students.Count!=0)
maxStudentId = students.Max(s=>s.StudentID);
Student student = new Student()
{
StudentID = maxStudentId + 1,
StudentName = txtStudentName.Text
};
realmDB.Write(() =>
{
realmDB.Add(student);
});
txtStudentName.Text = string.Empty;
List<Student> studentList = realmDB.All<Student>().ToList();
listStudent.ItemsSource = studentList;
}
private async void listOptions_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var realmDB = Realm.GetInstance();
OptionItems selectedItem = optionList.SelectedItem as OptionItems;
if (selectedItem != null)
{
switch (selectedItem.OptionText)
{
case "Edit":
popupOptionView.IsVisible = false;
popupEditView.IsVisible = true;
editStudent = realmDB.All<Student>().First(b => b.StudentID == selectedItem.StudentId);
txtEditStudentName.Text = editStudent.StudentName;
break;
case "Delete":
var removeStudent = realmDB.All<Student>().First(b => b.StudentID == selectedItem.StudentId);
using (var db = realmDB.BeginWrite())
{
realmDB.Remove(removeStudent);
db.Commit();
}
await DisplayAlert("Success", "Student Deleted", "OK");
popupOptionView.IsVisible = false;
List<Student> studentList = realmDB.All<Student>().ToList();
listStudent.ItemsSource = studentList;
break;
default:
popupOptionView.IsVisible = false;
break;
}
optionList.SelectedItem = null;
}
}
protected override void OnAppearing()
{
base.OnAppearing();
var realmDb = Realm.GetInstance();
}
private void listStudent_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
Student selectedStudent = listStudent.SelectedItem as Student;
if(selectedStudent!=null)
{
optionItems.Add(new OptionItems { OptionText = "Edit",StudentId=selectedStudent.StudentID});
optionItems.Add(new OptionItems { OptionText = "Delete", StudentId = selectedStudent.StudentID });
optionItems.Add(new OptionItems { OptionText = "Cancel"});
optionList.ItemsSource = optionItems;
popupOptionView.IsVisible = true;
}
}
private void Button_Clicked(object sender, EventArgs e)
{
popupEditView.IsVisible = false;
}
private async void Button_Clicked_1(object sender, EventArgs e)
{
var realmDB = Realm.GetInstance();
var selectedStudent = realmDB.All<Student>().First(b => b.StudentID == editStudent.StudentID);
using (var db = realmDB.BeginWrite())
{
editStudent.StudentName = txtEditStudentName.Text;
db.Commit();
}
await DisplayAlert("Success", "Student Updated","OK");
txtEditStudentName.Text = string.Empty;
popupEditView.IsVisible = false;
}
}
Are you deploying on a physical device? If that's the case, it's likely due to the automatic backup and restore functionality built into Android - when you deploy the app, it treats it as an install and restores the last known state.
You can read about it here: An Android app remembers its data after uninstall and reinstall but the tl;dr is - go to settings and turn off "Automatic Restore" or update your manifest to instruct Android not to backup the data.
I've got a problem with my Xamarin App. The App uses a custom API to my website. I have not much experience in async/await methods.
The following code shows the App.xaml.cs:
public partial class App : Application
{
public static bool IsUserLoggedIn { get; set; }
public static UserModel currentLoggedInUser { get; set; }
public static List<ActionTypeModel> listTypes;
public static List<ActionSubTypeModel> listSubtypes;
public static List<UserModel> listFriends;
public static List<List<ActionModel>> listActiveActions;
public static List<ActionModel> listLastAction;
public App()
{
this.InitializeComponent();
APIHelper.InitializeClient();
StartApp().Wait();
}
private async Task StartApp()
{
//// DEBUG
//MyAccountStorage.Logout();
string username = await MyAccountStorage.GetUsername().ConfigureAwait(false);
string password = await MyAccountStorage.GetPassword().ConfigureAwait(false);
string user_id = await MyAccountStorage.GetId().ConfigureAwait(false);
if (username != null && password != null)
{
currentLoggedInUser = new UserModel();
if (user_id != null)
currentLoggedInUser.user_id = Convert.ToInt32(user_id);
currentLoggedInUser.username = username;
currentLoggedInUser.password = password;
bool isValid = false;
isValid = await AreCredentialsCorrect(0, currentLoggedInUser.username, currentLoggedInUser.password).ConfigureAwait(false);
if (isValid)
{
IsUserLoggedIn = true;
await FillLists().ConfigureAwait(false);
MainPage = new NavigationPage(await MyPage.BuildMyPage().ConfigureAwait(false));
}
else
{
IsUserLoggedIn = false;
MainPage = new NavigationPage(await LoginPage.BuildLoginPage().ConfigureAwait(false));
}
}
else
{
IsUserLoggedIn = false;
MainPage = new NavigationPage(await LoginPage.BuildLoginPage().ConfigureAwait(false));
}
}
private async Task FillLists()
{
listFriends = await DataControl.GetFriends(App.currentLoggedInUser.user_id, App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
if (listFriends == null)
listFriends = new List<UserModel>();
listTypes = await DataControl.GetTypes(App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
if (listTypes == null)
listTypes = new List<ActionTypeModel>();
listActiveActions = new List<List<ActionModel>>();
for (int i = 0; i < listTypes.Count; i++)
listActiveActions.Add(await DataControl.GetActiveActions(listTypes[i].action_type_id, currentLoggedInUser.user_id, currentLoggedInUser.username, currentLoggedInUser.password).ConfigureAwait(false));
listSubtypes = await DataControl.GetSubtypes(App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
if (listSubtypes == null)
listSubtypes = new List<ActionSubTypeModel>();
listLastAction = await DataControl.GetLastAction(App.currentLoggedInUser.user_id, App.currentLoggedInUser.username, App.currentLoggedInUser.password).ConfigureAwait(false);
if (listLastAction == null)
listLastAction = new List<ActionModel>();
}
public static async Task<bool> AreCredentialsCorrect(int type, string user, string pass, string nick = "", string email = "")
{
List<UserModel> listUsers;
if (type == 1)
listUsers = await DataControl.CheckCredentials(1, user, pass, nick, email).ConfigureAwait(false);
else
listUsers = await DataControl.CheckCredentials(0, user, pass).ConfigureAwait(false);
if (listUsers != null)
if (listUsers.Any())
{
currentLoggedInUser = listUsers.First();
currentLoggedInUser.password = pass;
return true;
}
return false;
}
}
I have the API in DataControl.cs:
public static async Task<List<UserModel>> CheckCredentials(int type, string username, string pass, string email = "", string nickname = "")
{
string password = APIHelper.GetHashSha256(pass);
string url = string.Empty;
if (type == 0)
url = APIHelper.ApiClient.BaseAddress + "/account/login.php?username=" + username + "&password=" + password;
if (type == 1)
{
string nick = string.Empty;
if (string.IsNullOrEmpty(nickname) == false)
nick = "&nickname=" + nickname;
url = APIHelper.ApiClient.BaseAddress + "/account/signup.php?username=" + username + "&password=" + password + "&email=" + email + nick;
}
if (string.IsNullOrEmpty(url))
return null;
using (HttpResponseMessage response = await APIHelper.ApiClient.GetAsync(url).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
List<UserModel> listUsers = JsonConvert.DeserializeObject<List<UserModel>>(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
return listUsers;
}
else
return null;
}
}
That's one of the different async methods. When I leave out the ConfigureAwait(false), I run into a deadlock. When I add it to the code I run into an error.
Could you please help me.
As #GSerg already wrote, you have to restructure the code. The App constructor must set the MainPage to some page. That one can be empty saying something like "Loading data".
Then you can start a background Task which retrieves the data you need.
When the data has been loaded, then you can update your page with the newly loaded data. But UI updates always have to happen on the UI thread. This is the same on all platforms. So you have to switch back with Device.BeginInvokeOnMainThread(...).
public App()
{
InitializeComponent();
APIHelper.InitializeClient();
MainPage = new LoadingPage();
// start a background thread
Task.Run(async () =>
{
try
{
await StartApp(); // load the data
// go back to the main thread
Device.BeginInvokeOnMainThread(() =>
{
// replace the MainPage with one which shows the loaded data
MainPage = new DataPage();
});
}
catch (Exception ex)
{
// handle the exception
}
});
}
You can use Task.Run(
//call your async method here
);
So in your case:
Task.Run(Startup);
I used to work with browser-based applications. for example Angular simple repository.
function getSomeData(params) {
...
return $http({
url: conf.urlDev + 'some/rest-url',
method: "GET",
params: params,
cache: true
}).then(getDataComplete);
function getDataComplete(response) {
return response.data;
}
}
How it will look the same in c# (XAMARIN for example)?
i try :
public class BaseClient
{
protected Http _client = null;
protected string _urlObj;
protected string _basePath;
public BaseClient ()
{
_client = new Http(new HttpClientHandler());
}
public string Path
{
set
{
_urlObj = value;
}
}
public async Task<Result<IList<T>>>getList<T>(Dictionary<string,object> parametrs = null)
{
if (parametrs != null)
{
foreach(KeyValuePair<string, object> keyValue in parametrs)
{
_urlObj = _urlObj.SetQueryParam(keyValue.Key, keyValue.Value);
}
}
var response = await _client.GetAsync(_urlObj.ToString());
if (response.IsSuccessStatusCode)
{
return new Result<IList<T>>()
{
Success = true,
Value = JsonConvert.DeserializeObject<IList<T>>(await response.Content.ReadAsStringAsync())
};
}
else
{
var error = new Result<IList<T>>()
{
Error = response.StatusCode.ToString(),
Message = response.ReasonPhrase,
Success = false
};
return error;
}
}
in my service:
public async Task<IList<News>> GetAllNewsByParams(DateTime from,
string orderBy = "-published",
DateTime to = new DateTime(),
int page = 1, int category = 0)
{
_client.Path = _config.NewsPath;
var dict = new Dictionary<string, object> {
{"from", from.ToString("s")},
{"order_by", orderBy.ToString()},
{"to", to.ToString("s")},
{"page", page.ToString()}
};
if (category != 0)
{
dict.Add("category", category.ToString());
}
var res = await _client.getList<News>(dict);
return res.Value;
}
and im ny viewmodel
foreach (var item in await _newsService.GetAllNewsByParams(
_To,
_OrderBy,
_From, _Page,
selectedTag == null ? _SeletedNewsTagId : selectedTag.Id))
{
NewsList.Add(item);
}
Is his query executed synchronously ?
How do I make it an asynchronous?
First of all I would really encourage you to use RestSharp, it really simplifies making HTTP requests and deserialise them. Add a RestSharp nuget package to your project. Here is how your code will look like using RestSharp.
public class BaseClient
{
protected IRestClient _client = null;
protected string _urlObj;
protected string _basePath;
public BaseClient()
{
_client = new RestClient();
}
public async Task<Result<IList<T>>> GetList<T>(string path, Dictionary<string, object> parametrs = null)
{
var request = new RestRequest(path, Method.GET);
if (parametrs != null)
{
foreach (var keyValue in parametrs)
{
request.AddQueryParameter(keyValue.Key, keyValue.Value);
}
}
var response = await _client.Execute<List<T>>(request);
if (response.IsSuccess)
{
return new Result<IList<T>>()
{
Success = true,
Value = response.Data
};
}
else
{
var error = new Result<IList<T>>()
{
Error = response.StatusCode.ToString(),
Message = response.StatusDescription,
Success = false
};
return error;
}
}
}
In your service
public async Task<IList<News>> GetAllNewsByParams(DateTime from,
string orderBy = "-published",
DateTime to = new DateTime(),
int page = 1, int category = 0)
{
var dict = new Dictionary<string, object> {
{"from", from.ToString("s")},
{"order_by", orderBy.ToString()},
{"to", to.ToString("s")},
{"page", page.ToString()}
};
if (category != 0)
{
dict.Add("category", category.ToString());
}
var res = await _client.GetList<News>(_config.NewsPath, dict);
return res.Value;
}
And in your viewmodel
var news = await _newsService.GetAllNewsByParams(
_To,
_OrderBy,
_From, _Page,
selectedTag == null ? _SeletedNewsTagId : selectedTag.Id);
foreach (var item in news)
{
NewsList.Add(item);
}
This will be 100% asynchronous.
I created a ContentDialog that contains a TextBox where the user enter a SMS code. When this code is right, I need the user navigate to a Home Page.
The problem is Navigate.Frame does not exist in this context.
Please, What Am I doing wrong?
private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
String _confirmaSms = "https://example.com";
RestClient client = new RestClient();
string msisdn = PrimaryButtonCommandParameter.ToString();
string codigoConfirmacao = txtCodigoConfirmacao.Text;
Usuario usuario = new Usuario()
{
msisdn = msisdn,
codesms = codigoConfirmacao
};
string output = JsonConvert.SerializeObject(usuario);
//Debug.WriteLine(output);
string response = await client.RestConnection(_confirmaSms, "POST", output);
JObject responseObj = JObject.Parse(response);
JObject resultObj = (JObject)responseObj["result"];
string result = resultObj["codesms"].ToString();
if (usuario.codesms.ToString() == result && result != null)
{
//code to navigate
}
else
{
//code to navigate to other page
}
Debug.WriteLine(resultObj["ltoken"]);
}
Finally, after some research, I found an answer.
Have to instantiate the RootFrame at the beginning of class.
public sealed partial class ConfirmaSMS : ContentDialog
{
Frame rootFrame = Window.Current.Content as Frame;
public ConfirmaSMS()
{
this.InitializeComponent();
}
private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
String _confirmaSms = "https://www.Example.com";
RestClient client = new RestClient();
string msisdn = PrimaryButtonCommandParameter.ToString();
string codigoConfirmacao = txtCodigoConfirmacao.Text;
string output = JsonConvert.SerializeObject(usuario);
//Debug.WriteLine(output);
string response = await client.RestConnection(_confirmaSms, "POST", output);
JObject responseObj = JObject.Parse(response);
JObject resultObj = (JObject)responseObj["result"];
string result = resultObj["codesms"].ToString();
if (usuario.codesms.ToString() == result && result != null)
{
Debug.WriteLine(result.ToString());
rootFrame.Navigate(typeof(HomePage));
}
else
{
confirmaSMS.SecondaryButtonCommandParameter = false;
confirmaSMS.Hide();
}
Debug.WriteLine(resultObj["ltoken"]);
}
private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
}
}