Consume and Configure Graphql request from .Net C# console application client - c#

I'm trying to consume a Graphql Api from a C# client. For that I'm using the GraphQl.Net Nuget package. The problem is that, I have no idea how to set the Api Url as I don't have HttpRequest object and this results also with additional problems that I can't set the authentcation header and send the token with the request. My code looks like:
public void Post(TestGraphQl.GraphQLQuery query)
{
var inputs = query.Variables.ToInputs();
var queryToExecute = query.Query;
var result = _executer.ExecuteAsync(_ =>
{
_.Schema = _schema;
_.Query = queryToExecute;
_.OperationName = query.OperationName;
_.Inputs = inputs;
//_.ComplexityConfiguration = new ComplexityConfiguration { MaxDepth = 15 };
_.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
}).Result;
var httpResult = result.Errors?.Count > 0
? HttpStatusCode.BadRequest
: HttpStatusCode.OK;
var json = _writer.Write(result);
}
And the caller looks like this:
var jObject = new Newtonsoft.Json.Linq.JObject();
jObject.Add("id", deviceId);
client.Post(new GraphQLQuery { Query = "query($id: String) { device (id: $id) { displayName, id } }", Variables = jObject });
I'm totally new to this topic and appreciate any help. Many thanks!!

This worked out for me. You will need the GraphQL.Client Package. My_class is the class for the deserialization.
var client = new GraphQLHttpClient(Api_Url, new NewtonsoftJsonSerializer());
var request = new GraphQLRequest
{
Query = {query}
};
var response = await client.SendQueryAsync<my_class>(request);

Not sure if you are still looking for it. One can always use GraphQl.Client nuget to achieve this. Sample code to consume is
var query = #"query($id: String) { device (id: $id) { displayName, id } }";
var request = new GraphQLRequest(){
Query = query,
Variables = new {id =123}
};
var graphQLClient = new GraphQLClient("http://localhost:8080/api/GraphQL");
graphQLClient.DefaultRequestHeaders.Add("Authorization", "yourtoken");
var graphQLResponse = await graphQLClient.PostAsync(request);
Console.WriteLine(graphQLResponse.Data);

Related

Unable to deserialize the JSON Data

I'm currently using an API to grab some player information, which looks like this in raw data form:
{
"response": {
"players": [
{
"steamid": "76561198166559342",
"communityvisibilitystate": 1,
"profilestate": 1,
"personaname": "Stack Overflow",
"commentpermission": 2,
"profileurl": "https://steamcommunity.com/id/stackoverflow/",
"avatar": "https://avatars.akamai.steamstatic.com/8a2e52a3eaefed0296459fa811aasdasd1ce29374.jpg",
"avatarmedium": "https://avatars.akamai.steamstatic.com/8a2e52a3eaefed0296459fa81asdas1ce29374_medium.jpg",
"avatarfull": "https://avatars.akamai.steamstatic.com/8a2e52a3eaefed0296459fa811a61212312e29374_full.jpg",
"avatarhash": "8a2e52a3eaefed02asdasd",
"personastate": 0
}
]
}
}
I am trying to just grab the "personaname" and "avatar" values from my data, which have been quite unsuccessful, so I've tried to objectify the JSON before getting it, which still isn't working:
Models.SteamUser persona;
String httpres;
using (var client = new HttpClient())
{
string steamurl = "MY HIDDEN URL HERE" + s64;
var steamapi = new Uri(steamurl);
var result = client.GetAsync(steamapi).Result.Content.ReadAsStringAsync().Result;
var json = result.ToString();
httpres = json;
var jUser = JObject.Parse(json);
var userData = JsonConvert.DeserializeObject<Models.SteamUser>(jUser["players"]).ToString(); ;
persona = userData;
}
Is there something I'm missing?
To get players from the JSON response, you need jObj["response"]["players"] instead of jObj["players"].
You have to deserialize as List<Models.SteamUser> but not Models.SteamUser as it is an array. Then with IEnumerable.FirstOrDefault() to get the first item of the array.
From the existing code, the userData is string type while persona is List<Models.SteamUser> type. You can't assign userData to persona.
Not suggested using Task.Result as it performs the operation synchronously and waits for the operation to be completed. Hence, it may lead to a deadlock. Instead, works with async/await. Source: What happens while waiting on a Task's Result?
Your code should be looked as below:
Models.SteamUser persona = null;
using (var client = new HttpClient())
{
string steamurl = "MY HIDDEN URL HERE" + s64;
var steamapi = new Uri(steamurl);
var response = await client.GetAsync(steamapi);
var jsonResult = await response.Content.ReadAsStringAsync();
var jObj = JObject.Parse(jsonResult);
var players = JsonConvert.DeserializeObject<List<Models.SteamUser>>(jObj["response"]["players"].ToString());
// Or
// var players = (jObj["response"]["players"] as JArray).ToObject<List<Models.SteamUser>>();
persona = players.FirstOrDefault();
}

Making DialogFlow v2 DetectIntent Calls w/ C# (including input context)

So I finally figured out a way to successfully make detect intent calls and provide an input context. My question is whether or not this is the CORRECT (or best) way to do it:
(And yes, I know you can just call DetectIntent(agent, session, query) but I have to provide a input context(s) depending on the request)
var query = new QueryInput
{
Text = new TextInput
{
Text = model.Content,
LanguageCode = string.IsNullOrEmpty(model.Language) ? "en-us" : model.Language,
}
};
var commonContext = new global::Google.Cloud.Dialogflow.V2.Context
{
ContextName = new ContextName(agent, model.sessionId, "my-input-context-data"),
LifespanCount = 3,
Parameters = new Struct
{
Fields = {
{ "Source", Value.ForString(model.Source) },
{ "UserId" , Value.ForString(model.UserId.ToString())},
{ "Name" , Value.ForString(model.FirstName)}
}
}
};
var request = new DetectIntentRequest
{
SessionAsSessionName = new SessionName(agent, model.sessionId),
QueryParams = new QueryParameters
{
GeoLocation = new LatLng {Latitude = model.Latitude, Longitude = model.Longitude},
TimeZone = model.TimeZone ?? "MST"
},
QueryInput = query
};
request.QueryParams.Contexts.Add(commonContext);
// ------------
var creds = GetGoogleCredentials("myCredentials.json");
var channel = new Grpc.Core.Channel(SessionsClient.DefaultEndpoint.Host, creds.ToChannelCredentials());
var client = SessionsClient.Create(channel);
var response = client.DetectIntent(request);
channel.ShutdownAsync();
return response;
Note: I included the explicit ShutDownAsync (it's not in an async call) because I was getting some file locking issues when attempting to re-deploy the WebAPI project (and only after having executed this code).
Thanks
Chris
Updated 4/25: The most basic way I use this is to integrate the user's name into intent responses:
It can also be read from within the webhook/inline fulfillment index.js:
const name = request.body.queryResult && request.body.queryResult.outputContexts && request.body.queryResult.outputContexts[0].parameters.Name

remote object server is never synchronized

hi i cannot seem to get realm synced with the realm object server i am working xamarin and it's working great localing i just can't seem to sync to the cloud , not even the schema
my code is:
var credentials = Credentials.UsernamePassword(usernameField.Text.ToLower(), passField.Text, createUser: true);
var authURL = new System.Uri("https://game-object.us1.cloud.realm.io/");
var user = await User.LoginAsync(credentials, authURL);
var serverURL = new System.Uri("realm://game-object.us1.cloud.realm.io/~/default");
var configuration = new SyncConfiguration(user, serverURL);
var permission= await user.GetGrantedPermissionsAsync(Recipient.CurrentUser,millisecondTimeout:2111);
var realm = Realm.GetInstance(configuration);
bool m;
if (realm.Config == configuration)
m=true;
var realmSession= realm.GetSession();
var state = realmSession.State;
var permissionCondition = PermissionCondition.UserId(user.Identity);
/* await user.ApplyPermissionsAsync(permissionCondition, "realm://game-object.us1.cloud.realm.io/~/default", AccessLevel.Write);
permission = await user.GetGrantedPermissionsAsync(Recipient.CurrentUser, millisecondTimeout: 2111);
*/
var players = realm.All<Player>();
realm.Write(() =>
{
realm.Add(new Player { Health = 1, name = "apex" });
});
var count = players.Count();
i feel embraced, but the reason i wasn't getting updates is because the client object browser doesn't auto update

Dispatching Index() from NEST into to Elasticsearch.NET failed

I am having error when calling client.Index when using Nest and Elasticsearch.NET
var httpConnection = new AwsHttpConnection(new AwsSettings
{
AccessKey = "AKIAIFIV4LN6XZAFVX7Q",
SecretKey = "MySecretKey",
Region = "us-east-1",
});
var pool = new SingleNodeConnectionPool(new Uri(sSearchURI));
var config = new ConnectionSettings(pool, httpConnection);
var client = new ElasticClient(config);
var person = new Person
{
Id = "1",
Firstname = "Martijn",
Lastname = "Laarman"
};
var index = client.Index(person);
Dispatching Index() from NEST into to Elasticsearch.NET failed
Received a request marked as PUT This endpoint accepts POST,PUT The
request might not have enough information provided to make any of
these endpoints:
- /{index}/{type}
- /{index}/{type}/{id}
Any idea?
You need to set the default index:
settings.DefaultIndex("indexName");

Xamarin: Using HttpClient POST in combination with a dynamic Class

I have some services that require rather complex objects. Every service uses almost the same base object but it needs to be extended for each service.
A simple example:
The Standard Object would be something like:
ContextObject {
params {
Device {
Name: "MyMobileDevice",
ID: 123455691919238
}
}
}
and for my service I need to add some properties under params,
something like:
ContextObject {
params {
Device {
Name: "MyMobileDevice",
ID: 123455691919238
},
requested_employee_id: 112929
}
}
I tried to get this by using JObject and got it working so far but now I cant find a proper example on how to send this object to my server using HttpClient.
Edit:
Here is my full JObject which all Requests need:
public static JObject DefaultContext (string ServiceMethod) {
var Context = new JObject();
Context["version"] = "1.1";
Context["method"] = ServiceMethod;
Context["params"] = JObject.FromObject( new {
Context = JObject.FromObject( new {
User = App.UserSettings.USERNAME,
Password = App.UserSettings.PASSWORD,
SerialNumber = "1234567890", // TODO: use generated id
Locale = "de-DE",
Timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffzzz"),
Device = JObject.FromObject( new {
DeviceType = "phone",
ProductType = "D6603", // TODO: Get from Device-Info
screen = JObject.FromObject( new {
Density = "xxhdpi", // TODO: Get from Device-Info
resolution = JObject.FromObject( new {
Height = "1920", // TODO: Get from Device-Info
Width = "1080" // TODO: Get from Device-Info
})
}),
version = JObject.FromObject( new {
AppVersion = "myAppVersion", // TODO: Get App-Information LayoutVersion = "1.0"
} )
})
})
});
return mobileContext;
}
For my Requests I need to add parameters under the "params"-Node. Which works with:
mobileContext["params"]["mynewparameter"] = "FOO";
Now I wanted to send this JObject via System.Net.Http-Client to my server with something like this:
var client = new HttpClient ();
client.BaseAddress = new Uri (App.UserSettings.HOST + ":" + App.UserSettings.PORT + App.UserSettings.TYPE);
client.Timeout = 3000;
var context = MyContext.DefaultContext (ServiceMethods.CUSTOMER_LIST_METHOD);
context ["params"] ["myrequestparam"] = "FOO";
var jsonString = JsonConvert.SerializeObject (context);
var responseData = await client.Get???????
Is my general approach correct? How would you do it? Is there a sample on how to handle such dynamic stuff?
I couldn't find a example on how to use httpclient correctly with the Newtonsoft.JSON-Library how far am I from actually working code?

Categories