Is there a working way to read the AssignedLicenses property of a user in the Microsoft Graph Client Library? I tried the following things, but the AssignedLicenses property always returned null allthough there are licenses assigned to the user
// test 1: using "Me"
var lic = client.Me.Request().GetAsync().Result.AssignedLicenses;
// test 2: using the Id of a user
var lic = client.Users["<ID OF THE USER>"].Request().GetAsync().Result.AssignedLicenses;
using Select is the correct technique here as you found out, viz Request().Select("assignedLicenses").GetAsync().Result.AssignedLicenses
On the Graph, Select is used BOTH to reduce the set of properties returned and to bring in properties that are not returned by default. We do this in an attempt to keep default packet sizes moderately sized and readable and to keep call performance high by not routing every call to every underlying service necessary to fetch data that most callers don't need.
Related
I am using the Virtual Assistant Template and using custom middelwares.
what I want is to pass custom data in the activity Properties to my middleware from my MainDialog
turnContext.Activity.Properties["dummy"] = "data";
But the activity I receive in the middleware never has the Properties property set, it is always empty.
I know that:
As each activity flows in and out of the bot, each piece of middleware can inspect or act upon the activity, both before and after the bot logic runs.
My case is needing to pass data to the middleware "after the bot logic runs" How can I do that?
Turn state is a TurnContextStateCollection which is a type that derives from Dictionary<string, object>. As such, you can use it like a dictionary. In the SDK, data is usually stored in turn state using Add because the SDK is written to only add the data once. If you try to use Add when the data is already present, it will throw an exception. If you want to ensure that data is present in the turn state and you don't know if it's already there or not, you can use Set. This is the same as using the indexer's set accessor:
turnContext.TurnState["dummy"] = "data";
You can access it from your middleware using Get or by using the indexer again:
var dummy = turnContext.TurnState["dummy"];
Note that the TurnContextStateCollection provides generic methods for convenience so that if you're only storing one object of a given type in your turn state then you don't need a key to get or set it. The key is generated automatically from the name of the type.
turnContext.TurnState.Set(new DummyData());
var dummy = turnContext.TurnState.Get<DummyData>();
I am using the Microsoft.Graph library which I got off of Nuget. I have a problem regarding change tracking using deltas. Suppose
I am getting changes to users using something like the code below:
var usersDeltaRequest = client
.Users
.Delta()
.Request(usersDeltaLink == null ? new Option[0] : new []
{
new QueryOption("$deltatoken", usersDeltaLink)
});
var users = await usersDeltaRequest.GetAsync();
foreach (var user in users)
{
//code that updates the user goes here
}
My problem is that in this case, what gets returned is a User object. However since this is a delta, not all the fields in the object get populated. Only the ones that have been changed are guaranteed to be populated.
Now were I to parse the JSON returned manually, it would be easy to see which fields have actually been included in the response, since only those will be included in the JSON.
However, the library returns a User object and leaves the fields which haven't been returned as null. In this case, it does not seem possible to disambiguate between a field which simply hasn't been returned in the delta vs a field that actually does contain a null value.
Is there something I'm missing in how the library should be used? Because as it stands, it appears as if the library does lose some critical information, because I can't rely on the returned User object to reliably update my database, because a changed field containing a null value and a field that hasn't changed both result in a null value in the returned .Net object.
This obviously also applies to other types of resources, I just chose Users for the example.
As I read the API docs at https://developer.microsoft.com/en-us/graph/docs/concepts/delta_query_users it sez:
The optional $select query parameter is included in the request to
demonstrate how query parameters are automatically included in future
requests.
I haven't tried this. Did you include the properties you want to track changes for on your original request? Or perhaps try $select=* to return everything? The API sez:
By default, only a limited set of properties are returned
(businessPhones, displayName, givenName, id, jobTitle, mail,
mobilePhone, officeLocation, preferredLanguage, surname,
userPrincipalName).
This is a contrived example however I have simplified it for ease of explanation.
Please see my update at the bottom before investing too much of your
time!
Background
I have some (a lot of) code that ordinarily queries my DB as follows:
SELECT name FROM sites where IsLive=1;
My challenge is to, under certain conditions, return the full list of sites, essentially
SELECT name from sites;
I do not wish to modify the actual C# code issuing the SQL (although I can do if I have to in order to achieve my goal which is purely for demonstration purposes).
Therefore in order to leave as much untouched as possible my thoughts are to insert a database-proxy-view called site that returns the data dependent on a control variable
Method
Rename existing site table to site_table
Create a new view named site that the C# code now unknowingly targets and which returns the (possibly filtered) details from site_table according to the control variable value (Note a limitation on variables in views meant I had to create a function in order to demonstrate this - see http://dev.mysql.com/doc/refman/5.7/en/create-view.html wrt error 1351)
Changes made
ALTER TABLE site RENAME TO site_table;
CREATE FUNCTION controlVariableFn() RETURNS VARCHAR(16) RETURN #controlVariable;
CREATE OR REPLACE VIEW site AS SELECT * from site_table WHERE (IsLive = 1 OR controlVariableFn() = 'SHOWALL');
The above statements are ugly but achieve the result I want, however my problem is to dynamically pass through controlVariable without changing my main SQL queries being sent.
My Question
Is there a way to (ideally as I am creating my connection object) define the controlVariable outside the actual SQL to be executed but which the View can still access similar to the above as though it had been supplied as a regular user variable parameter to the query?
so the code would look something like
var connectionString = "Server=localhost;User ID=un;Password=pw;Database=dbname;....";
DbConnection db = new MySql.Data.MySqlClient.MySqlConnection
(connectionString, "controlVariable=SHOWALL");
var results = db.Query<Site>("SELECT * FROM site;");
(I understand that this would not be a smart permanent solution)
Update
My preferred solution as outlined above will not work for me as once I get into my data access layer as the results set will
essentially be filtered again back to the original set. There are some circumstances where it
could work; it would depend on the SQL issued (e.g. when collapsing a
results set down instead of trying to expand a results set as I was
trying to do here).
In that regard I am no longer looking for an answer here but will leave it for posterity as a preferred option and as per the guidelines - thanks anyway.
If you do not want to edit the c# code then the variable will have to be stored in the database although i am not sure how you will not edit the code.
If you are willing to edit the code then you can access a secondary configuration table which will have the settings that you would like the user to pass to the view. take this and allow the user to select which they want and then pass it to the view through the application.
I'm using v2.0 of the API via the C# dll. But this problem also happens when I pass a Query String to the v2.0 API via https://rally1.rallydev.com/slm/doc/webservice/
I'm querying at the Artifact level because I need both Defects and Stories. I tried to see what kind of query string the Rally front end is using, and it passes custom fields and built-in fields to the artifact query. I am doing the same thing, but am not finding any luck getting it to work.
I need to be able to filter out the released items from my query. Furthermore, I also need to sort by the custom c_ReleaseType field as well as the built-in DragAndDropRank field. I'm guessing this is a problem because those built-in fields are not actually on the Artifact object, but why would the custom fields work? They're not on the Artifact object either. It might just be a problem I'm not able to guess at hidden in the API. If I can query these objects based on custom fields, I would expect the ability would exist to query them by built-in fields as well, even if those fields don't exist on the Ancestor object.
For the sake of the example, I am leaving out a bunch of the setup code... and only leaving in the code that causes the issues.
var request = new Request("Artifact");
request.Order = "DragAndDropRank";
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I comment the Order by DragAndDropRank line, it works.
var request = new Request("Artifact");
request.Query = (new Query("c_SomeCustomField", Query.Operator.Equals, "somevalue").
And(new Query("Release", Query.Operator.Equals, "null")));
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I take the Release part out of the query, it works.
var request = new Request("Artifact");
request.Query = (((new Query("TypeDefOid", Query.Operator.Equals, "someID").
And(new Query("c_SomeCustomField", Query.Operator.Equals, "somevalue"))).
And(new Query("DirectChildrenCount", Query.Operator.Equals, "0"))));
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I take the DirectChildrenCount part out of the query, it works.
Here's an example of the problem demonstrated by an API call.
https://rally1.rallydev.com/slm/webservice/v2.0/artifact?query=(c_KanbanState%20%3D%20%22Backlog%22)&order=DragAndDropRank&start=1&pagesize=20
When I remove the Order by DragAndDropRank querystring, it works.
I think most of your trouble is due to the fact that in order to use the Artifact endpoint you need to specify a types parameter so it knows which artifact sub classes to include.
Simply adding that to your example WSAPI query above causes it to return successfully:
https://rally1.rallydev.com/slm/webservice/v2.0/artifact?query=(c_KanbanState = "Backlog")&order=DragAndDropRank&start=1&pagesize=20&types=hierarchicalrequirement,defect
However I'm not tally sure if the C# API allows you to encode additional custom parameters onto the request...
Your question already contains the answer.
UserStory (HierarchicalRequirement in WS API) and Defect inherit some of their fields from Artifact, e.g. FormattedID, Name, Description, LastUpdateDate, etc. You may use those fields in the context of Artifact type.
The fields that you are trying to access on Artifact object do not exist on it. They exist on a child level, e.g. DragAndDropRank, Release, Iteration. It is not possible to use those fields in the context of Artifact type.
Parent objects don't have access to attributes specific to child object.
Artifact is an abstract type.
If you need to filter by Release, you need to make two separate requests - one for stories, the other for defects.
I'm developing an application that does some CRUD operations through a WCF service. The read method returns a complete entity, the update is performed through a legacy system, and only the changed values should be updated.
What is the best way to design the data contract for this scenario without simply sending a dictionary of key-value pairs?
The only other thing I can think of is to make your component durable - i.e. persist its state to a file or database. That way, on the update you can compare the previous state to the state being passed in. I'm not sure that's a good way to go since it will introduce more overhead than just passing in the key-value pairs.
From the outside it might look more CRUDy or whatever, but from a practical standpoint you may be better off just passing some indication as to which values changed.
In case it helps, not sure exactly what you're looking for though ...
In the update request, only act upon fields that are not null.
In addition wrap any non-nullable types in a nullable structure.
As an example ...
Update( Nullable<int> orderNumber,
Nullable<DateTime> orderDate,
Nullable<bool> isComplete )
{
if( orderNumber != null )
databaseRecord.OrderNumber = orderNumber;
if( orderDate != null )
databaseRecord.OrderDate = orderDate;
if( isComplete != null )
databaseRecord.IsComplete = isComplete;
}
the best way to do this is with property dictionary, just represent your entities as dictionary of property name and value.
save all changes in some list and pass a partial dictionary with all changed properties.
i think this is best design,
if u wanna avoid this design, send entire entity with some list of changed properties.
(to save transport u can put null on other properties)
if u don't wanna change the service contract signature u can push the names of modified properties on the header
I had two ideas of how to achieve this;
Have the client send both the original entity, and the changed entity in full, the service would then figure out what properties were changed.
Use a pattern similar to Nullable, lets call it Modified with an IsModified flag and a NewValue property of type T. Each property of the DataContract would be of this type, the service can check the IsModified flag when performing the update.
The legacy sytem we use has an api that accepts String.Empty to identify unmodified fields, a '?' character is used to indicate an update to an empty string. I really don't like this, the user of the api is forced to read the documentation, and if you actually want to store a '?' you can't. I want our webservice api to be more explicit.
You can use DataSet to keep your changes. Call your record as DataSet then assign some values to the record. DataSet.Tables[0].GetChanges() will give you the columns which were changed.
You could leave the data contract alone and update your service contract. Just represent the required fields for the method as properties within the service contract. Any consuming application using the service will have to be updated if the service contact changes, but the consuming application will know what is required to successfully update the data.
There are positives and negatives to this method, but I use it when a method I am writing doesn't require the full data contract.
--Edited for a spelling error--
Looking at your requirements and statements, i've made a few assumptions before starting to write my vision on a possible solution:
You are using the same class for retrieving (return value type of "read" operation) and updating an item (input parameter type of "update" operation) in your WCF service.
Your current problem of implementation is how to use the original class (not a dictionary) AND still be able to determine 'what has changed compared to the read' when you get the "Update" operation called on your WCF service
You are writing both the server and client. Both are written using the MS .Net framework.
If this is true, the problem lies in the Update method missing information. The information required is 'has changed' which could be inferred if a 2nd state is present to compare against or should already be present along side the state to update in the back-end.
Since you only have the 'back-end state' (without flags) when the client posts its data to the WCF service, how should we determine what did change? Obviously, we want to prevent another 'read' roundtrip to get the current server state and start comparing.
Sending the original & changed state from the client to the server is a possible but heavy solution. Next to that, the client isn't interrested in this information, the server is.
Adding this all up makes my guess is that changing the type of the 'Update' operation input parameter is the easiest way to go. Create a decorator class that adds 'dirty bit' behavior to the original entity. Use this new class as input parameter for your "Update" operation. You then will have the availability in the server to check this dirty bit next to the full state send by the client. The major change on the client side is that the object needed for the 'Update' operation is no longer the same as the one provided by the 'Read' method. To eleviate this pain, i would probably create a decorator class which added the required 'dirty bit' handling. This only requires the object instanciation to change, while maintaining the interface signature for the client (very little code changes).