microsoftgraph / msgraph-sdk-dotnet

Microsoft Graph Client Library for .NET!
https://graph.microsoft.com
Other
689 stars 246 forks source link

[Client bug]: Missing methods for workbook range resource type in v5 #1873

Open MartinM85 opened 1 year ago

MartinM85 commented 1 year ago

Describe the bug In the current version 5.9.0 users can get a set of one or more workbook cells.

There is no way to update/insert/delete/merge/unmerge/clear range and get/update range format.

API calls

GET /me/drive/items/{id}/workbook/worksheets/{id|name}/range(address='<address>')
GET /me/drive/root:/{item-path}:/workbook/worksheets/{id|name}/range(address='<address>')
GET /me/drive/items/{id}/workbook/tables/{id|name}/columns/{id|name}/range
GET /me/drive/root:/{item-path}:/workbook/tables/{id|name}/columns/{id|name}/range

v5 client methods

graphClient.Drives["driveId"].Items["itemId"].Workbook.Names["name"].Range.GetAsync()
graphClient.Drives["driveId"].Items["itemId"].Workbook.Tables["tableName"].Range.GetAsync()
graphClient.Drives["driveId"].Items["itemId"].Workbook.Worksheets["worksheet"].Range.GetAsync()

There is a RangeRequestBuilder class in different namespaces.

Microsoft.Graph.Drives.Item.Items.Item.Workbook.Names.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Tables.Item.Columns.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Tables.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Tables.Item.Rows.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Worksheets.Item.Names.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Worksheets.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Worksheets.Item.Tables.Item.Columns.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Worksheets.Item.Tables.Item.RangeNamespace.RangeRequestBuilder
Microsoft.Graph.Drives.Item.Items.Item.Workbook.Worksheets.Item.Tables.Item.Rows.Item.RangeNamespace.RangeRequestBuilder

All RangeRequestBuilder classes are missing methods for the following endpoints

update range insert range delete range merge range unmerge range clear range get range format update range format bounding rect cell column columns after columns before entire row intersection last cell last column last row offset range row rows above rows below used range resized range visible view

To Reproduce Steps to reproduce the behavior:

  1. Check all RangeRequestBuilder classes.
  2. There is only GetAsync() method
  3. Other methods are missing

Expected behavior All RangeRequestBuilder classes contains all methods.

Client version 5.9.0

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

annerajb commented 1 year ago

Stumbled upon this trying to call .VisibleView() and finding out that the SDK does not have it :/

dmstrat commented 1 year ago

Is this project open enough to start assigning the clear range as a contribution? I'd really like to see these missing functions as it all worked in v1 but I have to move to .net 6 before I start adding more bridges to my application and this is really making things unpleasant to work in MSGraph's updated code base. Is there a workaround in the MSGraph SDK to get the clear function working?

MartinM85 commented 1 year ago

Is this project open enough to start assigning the clear range as a contribution? I'd really like to see these missing functions as it all worked in v1 but I have to move to .net 6 before I start adding more bridges to my application and this is really making things unpleasant to work in MSGraph's updated code base. Is there a workaround in the MSGraph SDK to get the clear function working?

@dmstrat Great question. I'm not sure whether the contribution is possible because the SDK is auto-generated by Kiota from metadata, and probably metadata itself are auto-generated.

@andrueastman Could you please advise, how we can contribute to this repo?

dmstrat commented 1 year ago

If it is autogenerated from what I can only assume is the API source, then why is it missing so many features/functions?

aoisupersix commented 11 months ago

I would like to use update range, but this problem seems to be unresolved even in version 5.28.0. Therefore unfortunately, I have created a own RequestBuilder to solve this problem:

public record RangeUpdateRequestBody
{
    public IReadOnlyCollection<IReadOnlyCollection<string?>>? Values { get; init; } = null;
    ...
}

public class RangeRequestBuilder : BaseRequestBuilder
{
    public RangeRequestBuilder(IRequestAdapter requestAdapter, string driveId, string driveItemId, string workbookWorksheetNameOrId, string address) : base(
        requestAdapter,
        "{+baseurl}/drives/{driveId}/items/{driveItemId}/workbook/worksheets/{workbookWorksheetNameOrId}/range(address='{address}')",
        new Dictionary<string, object>())
    {
        if (string.IsNullOrEmpty(RequestAdapter.BaseUrl))
        {
            RequestAdapter.BaseUrl = "https://graph.microsoft.com/v1.0";
        }

        PathParameters.Add("baseurl", RequestAdapter.BaseUrl);
        PathParameters.Add("driveId", driveId);
        PathParameters.Add("driveItemId", driveItemId);
        PathParameters.Add("workbookWorksheetNameOrId", workbookWorksheetNameOrId);
        PathParameters.Add("address", address);
    }

    public async Task<WorkbookRange?> PatchAsync(RangeUpdateRequestBody body, string? workbookSessionId = null, CancellationToken cancellationToken = default)
    {
        var requestInfo = ToPatchRequestInformation(body, workbookSessionId);

        return await RequestAdapter
            .SendAsync<WorkbookRange>(requestInfo, WorkbookRange.CreateFromDiscriminatorValue, null, cancellationToken)
            .ConfigureAwait(false);
    }

    public RequestInformation ToPatchRequestInformation(RangeUpdateRequestBody body, string? workbookSessionId = null)
    {
        var requestInfo = new RequestInformation
        {
            HttpMethod = Method.PATCH,
            UrlTemplate = UrlTemplate,
            PathParameters = PathParameters,
        };

        requestInfo.Headers.Add("Accept", MediaTypeNames.Application.Json);
        requestInfo.Headers.Add("Content-Type", MediaTypeNames.Application.Json);

        if (workbookSessionId != null)
        {
            requestInfo.Headers.Add("Workbook-Session-Id", workbookSessionId);
        }

        var jsonBody = JsonConvert.SerializeObject(body, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
        var bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonBody));
        requestInfo.Content = bodyStream;

        return requestInfo;
    }
}
var rangeRequestBuilder = new RangeRequestBuilder(graphClient.RequestAdapter, "DriveID", "FileID", "SheetName", "Address");
var result = await rangeRequestBuilder.PatchAsync(new() { Values = new[] { new[] { "Value" } } });
baywet commented 11 months ago

Hi everyone, Thanks for your patience on the matter.

The good news is that @MartinM85 started a pull request in the conversion process at https://github.com/microsoft/OpenAPI.NET.OData/pull/431

Long story short here is how we produce the SDKs:

  1. The different service teams edit a CSDL file that describes the API surface.
  2. weekly (on Tuesdays) we convert the CSDL to OpenAPI using hidi, which itself relies on the conversion library the PR was opened for.
  3. we feed the converted OpenAPI description to Kiota to generate and open a pull request on the SDKs
  4. The SDK gets validated and released

CSDL is the IDL of OData, and OData relies on a lot of implicit conventions, including the composable functions and the containment (contains target, where the data "lives"). To avoid over expansion (the SDK size getting out of control), we only expand functions on canonical paths. What that means is once the fix is in place, the functions will ONLY be made available under /drives/{id}/root:/{item-path}:/workbook/tables/{id|name}/columns/{id|name}/range/row NOT under /me, or /users or /groups. For those other scenarios, you can build the URL yourselves and use the new with URL method

E.g.

var manuallyBuiltUrl = "https://graph.microsoft.com/v1.0/users/id/drive/root:/{item-path}:/workbook/tables/{id|name}/columns/{id|name}/range/row";
var rowResult = await client.Drives["doesntmatter"].Items["doesntmatter"].Workbook.Tables["doesntMatter"].Columns["doesntMatter"].Range.Row.WithUrl(manuallyBuiltUrl).GetAsync();

I hope this lengthy reply addresses some of the interrogations you had regarding how the release process works and why the functions are missing to date.

Lastly I'd like to address this comment from @dmstrat

I'd really like to see these missing functions as it all worked in v1 but I have to move to .net 6 before I start adding more bridges to my application and this is really making things unpleasant to work in MSGraph's updated code base

Are you saying that you lost functionality upgrading from SDK v4 to v5? v5 is dotnet framework compatible, like v4 was. v5 supports many more API endpoints than v4 ever supported (about 30 to 40% more), in facts the excel APIs were entirely missing from the v4.

vpetit-reimagine commented 6 months ago

Hi everyone, Thanks for your patience on the matter.

The good news is that @MartinM85 started a pull request in the conversion process at microsoft/OpenAPI.NET.OData#431

Long story short here is how we produce the SDKs:

1. The different service teams edit a CSDL file that describes the API surface.

2. weekly (on Tuesdays) we convert the CSDL to OpenAPI using hidi, which itself relies on the conversion library the PR was opened for.

3. we feed the converted OpenAPI description to Kiota to generate and open a pull request on the SDKs

4. The SDK gets validated and released

CSDL is the IDL of OData, and OData relies on a lot of implicit conventions, including the composable functions and the containment (contains target, where the data "lives"). To avoid over expansion (the SDK size getting out of control), we only expand functions on canonical paths. What that means is once the fix is in place, the functions will ONLY be made available under /drives/{id}/root:/{item-path}:/workbook/tables/{id|name}/columns/{id|name}/range/row NOT under /me, or /users or /groups. For those other scenarios, you can build the URL yourselves and use the new with URL method

E.g.

var manuallyBuiltUrl = "https://graph.microsoft.com/v1.0/users/id/drive/root:/{item-path}:/workbook/tables/{id|name}/columns/{id|name}/range/row";
var rowResult = await client.Drives["doesntmatter"].Items["doesntmatter"].Workbook.Tables["doesntMatter"].Columns["doesntMatter"].Range.Row.WithUrl(manuallyBuiltUrl).GetAsync();

I hope this lengthy reply addresses some of the interrogations you had regarding how the release process works and why the functions are missing to date.

Lastly I'd like to address this comment from @dmstrat

I'd really like to see these missing functions as it all worked in v1 but I have to move to .net 6 before I start adding more bridges to my application and this is really making things unpleasant to work in MSGraph's updated code base

Are you saying that you lost functionality upgrading from SDK v4 to v5? v5 is dotnet framework compatible, like v4 was. v5 supports many more API endpoints than v4 ever supported (about 30 to 40% more), in facts the excel APIs were entirely missing from the v4.

It is indeed the case that some functionalities are lost between v4 and v5, or they are really not well documented enough anywhere and they are not easily discoverable. The documentation also lacks useful examples in some places.

MartinM85 commented 6 months ago

@vpetit-reimagine The Graph API docs for workbook API is totally different story. Owners of workbook API responsible for keeping the doc up-to-date are not active at all, so the doc is lack of examples. On the other hand, code snippets are generated and the code snippets generator requires the functionalities to be implemented in v5.

craig-blowfield commented 1 month ago

As a developer the explanation by @vpetit-reimagine of how the process works is deeply worrying. There is a clear lack of responsibility across this process within MS and the various teams involved in that 'chain' in ensuring us (devs) have a good experience. For example my experience is

  1. Workbook API in the SDK doesn't work ->
  2. Talk to the Graph team ->
  3. That's the Workbook team

Or

  1. Workbook API in the SDK doesn't work ->
  2. Issue in the Kiota tool, waiting for that team

Its a pretty poor situation and I don't think I have ever experienced this working with any other SDK.