SignalR list of object undefined - signalr

I am trying to display on the console a list of object But it doesn't show the objects...
Here is the javascript I use to display the object received from the server :
connection.on("ReceiveLog", function (chatMessages) {
console.log(chatMessages);
for (var item in chatMessages) {
// work with key and value
var encodedMsg = item.User + " says " + item.Message;
var li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
} });
The server is sending a list of ChatMessage. Here is the ChatMessage class :
public class ChatMessage
{
string User { get; set; }
string Message { get; set; }
public ChatMessage(string user, string message)
{
this.User = user;
this.Message = message;
}
}
Why are my objects completely broken ? When I break the code on the server side, it really sends the list correctly. The problem seems to be from the javascript or maybe I need to serialize from the server side ?

I needed to set all the property of the object Public like so :
public class ChatMessage
{
public string User { get; set; }
public string Message { get; set; }
public ChatMessage(string user, string message)
{
this.User = user;
this.Message = message;
}
}
It works now.

Related

System.Text.Json Deserialize Fails

With this DTO:
public class QuestionDTO {
public Guid Id { get; set; }
public string Prompt { get; set; }
public List<Answer> Choices { get; set; }
public QuestionDTO() {
}
public QuestionDTO(Question question) {
this.Id = question.Id;
this.Prompt = question.Prompt;
this.Choices = question.Choices;
}
}
I was getting an error about Unable to Parse without a parameterless constructor. I have since fixed that, but now my objects are de-serialized empty:
using System.Text.Json;
var results = JsonSerializer.Deserialize<List<QuestionDTO>>(jsonString);
The jsonString contains 3 items with the correct data, and the deserialized list contains 3 items, but all the properties are empty.
The new json library is case sensitive by default. You can change this by providing a settings option. Here is a sample:
private JsonSerializerOptions _options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
private async Task SampleRequest()
{
var result = await HttpClient.GetStreamAsync(QueryHelpers.AddQueryString(queryString, queryParams));
_expenses = await JsonSerializer.DeserializeAsync<List<Common.Dtos.Expenses.Models.Querys.ExpensesItem>>(result, _options);
}

Display Information to the UI

So what I have been trying is this: After successful registration the user gets a Message in the interface to show that Registration was successful. My first method was I declared a Message variable and use Data Binding to bind the result to a label in my RegisterPage.xaml. That failed because whether the message is successful or not the label is not showing. So I commented out using a label and tried DisplayAlert but DisplayAlert is giving an error- does not exist in the current context.
Please help, still learning.
public class RegisterViewModel
{
private readonly DataService dataService = new DataService();
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public string Message { get; set; }
public ICommand RegisterCommand
{
get
{
return new Command(async () =>
{
var isRegistered = await dataService.RegisterUserAsync(Email, Password, ConfirmPassword);
Settings.Username = Email;
Settings.Password = Password;
if (isRegistered)
{
//DisplayAlert( "Alert" , "Registered", "OK");
//Message = "Registered Successfully :)";
// DependencyService.Get<Toast>().Show("You have registered succefully");
Application.Current.MainPage = new NavigationPage(new EntryPage());
}
else
{
Message = " Retry Later :(";
}
});
}
}
}
DisplayAlert is part of the Page class. If you want to display an alert from a view model (there are many results on Google), you'd call a method like:
private async Task DisplayGenericDialog(string title, string message)
{
await App.Current.MainPage.DisplayAlert(title, message, "OK");
}

Error retrieving data from Api Controller

I'm working on an ASP.NET Core Api and Xamarin forms client using Visual Studio 2017.
I'm getting an error
System.Runtime.Serialization.SerializationException: Invalid JSON string
because response.Content is null, when retrieving data from API but when paste this Url in browser "https://localhost:44305/api/Agreement/GetAgreementText/1" it shows data in the browser. When I run using client it's not hit to api method debug point .
Here is my APi method
[HttpGet]
[Route("GetAgreementText/{id}")]
public DefaultApiResult GetAgreementText(long Id)
{
Company com = _companyRepository.Get(Id);
string st = com.AgreementText;
DefaultApiResult result = new DefaultApiResult
{
Data = st
};
return result;
}
Here is my client application Api invoking method
public string GetAgreementTextLoading(long idCompany)
{
string agreementText = "";
// var token = _tokenService.GetLastActivateToken().Hash;
var clientURL = "https://localhost:44305/";
var client = new RestClient(clientURL);
var request = new RestRequest("api/Agreement/GetAgreementText/{Id}", Method.GET);
request.AddUrlSegment("Id", idCompany.ToString());
IRestResponse response = client.Execute(request);
AppRestResponse apiResponse = SimpleJson.DeserializeObject<AppRestResponse>(response.Content);
var statusMessage = "";
if (apiResponse.Success)
{
statusMessage = "Success.";
if (!string.IsNullOrEmpty(response.Content))
{
agreementText = apiResponse.Data.ToString();
}
else
{
throw new Exception("Invalid response");
}
}
else
{
agreementText = "Error retrieving agreement text";
}
return agreementText;
}
public class AppRestResponse
{
public bool Success { get; set; }
public object Data { get; set; }
public IEnumerable<AppRestReponseError> ErrorMessages { get; set; }
}
public class DefaultApiResult
{
public bool Success
{
get
{
return ErrorMessages.Count == 0;
}
private set { }
}
public List<ErrorMessage> ErrorMessages { get; set; }
public object Data { get; set; }
public DefaultApiResult()
{
ErrorMessages = new List<ErrorMessage>();
}
public DefaultApiResult(string errorMessage)
:this()
{
ErrorMessages.Add(new ErrorMessage()
{
Message = errorMessage
});
}
public DefaultApiResult(string[] errorMessages)
:this()
{
foreach (var errorMessage in errorMessages)
{
ErrorMessages.Add(new ErrorMessage()
{
Message = errorMessage
});
}
}
}
I'm not sure about the SimpleJson and the rest client you are using .
However , assuming you're using the RestSharp , it seems that there's no need to use the SimpleJson to deserialize response here .
I just remove the following codes :
IRestResponse response = client.Execute(request);
AppRestResponse apiResponse = SimpleJson.DeserializeObject<AppRestResponse>(response.Content);
and add the following two lines:
IRestResponse<AppRestResponse> response = client.Execute<AppRestResponse>(request);
var apiResponse= response.Data;
It works as expected .

get user email after Azure AD authentication in xamarin app

I need to get the email adress after the user authentication.
I tried to fid this information in the authenticationResult but I just found the user name .. but not the email.
How can I get this information?
Thanks
Do you want the email on the client-side or the server-side? If it's the server-side, try checking the x-ms-client-principal-name HTTP header value. If it's the client-side, try making an authenticated request to /.auth/me and you should see all the claims, including the user's email in the JSON response.
Since you mentioned in another answer that this is client side, use the InvokeApi<>() method. This is discussed in detail in the book here: https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/authorization/#obtaining-user-claims
Short version is this code:
List<AppServiceIdentity> identities = null;
public async Task<AppServiceIdentity> GetIdentityAsync()
{
if (client.CurrentUser == null || client.CurrentUser?.MobileServiceAuthenticationToken == null)
{
throw new InvalidOperationException("Not Authenticated");
}
if (identities == null)
{
identities = await client.InvokeApiAsync<List<AppServiceIdentity>>("/.auth/me");
}
if (identities.Count > 0)
return identities[0];
return null;
}
Where AppServiceIdentity is defined like this:
public class AppServiceIdentity
{
[JsonProperty(PropertyName = "id_token")]
public string IdToken { get; set; }
[JsonProperty(PropertyName = "provider_name")]
public string ProviderName { get; set; }
[JsonProperty(PropertyName = "user_id")]
public string UserId { get; set; }
[JsonProperty(PropertyName = "user_claims")]
public List<UserClaim> UserClaims { get; set; }
}
public class UserClaim
{
[JsonProperty(PropertyName = "typ")]
public string Type { get; set; }
[JsonProperty(PropertyName = "val")]
public string Value { get; set; }
}
I don't find the InvokeApiAsync to call it.
are there a token or something like that to find the email ?
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, CloudConstants.ApIbaseUrl + /.auth/me");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _authenticationResult.Token);
try
{
var response = client.SendAsync(request);
if (response.Result.IsSuccessStatusCode)
{
var responseString = response.Result.Content.ReadAsStringAsync();
var profile = JArray.Parse(responseString.Result);
}
}
catch (Exception ee)
{
_dialogService.DisplayAlertAsync("An error has occurred", "Exception message: " + ee.Message, "Dismiss");
}

How to post JSON data to SQL using ajax post & knockout

I have a pretty straightforward view model:
var ProjectViewModel = {
ProjectName: ko.observable().extend({ required: "" }),
ProjectDescription: ko.observable().extend({ required: "" }),
ProjectStartDate: ko.observable(),
ProjectEndDate: ko.observable()
};
I want to save this data that is located in my viewmodel to my SQL server.
I have a class defining this View Model in my Server Side Code:
public class Projects
{
public string ProjectName { get; set; }
public DateTime ProjectStartDate { get; set; }
public DateTime ProjectEndDate { get; set; }
public string ProjectDescription { get; set; }
}
I also have this web method to receive the code:
[WebMethod]
public bool SaveProject(string[] JSONDATA)
{
TaskNinjaEntities entities = new TaskNinjaEntities();
foreach (var item in JSONDATA)
{
Console.WriteLine("{0}", item);
}
return true;
}
And finally I have this POST that does not want to send the data to the server:
function SaveMe() {
var data = ko.toJSON(ProjectViewModel);
$.post("CreateProject.aspx/SaveProject", data, function (returnedData) {
});
}
I get nothing from the returned data in this post method, also added breakpoint in server side code, and it doesn't hit it at all. My URL is correct and the Viewmodel converts to JSON without hassle.
Make the web method static.
[WebMethod]
public static bool SaveProject(string[] JSONDATA)
{
TaskNinjaEntities entities = new TaskNinjaEntities();
foreach (var item in JSONDATA)
{
Console.WriteLine("{0}", item);
}
return true;
}

Resources