0
votes

I have SharePoint List which content a Reference No. It'd URL look like this: https://xyz.sharepoint.com/sites/site_name/Lists/List_name/AllItems.aspx

This List content ref no. I am trying to insert this data in the list.

{
"Optimum_x0020_Case_x0020_Reference": "000777"
} 

This is url I am posting the data. https://graph.microsoft.com/v1.0/sites/xyz.sharepoint.com:/sites/site_name:/lists/List_names/items

But I am getting this error:

error": {
"code": "accessDenied",
"message": "The caller does not have permission to perform the action.",

How to solve this? Using the access I am able to create folder, sub folder and Update meta data for other document.

1

1 Answers

0
votes

What is the context of what you are doing this with? Is it an app that you are using? Are you inserting data on a already existing listitem or a new item?

This is the code I had to use for my UWP App. I'm not sure if this will help you or not, but it should give you a little guidance I hope. Creating the dictionary and figuring out the XML structure were the keys things I had to piece together to get my code to work.

I declared my scopes in my App.xaml.cs

    public static string[] scopes = new string[] { "user.ReadWrite", "Sites.ReadWrite.All", "Files.ReadWrite.All" };

I have a submit button that I use on my MainPage

    private async void SubmitButton_Click(object sender, RoutedEventArgs e)
    {
       var (authResult, message) = await Authentication.AquireTokenAsync();

        if (authResult != null)
        {
            await SubmitDataWithTokenAsync(submiturl, authResult.AccessToken);
        }
    }

This calls the AquireToken which I have in a class file:

    public static async Task<(AuthenticationResult authResult, string message)> AquireTokenAsync()
    {
        string message = String.Empty;
        string[] scopes = App.scopes;

        AuthenticationResult authResult = null;
        message = string.Empty;
        //TokenInfoText.Text = string.Empty;

        IEnumerable<IAccount> accounts = await App.PublicClientApp.GetAccountsAsync();
        IAccount firstAccount = accounts.FirstOrDefault();

        try
        {
            authResult = await App.PublicClientApp.AcquireTokenSilentAsync(scopes, firstAccount);
        }
        catch (MsalUiRequiredException ex)
        {
            // A MsalUiRequiredException happened on AcquireTokenSilentAsync. This indicates you need to call AcquireTokenAsync to acquire a token
            System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

            try
            {
                authResult = await App.PublicClientApp.AcquireTokenAsync(scopes);
            }
            catch (MsalException msalex)
            {
                message = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
            }
        }
        catch (Exception ex)
        {
            message = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";
        }
        return (authResult,message);
    }

I had created another class for my SharePointList

public class SharePointListItems { public class Lookup { public string SerialNumber { get; set; } public string id { get; set; } public override string ToString() { return SerialNumber; } }

public class Value
{
    public Lookup fields { get; set; }
}

    public class Fields
    {
        [JsonProperty("@odata.etag")]
        public string ODataETag { get; set; }

        public string ParameterA { get; set; }
        public string ParameterB { get; set; }
        public string ParameterC { get; set; }
    }

    public class RootObject
    {
        [JsonProperty("@odata.context")]
        public string ODataContext { get; set; }

        [JsonProperty("@odata.etag")]
        public string ODataETag { get; set; }

        [JsonProperty("[email protected]")]
        public string FieldsODataContext { get; set; }

        public Fields Fields { get; set; }
    }    
}

I used this class to create a dictionary for submitting my data to SharePoint.

    public async Task<string> SubmitDataWithTokenAsync(string url, string token)
    {
        var httpClient = new HttpClient();
        HttpResponseMessage response;
        try
        {
            var root = new
            {
                fields = new Dictionary<string, string>
                {
                   // The second string are public static strings that I
                   // I declared in my App.xaml.cs because of the way my app
                   // is set up.
                   { "ParameterA", App.ParameterA },
                   { "ParameterB", App.ParameterB },
                   { "ParameterC", App.ParameterC },
                }
            };

            var s = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat };
            var content = JsonConvert.SerializeObject(root, s);
            var request = new HttpRequestMessage(HttpMethod.Post, url);
            //Add the token in Authorization header
            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            request.Content = new StringContent(content, Encoding.UTF8, "application/json");
            response = await httpClient.SendAsync(request);
            var responseString = await response.Content.ReadAsStringAsync();                
            return responseString;
        }
        catch (Exception ex)
        {
            return ex.ToString();
        }
    }

And my submiturl is defined:

    public static string rooturl = "https://graph.microsoft.com/v1.0/sites/xxxxxx.sharepoint.com,495435b4-60c3-49b7-8f6e-1d262a120ae5,0fad9f67-35a8-4c0b-892e-113084058c0a/";
    string submiturl = rooturl + "lists/18a725ac-83ef-48fb-a5cb-950ca2378fd0/items";

You can also look at my posted question on a similar topic here.