Cannot access child value on JValue in Azure Mobile App

Multi tool use
Cannot access child value on JValue in Azure Mobile App
I recently implemented custom authentication with Azure Mobile App - All the server side works fine and also my web application which is using that mobile app service is working fine. I tested the server-side in details with POSTMAN and with different scenarios, everything works fine until I try to LoginAsync
on Xamarin.
LoginAsync
When I pass email and password in POSTMAN, I get the following response as a clear indication that it is working
but when I send a request from my app using LoginAsync
I get the following error.
LoginAsync
Cannot access child value on Newtonsoft.Json.Linq.JValue
My code to send request is fairly simple as following
public async Task<bool> Authenticate()
{
string username = "todo@gmail.com";
string password = "todo";
string message = string.Empty;
var success = false;
var credentials = new JObject
{
["email"] = username,
["password"] = password
};
try
{
MobileServiceUser user = await client.LoginAsync("CustomAuth", credentials);
if (user != null)
{
success = true;
CreateAndShowDialog("OK", "Auth");
}
}
catch (Exception ex)
{
CreateAndShowDialog(ex, "Auth Error");
}
return success;
}
where I am calling it as follows
private MobileServiceClient client;
client = new MobileServiceClient(applicationURL);
await Authenticate();
Any idea why I am getting Cannot access child value on Newtonsoft.Json.Linq.JValue
error?
Cannot access child value on Newtonsoft.Json.Linq.JValue
Cheers
EDIT POST
As a workaround, I am temporarily using InvokeApiAsync
with JObject.FromObject
instead of LoginAsync
InvokeApiAsync
JObject.FromObject
LoginAsync
await client.InvokeApiAsync("/.auth/login/CustomAuth", JObject.FromObject(credentials), HttpMethod.Post, null);
await client.InvokeApiAsync("/.auth/login/CustomAuth", JObject.FromObject(credentials), HttpMethod.Post, null);
I am still not sure why LoginAsync
does not work - Until I find a solution I will keep using InvokdeApiAsync
as a workaround
LoginAsync
InvokdeApiAsync
var credentials = new JObject(new { email = username, password = password });
hi, thanks for your reply, now i got this error after i changed it to your code
Could not determine JSON object type for type <>f__AnonymousType1
2[System.String,System.String]`– aliusman
Jul 2 at 4:36
Could not determine JSON object type for type <>f__AnonymousType1
1 Answer
1
AFAIK, your initialization for credentials
is correct. For the below error:
credentials
Cannot access child value on Newtonsoft.Json.Linq.JValue
I checked your testing result via POSTMAN and found that you did not return userId
to your client. The essential properties returned to your client would look like as follows:
userId
{
"authenticationToken":"***",
"user":{
"userId":"***"
}
}
When using MobileServiceClient.LoginAsync
, the client SDK would internally invoke LoginAsync()
method under MobileServiceAuthentication.cs as follows:
MobileServiceClient.LoginAsync
LoginAsync()
JToken authToken = JToken.Parse(response);
// Get the Mobile Services auth token and user data
this.Client.CurrentUser = new MobileServiceUser((string)authToken["user"]["userId"]);
this.Client.CurrentUser.MobileServiceAuthenticationToken = (string)authToken[LoginAsyncAuthenticationTokenKey];
You would find that it would try to extract the userId
property under user
to construct the MobileServiceUser
instance and assign to MobileServiceClient.CurrentUser
.
userId
user
MobileServiceUser
MobileServiceClient.CurrentUser
Oh Bruce, you are legend. For some reason I thought it was just 'user' and not the value 'userId'. I should have checked the MobileServiceAuthentication.cs file , I will test this out and post results. Thank you so much for your help
– aliusman
Jul 3 at 3:20
It works, just a side question, is it ok to keep using InvokeApi instead? I mean what's the drawback
– aliusman
Jul 3 at 3:36
You could also use
InvokeApi
, at this point, you need to manually initialize / update your MobileServiceClient.CurrentUser
with the relevant userId
and authenticationToken
. Since MobileServiceClient.LoginAsync
has handled it automatically for you, I would prefer to use LoginAsync
for logging.– Bruce Chen
Jul 3 at 4:59
InvokeApi
MobileServiceClient.CurrentUser
userId
authenticationToken
MobileServiceClient.LoginAsync
LoginAsync
Thank you, makes perfect sense. I still have to set
MobileServiceClient.CurrentUser
if I want to reuse
same authToken
the next time MobileServiceClient
is initialised - I believe this is the correct approach to save authToken in SharedPrefrences
for reusability as my tokenTimespam is 30 days?– aliusman
Jul 3 at 5:42
MobileServiceClient.CurrentUser
reuse
authToken
MobileServiceClient
SharedPrefrences
You are right. Here is a complete tutorial about caching token in your mobile client side, details you could follow Tokens in Real Apps about caching / refreshing the token. You could also specify
null
for the lifetime
parameter when using AppServiceLoginHandler.CreateToken
for generating the JWT authenticationToken, then your client would get a never-expiring token.– Bruce Chen
Jul 3 at 6:08
null
lifetime
AppServiceLoginHandler.CreateToken
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Not familiar with the syntax of JObject you have mentioned. Can you try with
var credentials = new JObject(new { email = username, password = password });
– user1672994
Jul 2 at 4:31