Skip to content

Commit

Permalink
Merge pull request #1756 from microsoftgraph/dev
Browse files Browse the repository at this point in the history
Release 5.3.0
  • Loading branch information
andrueastman authored Mar 22, 2023
2 parents df8a643 + 9232733 commit c77745b
Show file tree
Hide file tree
Showing 180 changed files with 6,431 additions and 303 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validatePullRequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
env:
solutionName: Microsoft.Graph.sln
steps:
- uses: actions/checkout@v3.3.0
- uses: actions/checkout@v3.4.0
- name: Setup .NET
uses: actions/[email protected]
with:
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ and this project does adheres to [Semantic Versioning](https://semver.org/spec/v
## [Unreleased]


## [5.3.0] - 2023-03-21

### Added

- Allows checking for status codes without parsing request bodies in batch requests (https://github.com/microsoftgraph/msgraph-sdk-dotnet-core/pull/626)
- Updates kiota abstraction library dependencies to fix serialization errors.
- Metadata fixes for missing expand clauses for messages,calendar and mailfolder endpoints
- Latest metadata updates from 21st March 2023

## [5.2.0] - 2023-03-14

### Added
Expand Down
38 changes: 30 additions & 8 deletions docs/errors.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
Handling errors in the Microsoft Graph .NET Client Library
=====

Errors in the Microsoft Graph .NET Client Library behave like errors returned from the Microsoft Graph service. You can read more about them [here](https://graph.microsoft.io/en-us/docs/overview/errors).
Errors in the Microsoft Graph .NET Client Library behave like errors returned from the Microsoft Graph service. You can read more about them [here](https://learn.microsoft.com/en-us/graph/errors).

Anytime you make a request against the service there is the potential for an error. In the case of an error, the request will throw a `ServiceException` object with an inner `Error` object that contains the service error details.
Anytime you make a request against the service there is the potential for an error. In the case of an error, the request will throw a `ODataError` exception that contains the service error details and can be handled as below.

## Checking the error
```cs
try
{
await graphServiceClient.Me.PatchAsync(user);
}
catch (ODataError odataError)
{
Console.WriteLine(odataError.Error?.Code);
Console.WriteLine(odataError.Error?.Message);
throw;
}
```


## Checking the error status code

There are a few different types of errors that can occur during a network call. These error codes are defined in [GraphErrorCode.cs](../src/Microsoft.Graph/Enums/GraphErrorCode.cs).
You can check the status code that caused the error as below.

```csharp
catch (ODataError odataError) when (odataError.ResponseStatusCode.Equals(HttpStatusCode.NotFound))
{
// Handle 404 status code
}
```

## Checking the error

### Checking the error code
You can easily check if an error has a specific code by calling `IsMatch` on the error code value. `IsMatch` is not case sensitive:
There are a few different types of errors that can occur during a network call. These most common error codes are defined in [GraphErrorCode.cs](../src/Microsoft.Graph/Enums/GraphErrorCode.cs). These can be checked by matching with the error code value as below.

```csharp
if (exception.IsMatch(GraphErrorCode.AccessDenied.ToString())
catch (ODataError odataError) when (odataError.Error.Code.Equals(GraphErrorCode.AccessDenied.ToString()))
{
// Handle access denied error
}
```

Each error object has a `Message` property as well as code. This message is for debugging purposes and is not be meant to be displayed to the user. Common error codes are defined in [GraphErrorCode.cs](../src/Microsoft.Graph/Enums/GraphErrorCode.cs).
Each error object has a `Message` property as well as code. This message is for debugging purposes and is not be meant to be displayed to the user. Common error codes are defined in [GraphErrorCode.cs](../src/Microsoft.Graph/Enums/GraphErrorCode.cs).
57 changes: 57 additions & 0 deletions docs/upgrade-to-v4.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,63 @@ var device = await graphClient.DeviceManagement.ManagedDevices["1"].Request().Ge
Assert.Equal("1",device.Id);
```

### Collection responses do not have @odata.nextLink in the AdditionalData

Response for collection types are now deserialized into the NextLink property in the collection response object(example [here](https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/23e9386538993ebe08ba88c084831b6163304e27/src/Microsoft.Graph/Generated/requests/AccessPackageAssignmentFilterByCurrentUserCollectionResponse.cs#L31)) and are not available in the additionalData bag. The property is then used to automatically initialize the nextPage request for the collection page and can be accessed as below.

```cs
var users = await graphServiceClient.Users.Request().GetAsync();
var nextLink = users.NextPageRequest.GetHttpRequestMessage().RequestUri.OriginalString;
```

#### Note
It is recommended to use the PageIterator when paging through collections as this allows for advance functionality such as configuring pausing, managing state and access to the DeltaLink and NextLink if needed. An example of using the PageIterator with delta is shown below.

```cs
int count = 0;
int pauseAfter = 25;

var messages = await graphClient.Me.Messages
.Request()
.Select(e => new {
e.Sender,
e.Subject
})
.Top(10)
.GetAsync();

var pageIterator = PageIterator<Message>
.CreatePageIterator(
graphClient,
messages,
(m) =>
{
Console.WriteLine(m.Subject);
count++;
// If we've iterated over the limit,
// stop the iteration by returning false
return count < pauseAfter;
}
);

await pageIterator.IterateAsync();

while (pageIterator.State != PagingState.Complete)
{
if (pageIterator.State == PagingState.Delta)
{
string deltaLink = pageIterator.Deltalink;
Console.WriteLine($"Paged through results and found deltaLink : {deltaLink}");
}

Console.WriteLine("Iteration paused for 5 seconds...");
await Task.Delay(5000);
// Reset count
count = 0;
await pageIterator.ResumeAsync();
}
```

## New capabilities

### Azure Identity
Expand Down
2 changes: 2 additions & 0 deletions src/Microsoft.Graph/Enums/GraphErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public enum GraphErrorCode
NameAlreadyExists,
/// The action is not allowed by the system.
NotAllowed,
/// The requested item is not not found.
NotFound,
/// The request is not supported by the system.
NotSupported,
/// Parameter Exceeds Maximum Length.
Expand Down
85 changes: 85 additions & 0 deletions src/Microsoft.Graph/Extensions/PlannerAssignment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------

using Microsoft.Kiota.Abstractions.Serialization;
using Microsoft.Kiota.Abstractions.Store;
using System;
using System.Collections.Generic;

namespace Microsoft.Graph.Models;

public class PlannerAssignment: IAdditionalDataHolder, IBackedModel, IParsable
{
/// <summary>Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.</summary>
public IDictionary<string, object> AdditionalData {
get { return BackingStore?.Get<IDictionary<string, object>>("additionalData"); }
set { BackingStore?.Set("additionalData", value); }
}
/// <summary>Stores model information.</summary>
public IBackingStore BackingStore { get; private set; }
/// <summary>The OdataType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? OdataType {
get { return BackingStore?.Get<string?>("@odata.type"); }
set { BackingStore?.Set("@odata.type", value); }
}
#nullable restore
#else
public string OdataType {
get { return BackingStore?.Get<string>("@odata.type"); }
set { BackingStore?.Set("@odata.type", value); }
}
#endif
/// <summary>The OdataType property</summary>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public string? OrderHint {
get { return BackingStore?.Get<string?>("orderHint"); }
set { BackingStore?.Set("orderHint", value); }
}
#nullable restore
#else
public string OrderHint {
get { return BackingStore?.Get<string>("orderHint"); }
set { BackingStore?.Set("orderHint", value); }
}
#endif
/// <summary>
/// Instantiates a new auditActivityInitiator and sets the default values.
/// </summary>
public PlannerAssignment() {
BackingStore = BackingStoreFactorySingleton.Instance.CreateBackingStore();
AdditionalData = new Dictionary<string, object>();
OdataType = "#microsoft.graph.plannerAssignment";
OrderHint = "!";
}
/// <summary>
/// Creates a new instance of the appropriate class based on discriminator value
/// </summary>
/// <param name="parseNode">The parse node to use to read the discriminator value and create the object</param>
public static PlannerAssignment CreateFromDiscriminatorValue(IParseNode parseNode) {
_ = parseNode ?? throw new ArgumentNullException(nameof(parseNode));
return new PlannerAssignment();
}
/// <summary>
/// The deserialization information for the current model
/// </summary>
public IDictionary<string, Action<IParseNode>> GetFieldDeserializers() {
return new Dictionary<string, Action<IParseNode>> {
{"@odata.type", n => { OdataType = n.GetStringValue(); } },
{"orderHint", n => { OrderHint = n.GetStringValue(); } },
};
}
/// <summary>
/// Serializes information the current object
/// </summary>
/// <param name="writer">Serialization writer to use to serialize this model</param>
public void Serialize(ISerializationWriter writer) {
_ = writer ?? throw new ArgumentNullException(nameof(writer));
writer.WriteStringValue("@odata.type", OdataType);
writer.WriteStringValue("orderHint", OrderHint);
writer.WriteAdditionalData(AdditionalData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public async Task<ChatMessageCollectionResponse> GetAsync(Action<RepliesRequestB
return await RequestAdapter.SendAsync<ChatMessageCollectionResponse>(requestInfo, ChatMessageCollectionResponse.CreateFromDiscriminatorValue, errorMapping, cancellationToken);
}
/// <summary>
/// Create a new reply to a chatMessage in a specified channel.
/// Find more info here <see href="https://docs.microsoft.com/graph/api/channel-post-messagereply?view=graph-rest-1.0" />
/// Send a new reply to a chatMessage in a specified channel.
/// Find more info here <see href="https://docs.microsoft.com/graph/api/chatmessage-post-replies?view=graph-rest-1.0" />
/// </summary>
/// <param name="body">The request body</param>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
Expand Down Expand Up @@ -132,7 +132,7 @@ public RequestInformation ToGetRequestInformation(Action<RepliesRequestBuilderGe
return requestInfo;
}
/// <summary>
/// Create a new reply to a chatMessage in a specified channel.
/// Send a new reply to a chatMessage in a specified channel.
/// </summary>
/// <param name="body">The request body</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public async Task<ChatMessageCollectionResponse> GetAsync(Action<MessagesRequest
return await RequestAdapter.SendAsync<ChatMessageCollectionResponse>(requestInfo, ChatMessageCollectionResponse.CreateFromDiscriminatorValue, errorMapping, cancellationToken);
}
/// <summary>
/// Send a new chatMessage in the specified channel or a chat.
/// Find more info here <see href="https://docs.microsoft.com/graph/api/chatmessage-post?view=graph-rest-1.0" />
/// Send a new chatMessage in the specified chat. This API can&apos;t create a new chat; you must use the list chats method to retrieve the ID of an existing chat before you can create a chat message.
/// Find more info here <see href="https://docs.microsoft.com/graph/api/chat-post-messages?view=graph-rest-1.0" />
/// </summary>
/// <param name="body">The request body</param>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
Expand Down Expand Up @@ -132,7 +132,7 @@ public RequestInformation ToGetRequestInformation(Action<MessagesRequestBuilderG
return requestInfo;
}
/// <summary>
/// Send a new chatMessage in the specified channel or a chat.
/// Send a new chatMessage in the specified chat. This API can&apos;t create a new chat; you must use the list chats method to retrieve the ID of an existing chat before you can create a chat message.
/// </summary>
/// <param name="body">The request body</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public InviteRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) {
RequestAdapter = requestAdapter;
}
/// <summary>
/// Invite participants to the active call. For more information about how to handle operations, see commsOperation.
/// Find more info here <see href="https://docs.microsoft.com/graph/api/participant-invite?view=graph-rest-1.0" />
/// Delete a specific participant in a call. In some situations, it is appropriate for an application to remove a participant from an active call. This action can be done before or after the participant answers the call. When an active caller is removed, they are immediately dropped from the call with no pre- or post-removal notification. When an invited participant is removed, any outstanding add participant request is canceled.
/// Find more info here <see href="https://docs.microsoft.com/graph/api/participant-delete?view=graph-rest-1.0" />
/// </summary>
/// <param name="body">The request body</param>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
Expand All @@ -69,7 +69,7 @@ public async Task<InviteParticipantsOperation> PostAsync(InvitePostRequestBody b
return await RequestAdapter.SendAsync<InviteParticipantsOperation>(requestInfo, InviteParticipantsOperation.CreateFromDiscriminatorValue, errorMapping, cancellationToken);
}
/// <summary>
/// Invite participants to the active call. For more information about how to handle operations, see commsOperation.
/// Delete a specific participant in a call. In some situations, it is appropriate for an application to remove a participant from an active call. This action can be done before or after the participant answers the call. When an active caller is removed, they are immediately dropped from the call with no pre- or post-removal notification. When an invited participant is removed, any outstanding add participant request is canceled.
/// </summary>
/// <param name="body">The request body</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
Expand Down
Loading

0 comments on commit c77745b

Please sign in to comment.