diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index f900ddf41..67b987f8d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -108,14 +108,14 @@ remove: Total 10 (delta 1), reused 10 (delta 1) Unpacking objects: 100% (10/10), done. ``` -## Switch to `master` branch +## Switch to `main` branch -In order to add your changes, you will need to do those in the `master` branch. +In order to add your changes, you will need to do those in the `main` branch. -Type the following command in the console to switch to `master` branch: +Type the following command in the console to switch to `main` branch: ``` -git checkout master +git checkout main ``` Now, you can update existing docs or add new docs to the docs repo. @@ -131,15 +131,15 @@ Depending on the doc's intent, you can choose to add your doc into `basics` or ## Submit a pull request -Once you have completed adding your changes, you can submit a pull request. +Once you have completed adding your changes, you can submit a pull request. -Navigate to the forked sp-dev-docs repo in your account. Make sure your current branch is `master` branch. +Navigate to the forked sp-dev-docs repo in your account. Make sure your current branch is `main` branch. -Once you are in the `master` branch, you should see a message stating `This branch is 1 commit ahead of SharePoint:master` and next to it will be a `Pull request` link. +Once you are in the `main` branch, you should see a message stating `This branch is 1 commit ahead of Sharepoint:main` and next to it will be a `Pull request` link. ![Submit a pull request to sp-dev-docs repo](../images/contribute-docs-submit-pr.png) -Click the `Pull request` link to start a new pull request. Make sure you use this [template](PULL_REQUEST_TEMPLATE.md) to fill in your changes. Make sure you are creating this pull request against the `master` branch. +Click the `Pull request` link to start a new pull request. Make sure you use this [template](PULL_REQUEST_TEMPLATE.md) to fill in your changes. Make sure you are creating this pull request against the `main` branch. Once you have all the information, click the `Create pull request` button to submit your pull request. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index bca528687..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,52 +0,0 @@ -> Thank you for reporting an issue or suggesting an enhancement. We appreciate your feedback - to help the team to understand your needs, please complete the below template to ensure we have the necessary details to assist you. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ -> - -#### Category -- [ ] Question -- [ ] Typo -- [ ] Bug -- [ ] Additional article idea -- [x] Example checked item (*delete this line*) - -> For the above list, an empty checkbox is [ ] as in [SPACE]. A checked checkbox is [x] with no space between the brackets. Use the `PREVIEW` tab at the top right to preview the rendering before submitting your issue. -> -> If you are planning to share a new feature request (enhancement / suggestion), please use SP Dev UserVoice at https://aka.ms/sp-dev-uservoice. (DELETE THIS PARAGRAPH AFTER READING) -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ -> - -#### Expected or Desired Behavior - -> If you are reporting a bug, please describe the expected behavior. If you are suggesting an enhancement please describe thoroughly the enhancement, how it can be achieved, and expected benefit. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ -> - -#### Observed Behavior - -> If you are reporting a bug, please describe the behavior you expected to occur when performing the action. If you are making a suggestion, you can delete this section. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ -> - -#### Steps to Reproduce - -> If you are reporting a bug please describe the steps to reproduce the bug in sufficient detail to allow testing. Only way to fix things properly, is to have sufficient details to reproduce it. If you are making a suggestion, you can delete this section. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ -> - -#### Submission Guidelines - -> - All suggestions or bugs are welcome, please let us know what's on your mind. -> - If you are reporting an issue around any of the documents or articles, please ensure that you have clear > reference on the specific file or URL, which should be fixed. -> - If you have technical questions about the framework, we’ll be monitoring #spfx, #spfx-webparts, and > #spfx-tooling on (SharePoint StackExchange)[http://sharepoint.stackexchange.com/]. You can also > alternatively submit your question to (SharePoint Developer group)> [https://network.office.com/t5/SharePoint-Developer/bd-p/SharePointDev] at Office Network. -> - Remember to include sufficient details and context. -> - If you have multiple suggestions or bugs please submit them in separate bugs so we can track resolution. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ -> - -Thanks for your contribution! Sharing is caring. diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 000000000..6d3825f0c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,116 @@ +name: 🐞 Bug or Error Report +description: Submit a bug or error report. +labels: ['Needs: Triage', 'type:bug-suspected'] + +body: +- type: markdown + attributes: + value: | + - [x] Bug + + This is for SharePoint development bugs. If your submission is not about SharePoint development such as out-of-the-box capabilities, SharePoint configuration, please refer to other support options listed on the [new issue chooser page](https://github.com/SharePoint/sp-dev-docs/issues/new/choose). Please provide as much information as possible so we can best address your submission. Thanks! + + - Follow our guidance on [How To Create Good Issues](https://github.com/sharepoint/sp-dev-docs/wiki/How-to-Create-Good-Issues). + - Remember to include sufficient details and context. + - If you have multiple questions, suggestions, or bugs, please submit them in separate issues. + + Please provide the following details about your environment. 🚨 *If this section is ignored, your submission will be flagged as **incomplete** & automatically closed.* + +- type: dropdown + attributes: + label: Target SharePoint environment + options: + - SharePoint Online + - SharePoint Server 2019 (on-premise) + - SharePoint Server 2016 (on-premise) + - other (enter in the "Additional environment details" area below) + validations: + required: true + +- type: dropdown + attributes: + label: What SharePoint development model, framework, SDK or API is this about? + description: | + What tooling, frameworks, SDKs, or official libraries is this related to? Please include the version details in the *"Additional environment details"* field below. + + **This form is only for officially supported Microsoft products**. + + *If your question is about a third-party or another library/SDK/tooling that is not officially supported by Microsoft, please submit your issue to that project's relevant forum.* + + **NOTE**:💥 If you select SharePoint Framework, you must include the following version numbers in the **Additional environment details** section below: 1️⃣ SharePoint Framework & 2️⃣ Node.js (`node -v`). + options: + - 💥 SharePoint Framework + - SharePoint Add-ins + - SharePoint CSOM + - SharePoint REST API + - Site designs & site scripts + - Declarative list formatting + - not applicable + - other (enter in the "Additional environment details" area below) + validations: + required: true + +- type: dropdown + attributes: + label: Developer environment + options: + - Windows + - macOS + - Linux + +- type: checkboxes + attributes: + label: What browser(s) / client(s) have you tested + description: | + Select the browser(s)/clients this submission is relevant to. + + **NOTE**:💥 If you select an item with this icon, you must include the version number of the selection in the **Additional environment details** section below. + options: + - label: 💥 Internet Explorer + - label: 💥 Microsoft Edge + - label: 💥 Google Chrome + - label: 💥 FireFox + - label: 💥 Safari + - label: mobile (iOS/iPadOS) + - label: mobile (Android) + - label: not applicable + - label: other (enter in the "Additional environment details" area below) + +- type: textarea + attributes: + label: Additional environment details + description: Include as much detail about the environment you're targetting. This is required if "other (enter below)" is selected in the previous field. + value: | + - browser version + - SPFx version + - Node.js version + - etc + +- type: markdown + attributes: + value: | + Provide a clear & concise description of what the bug is. Please follow our guidance on [How To Create Good Issues](https://github.com/sharepoint/sp-dev-docs/wiki/How-to-Create-Good-Issues) which explains how to apply formatting, adding references & resources, screenshots, etc. **Do not attach ZIP files** of your code or compiled projects - instead, please publish your code to a public GitHub repo & post a link to it. + +- type: textarea + attributes: + label: Describe the bug / error + validations: + required: true + +- type: textarea + attributes: + label: Steps to reproduce + description: How do you reproduce this? Please provide as much step-by-step detail as possible. + value: | + 1. + 2. + 3. + validations: + required: true + +- type: textarea + attributes: + label: Expected behavior + description: What did you expect to happen when the reproduce steps are followed? + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..419103265 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: true +contact_links: + - name: Feature Request / Change Request + url: https://aka.ms/sp-dev-uservoice + about: Feature requests should be submitted to the SharePoint Dev UserVoice site. + - name: SharePoint Developer Documentation + url: https://docs.microsoft.com/sharepoint/dev + about: All developer documentation for SharePoint can be found here. + - name: SharePoint TechCommunity + url: https://techcommunity.microsoft.com/t5/SharePoint/ct-p/SharePoint + about: Please submit non-developer questions/reports to the SharePoint TechCommunity site. This includes anything related to administrator, end-user, or user experience capabilities, questions, and errors. diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 000000000..dbb8092af --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,93 @@ +name: 🤔 Question or generic issue +description: Do you have a question? Or is it something else that doesn't fit one of the links below? Select this option! +labels: 'Needs: Triage' + +body: +- type: markdown + attributes: + value: | + This is for SharePoint development topics. If your submission is now about SharePoint development such as out-of-the-box capabilities, SharePoint configuration, please use refer to other support options listed on the [new issue chooser page](https://github.com/SharePoint/sp-dev-docs/issues/new/choose). Please provide as much information as possible so we can best address your submission. Thanks! + + - Follow our guidance on [How To Create Good Issues](https://github.com/sharepoint/sp-dev-docs/wiki/How-to-Create-Good-Issues). + - Remember to include sufficient details and context. + - If you have multiple questions, suggestions, or bugs, please submit them in separate issues. + + Please provide the following details about your environment. 🚨 *If this section is ignored, your submission will be flagged as **incomplete** & automatically closed.* + +- type: dropdown + attributes: + label: What type of issue is this? + options: + - Question + - Documentation issue / typo + - other + validations: + required: true + +- type: dropdown + attributes: + label: What SharePoint development model, framework, SDK or API is this about? + description: | + What tooling, frameworks, SDKs, or official libraries is this related to? Please include the version details in the *"Additional environment details"* field below. + + **This form is only for officially supported Microsoft products**. + + *If your question is about a third-party or another library/SDK/tooling that is not officially supported by Microsoft, please submit your issue to that project's relevant forum.* + + **NOTE**:💥 If you select SharePoint Framework, you must include the following version numbers in the **Additional environment details** section below: 1️⃣ SharePoint Framework & 2️⃣ Node.js (`node -v`). + options: + - 💥 SharePoint Framework + - SharePoint Add-ins + - SharePoint CSOM + - SharePoint REST API + - Site designs & site scripts + - Declarative list formatting + - not applicable + - other (enter in the "Additional environment details" area below) + validations: + required: true + +- type: dropdown + attributes: + label: Target SharePoint environment + options: + - SharePoint Online + - SharePoint Server 2019 (on-premise) + - SharePoint Server 2016 (on-premise) + - other (enter in the "Additional environment details" area below) + validations: + required: true + +- type: checkboxes + attributes: + label: What browser(s) / client(s) have you tested + description: | + Select the browser(s)/clients this submission is relevant to. + + **NOTE**:💥 If you select an item with this icon, you must include the version number of the selection in the **Additional environment details** section below. + options: + - label: 💥 Internet Explorer + - label: 💥 Microsoft Edge + - label: 💥 Google Chrome + - label: 💥 FireFox + - label: 💥 Safari + - label: mobile (iOS/iPadOS) + - label: mobile (Android) + - label: not applicable + - label: other (enter in the "Additional environment details" area below) + +- type: textarea + attributes: + label: Additional environment details + description: Include as much detail about the environment you're targetting. This is required if "other (enter below)" is selected in the previous field. + value: | + - browser version + - SPFx version + - Node.js version + - etc + +- type: textarea + attributes: + label: Issue description + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b6137b463..99aeec9af 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,31 +1,30 @@ -#### Category +## Category + - [ ] Content fix - [ ] New article - [x] Example checked item (*delete this line*) -> For the above list, an empty checkbox is [ ] as in [SPACE]. A checked checkbox is [x] with no space between the brackets. Use the `PREVIEW` tab at the top right to preview the rendering before submitting your issue. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ +> **DELETE THIS LINE BEFORE SUBMITTING** | *For the above list, an empty checkbox is [ ] as in [SPACE]. A checked checkbox is [x] with no space between the brackets. Use the `PREVIEW` tab at the top right to preview the rendering before submitting your issue.* + +## Related issues -#### Related issues: - fixes #issuenumber - partially #issuenumber - mentioned in #issuenumber -> If this fixes (aka: closes) or references an issue, please reference it here. This helps maintaining the issue list as it will (1) link the PR to the issue & (2) automatically close the issue when this PR is merged in. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ +> **DELETE THIS LINE BEFORE SUBMITTING** | *If this fixes (aka: closes) or references an issue, please reference it here. This helps maintaining the issue list as it will (1) link the PR to the issue & (2) automatically close the issue when this PR is merged in.* -#### What's in this Pull Request? +## What's in this Pull Request? -> Please describe the changes in this PR. Sample description or details around bugs which are being fixed. -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ +> **DELETE THIS LINE BEFORE SUBMITTING** | *Please describe the changes in this PR. Sample description or details around bugs which are being fixed.* -#### Guidance +## Submission guidelines -> *Please update this PR information accordingly. We'll use this as part of our release notes in monthly communications.* -> -> *Please target your PR to 'master' branch. Released documents are in `live` branch.* -> -> _(DELETE THIS PARAGRAPH AFTER READING)_ \ No newline at end of file +> - **!!IMPORTANT!!** - All submissions must complete the baseline sections included in this template. Ignoring or deleting this template may result in closing the issue with the label **type:incomplete-submission**. +> - Follow our guidance on [How To Create Good Pull Requests](https://github.com/SharePoint/sp-dev-docs/wiki/How-to-Create-Good-Pull-Requests). +> - Target the `main` branch of this repo. +> - When changing a page, ensure you update the `ms.date` front matter wih the current date in the format `MM/DD/YYYY`. +> - Review all build checks and address the automated errors, warnings, and suggestions. +> - *NOTE: The live site is based on the `live` branch. Site owners periodically refresh `live` branch from the `main` branch so merged PRs won't immediately appear on the live site. Please be patient to see your changes appear on the live site.* +> +> **DELETE THIS SECTION BEFORE SUBMITTING** diff --git a/.github/fabricbot.json b/.github/fabricbot.json new file mode 100644 index 000000000..6dcaf2f39 --- /dev/null +++ b/.github/fabricbot.json @@ -0,0 +1,1149 @@ +{ + "version": "1.0", + "tasks": [ + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isEvent", + "parameters": { + "eventName": "issues" + } + }, + { + "name": "isAction", + "parameters": { + "action": "opened" + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isAssignedToSomeone", + "parameters": {} + } + ] + } + ] + }, + "taskName": "Auto-label incoming issues as Needs Triage", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible." + } + }, + { + "name": "addLabels", + "parameters": { + "labels": [ + "Needs: Triage :mag:" + ] + } + } + ] + }, + "id": "DhSdUvTfU" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "operator": "not", + "operands": [ + { + "name": "isActivitySender", + "parameters": { + "user": "msft-github-bot" + } + } + ] + }, + { + "operator": "not", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + }, + { + "name": "hasLabel", + "parameters": { + "label": "no-recent-activity" + } + } + ] + }, + "taskName": "Remove no recent activity label", + "actions": [ + { + "name": "removeLabel", + "parameters": { + "label": "no-recent-activity" + } + } + ] + }, + "id": "EuTNKsOAX" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isEvent", + "parameters": { + "eventName": "issue_comment" + } + }, + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isActivitySender", + "parameters": { + "user": { + "type": "author" + } + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "Needs: Author Feedback" + } + } + ] + }, + "taskName": "Add needs attention label to issues", + "actions": [ + { + "name": "addLabels", + "parameters": { + "labels": [ + "Needs: Attention :wave:" + ] + } + } + ] + }, + "id": "4g_ssp7c7" + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssueResponder", + "version": "1.0", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "isActivitySender", + "parameters": { + "user": { + "type": "author" + } + } + }, + { + "operator": "not", + "operands": [ + { + "name": "isAction", + "parameters": { + "action": "closed" + } + } + ] + }, + { + "name": "hasLabel", + "parameters": { + "label": "Needs: Author Feedback" + } + } + ] + }, + "taskName": "Remove needs author feedback label from issues and pull requests", + "actions": [ + { + "name": "removeLabel", + "parameters": { + "label": "Needs: Author Feedback" + } + } + ] + }, + "id": "LSpcATOkS" + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "id": "R2LaDi6Kz", + "config": { + "taskName": "Closed answered issues in 3 days", + "frequency": [ + { + "weekDay": 0, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + }, + { + "weekDay": 1, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + }, + { + "weekDay": 2, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + }, + { + "weekDay": 3, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + }, + { + "weekDay": 4, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + }, + { + "weekDay": 5, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + }, + { + "weekDay": 6, + "hours": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ] + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "status:answered" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 3 + } + } + ], + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Closing this issue as \"answered\". If you encounter a similar issue(s), please open up a new issue. See our wiki for more details: [Issue-List: Our approach to closed issues](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#our-approach-to-closed-issues)" + } + }, + { + "name": "closeIssue", + "parameters": {} + }, + { + "name": "lockIssue", + "parameters": { + "reason": "resolved" + } + } + ] + } + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "id": "ejaaeLe6G", + "config": { + "frequency": [ + { + "weekDay": 0, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + }, + { + "weekDay": 1, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + }, + { + "weekDay": 2, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + }, + { + "weekDay": 3, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + }, + { + "weekDay": 4, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + }, + { + "weekDay": 5, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + }, + { + "weekDay": 6, + "hours": [ + 1, + 5, + 9, + 13, + 17, + 21 + ], + "timezoneOffset": -5 + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "Needs: Author Feedback" + } + }, + { + "name": "hasLabel", + "parameters": { + "label": "no-recent-activity" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 7 + } + } + ], + "taskName": "Close stale issues", + "actions": [ + { + "name": "closeIssue", + "parameters": {} + }, + { + "name": "addReply", + "parameters": { + "comment": "Closing issue due to no response from the original author. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: [No response from the original issue author](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#no-response-from-the-original-issue-author)" + } + }, + { + "name": "lockIssue", + "parameters": {} + } + ] + }, + "disabled": false + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "JN4EianUp", + "config": { + "conditions": { + "operator": "or", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "type:invalid-not-dev-issue" + } + }, + { + "name": "labelAdded", + "parameters": { + "label": "type:invalid" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "Reply & close issues tagged \"type:invalid-not-dev-issue\"", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Thank you for your submission. As explained in our wiki ([Issue List: What doesn't belong in the issue list](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#what-doesnt-belong-in-the-issue-list)), this issue list is for SharePoint developer/development issues. All capability question/discussion questions, or topics related to SharePoint administration & end-user topics should be reported through the support user interface available in the tenant admin settings. You can also have a discussion and ask questions at the [SharePoint TechCommunity](https://techcommunity.microsoft.com/t5/SharePoint/ct-p/SharePoint) forum. You can learn more about this in our wiki: [type:invalid-not-dev-issue](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List-Labels#typeinvalid-not-dev-issue)" + } + }, + { + "name": "closeIssue", + "parameters": {} + }, + { + "name": "lockIssue", + "parameters": { + "reason": "off-topic" + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "dTcNyMD5a", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "type:uservoice-request" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Thank you for your submission. As explained in our wiki ([Issue List: What doesn't belong in the issue list](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#what-doesnt-belong-in-the-issue-list)), all new feature requests and change requests to existing features should be posted to the [SP Dev UserVoice](https://aka.ms/sp-dev-uservoice) site. You can learn more about this in our wiki: [type:uservoice-request](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List-Labels#typeuservoice-request)" + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ], + "taskName": "Reply & close issues tagged \"type:uservoice-request\"" + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "TXAA0OOon", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "Needs: Context Detail :question:" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "Reply issues tagged \"Needs: Context Detail\"", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "The more context details you can provide, the easier it is to help assist on issues. Any code you can provide and/or screenshots of the issue also help. The easier you can make it to reproduce the issue, the easier and quicker it is for someone to help you. Please refer to [How to Create Good Issues](https://github.com/SharePoint/sp-dev-docs/wiki/How-to-Create-Good-Issues), specifically [How to Create Good Issues: Include context](https://github.com/SharePoint/sp-dev-docs/wiki/How-to-Create-Good-Issues#include-context), in our wiki for more details." + } + }, + { + "name": "addLabel", + "parameters": { + "label": "Needs: Author Feedback" + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "vAHQpj0AT", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "status:duplicate" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "Close issues tagged \"status:duplicate\"", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Closing this issue as a dupe. Please refer to our wiki for more details: [Issue List Labels: status:duplicate](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List-Labels#statusduplicate)" + } + }, + { + "name": "closeIssue", + "parameters": {} + }, + { + "name": "lockIssue", + "parameters": { + "reason": "resolved" + } + } + ] + } + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "id": "Lzyb5Csy_", + "config": { + "frequency": [ + { + "weekDay": 0, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 1, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 2, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 3, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 4, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 5, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 6, + "hours": [ + 0, + 6, + 12, + 18 + ] + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isClosed", + "parameters": {} + }, + { + "name": "noActivitySince", + "parameters": { + "days": 7 + } + }, + { + "name": "isUnlocked", + "parameters": {} + } + ], + "taskName": "Lock issues if inactive 7d after closing", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: [Issue List: Our approach to locked issues](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#our-approach-to-locked-issues)" + } + }, + { + "name": "lockIssue", + "parameters": { + "reason": "resolved" + } + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "k84udcNf_", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "bodyContains", + "parameters": { + "bodyPattern": "Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking." + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "actions": [ + { + "name": "addLabel", + "parameters": { + "label": "area:docs-comment" + } + } + ], + "taskName": "Label new issues created as comment on docs with \"area:docs-comment\"" + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "NbeJ2zWgh", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "type:incomplete-submission" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "taskName": "Reply & tag issues tagged with type:incomplete-submission", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Thank you for your submission, but there isn't enough detail in the issue for us to review & move forward. The new issue template includes sections for you to fill out. Please resubmit your issue and complete the provided sections in the new item template so we can move forward on it refer to our wiki for more information: [How to Create Good Issues](https://github.com/SharePoint/sp-dev-docs/wiki/How-to-Create-Good-Issues)" + } + }, + { + "name": "removeLabel", + "parameters": { + "label": "Needs: Triage :mag:" + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ] + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "PullRequestResponder", + "version": "1.0", + "id": "SgmbtMnlk", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "type:incomplete-submission" + } + } + ] + }, + "eventType": "pull_request", + "eventNames": [ + "pull_request", + "issues", + "project_card" + ], + "taskName": "Reply & tag PRs tagged with type:incomplete-submission", + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "Thank you for your submission, but there isn't enough detail in the pull request for us to review & move forward. The new PR template includes sections for you to fill out. Please resubmit your PR and complete the provided sections in the new item template so we can move forward on it refer to our wiki for more information: [How to Create Good Pull Requests]https://github.com/SharePoint/sp-dev-docs/wiki/How-to-Create-Good-Pull-Requests)" + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ] + } + }, + { + "taskType": "scheduled", + "capabilityId": "ScheduledSearch", + "subCapability": "ScheduledSearch", + "version": "1.1", + "id": "ECBdzA7w3Y7R-jcBx0icn", + "config": { + "frequency": [ + { + "weekDay": 0, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 1, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 2, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 3, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 4, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 5, + "hours": [ + 0, + 6, + 12, + 18 + ] + }, + { + "weekDay": 6, + "hours": [ + 0, + 6, + 12, + 18 + ] + } + ], + "searchTerms": [ + { + "name": "isIssue", + "parameters": {} + }, + { + "name": "isOpen", + "parameters": {} + }, + { + "name": "hasLabel", + "parameters": { + "label": "Needs: Author Feedback" + } + }, + { + "name": "noActivitySince", + "parameters": { + "days": 7 + } + } + ], + "actions": [ + { + "name": "addLabel", + "parameters": { + "label": "no-recent-activity" + } + }, + { + "name": "addReply", + "parameters": { + "comment": "This issue has been automatically marked as stale because it has marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within the next 7 days of this comment**. Please see our wiki for more information: [Issue List Labels: Needs Author Feedback](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List-Labels#needs-author-feedback) & [Issue List: No response from the original issue author](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#no-response-from-the-original-issue-author)" + } + } + ], + "taskName": "Mark issue with no-recent-activity label if there's no actions in 7 days" + } + }, + { + "taskType": "trigger", + "capabilityId": "IssueResponder", + "subCapability": "IssuesOnlyResponder", + "version": "1.0", + "id": "MdPj2K40N73yDGFnu9REz", + "config": { + "conditions": { + "operator": "and", + "operands": [ + { + "name": "labelAdded", + "parameters": { + "label": "listmaintenance-oldissues" + } + } + ] + }, + "eventType": "issue", + "eventNames": [ + "issues", + "project_card" + ], + "actions": [ + { + "name": "addReply", + "parameters": { + "comment": "This issue is being closed as part of an issue list cleanup project. Issues with no activity in the past 6 months that aren't tracked by engineering as bugs were closed as part of this inititive. If this is still an issue, please [follow the steps outlined to re-open or submit a new issue](https://github.com/sharepoint/sp-dev-docs/wiki/Issue-List#our-approach-to-closed-issues)." + } + }, + { + "name": "closeIssue", + "parameters": {} + } + ], + "taskName": "Close inactive issues based on list maintenance label" + } + } + ], + "userGroups": [] +} diff --git a/.github/label-actions.yml b/.github/label-actions.yml new file mode 100644 index 000000000..80a5bf7aa --- /dev/null +++ b/.github/label-actions.yml @@ -0,0 +1,14 @@ +# Configuration for Label Actions - https://github.com/dessant/label-actions + +# Actions taken when the `type:archive-old-issue` label is added to issues that are being archived. +type:archive-old-issue: + # Post a comment + comment: |+ + Thank you for taking the time to file an issue. We periodically **archive** older or inactive issues as part of our issue management process, which automatically closes them once they are archived. + + If you’d like to understand more about why and how we handle archived (closed) issues, please see [Our approach to closed issues](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#our-approach-to-closed-issues). + + We appreciate your contribution and if this is still an active issue with the latest SPFx versions, please do resubmit the details. We needed to perform a cleanup, so that we can start with a **clean table** with a new process. We apologize for the inconvenience this might cause. + + # Close the issue + close: true diff --git a/.github/policies/resourceManagement.yml b/.github/policies/resourceManagement.yml new file mode 100644 index 000000000..43263aa44 --- /dev/null +++ b/.github/policies/resourceManagement.yml @@ -0,0 +1,115 @@ +id: bot-issue-management +name: Issue Management +description: Enable tracking & monitoring of issues +resource: repository +disabled: false +configuration: + resourceManagementConfiguration: + scheduledSearches: + - description: Close answered issues after 3 days of inactivity + frequencies: + - hourly: { hour: 0 } + filters: + - isIssue + - isOpen + - hasLabel: { label: status:answered } + - noActivitySince: { days: 3 } + actions: + - addReply: + reply: > + Closing this issue as "answered". If you encounter a similar issue(s), please open up a new issue. See our wiki for more details: [Issue-List: Our approach to closed issues](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#our-approach-to-closed-issues) + - closeIssue + - lockIssue: + reason: resolved + + - description: Close stale issues with no recent author activity after 7 days + frequencies: + - hourly: { hour: 6 } + filters: + - isIssue + - isOpen + - hasLabel: { label: 'Needs: Author Feedback' } + - hasLabel: { label: no-recent-activity } + - noActivitySince: { days: 7 } + actions: + - addReply: + reply: > + Closing issue due to no response from the original author. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: [No response from the original issue author](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#no-response-from-the-original-issue-author) + - closeIssue + - lockIssue + + - description: Mark issues as no recent activity after 7 days + frequencies: + - hourly: { hour: 6 } + filters: + - isIssue + - isOpen + - hasLabel: { label: 'Needs: Author Feedback' } + - noActivitySince: { days: 7 } + actions: + - addLabel: { label: no-recent-activity } + - addReply: + reply: > + This issue has been automatically marked as stale because it has marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within the next 7 days of this comment**. Please see our wiki for more information: [Issue List Labels: Needs Author Feedback](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List-Labels#needs-author-feedback) & [Issue List: No response from the original issue author](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#no-response-from-the-original-issue-author) + + - description: Lock issues inactive 7 days after closing + frequencies: + - hourly: { hour: 6 } + filters: + - isIssue + - isClosed + - noActivitySince: { days: 7 } + - isUnlocked + actions: + - addReply: + reply: > + Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: [Issue List: Our approach to locked issues](https://github.com/SharePoint/sp-dev-docs/wiki/Issue-List#our-approach-to-locked-issues) + - lockIssue: + reason: resolved + + eventResponderTasks: + - if: + - payloadType: Issues + - isAction: { action: opened } + - not: + isAssignedToSomeone: true + then: + - addReply: + reply: > + Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible. + - addLabel: + label: 'Needs: Triage :mag:' + + - if: + - payloadType: Issue_Comment + - isActivitySender: { issueAuthor: true } + - hasLabel: { label: 'Needs: Author Feedback' } + - isOpen + then: + - addLabel: + label: 'Needs: Attention :wave:' + + - if: + - payloadType: Issues + - isActivitySender: { issueAuthor: true } + - not: + isAction: { action: closed } + - hasLabel: { label: 'Needs: Author Feedback' } + then: + - removeLabel: { label: 'Needs: Author Feedback' } + + - if: + - payloadType: Issues + - not: + isActivitySender: { user: microsoft-github-policy-service } + - not: + isAction: { action: closed } + - hasLabel: { label: no-recent-activity } + then: + - removeLabel: { label: no-recent-activity } + + - if: + - payloadType: Issue_Comment + - hasLabel: { label: no-recent-activity } + then: + - removeLabel: { label: no-recent-activity } diff --git a/.github/workflows/label-actions.yml b/.github/workflows/label-actions.yml new file mode 100644 index 000000000..d2dd0ff59 --- /dev/null +++ b/.github/workflows/label-actions.yml @@ -0,0 +1,18 @@ +name: 'Check for Incomplete Issues' + +on: + issues: + types: [labeled, unlabeled] + +permissions: + issues: write + pull-requests: write + +jobs: + reaction: + runs-on: ubuntu-latest + steps: + - uses: dessant/label-actions@v2 + with: + github-token: ${{ github.token }} + process-only: 'issues' diff --git a/.openpublishing.build.ps1 b/.openpublishing.build.ps1 deleted file mode 100644 index aadef7620..000000000 --- a/.openpublishing.build.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -param( - [string]$buildCorePowershellUrl = "https://opbuildstorageprod.blob.core.windows.net/opps1container/.openpublishing.buildcore.ps1", - [string]$parameters -) -# Main -$errorActionPreference = 'Stop' - -# Step-1: Download buildcore script to local -echo "download build core script to local with source url: $buildCorePowershellUrl" -$repositoryRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition -$buildCorePowershellDestination = "$repositoryRoot\.openpublishing.buildcore.ps1" -Invoke-WebRequest $buildCorePowershellUrl -OutFile "$buildCorePowershellDestination" - -# Step-2: Run build core -echo "run build core script with parameters: $parameters" -& "$buildCorePowershellDestination" "$parameters" -exit $LASTEXITCODE diff --git a/.openpublishing.publish.config.json b/.openpublishing.publish.config.json index 5f71295cf..f3522487f 100644 --- a/.openpublishing.publish.config.json +++ b/.openpublishing.publish.config.json @@ -24,12 +24,12 @@ ], "notification_subscribers": [ "vesaj@microsoft.com", - "bjansen@microsoft.com", - "v-licapu@microsoft.com" + "bjansen@microsoft.com" ], + "sync_notification_subscribers": null, "branches_to_filter": [], "git_repository_url_open_to_public_contributors": "https://github.com/SharePoint/sp-dev-docs", - "git_repository_branch_open_to_public_contributors": "master", + "git_repository_branch_open_to_public_contributors": "main", "skip_source_output_uploading": false, "need_preview_pull_request": true, "contribution_branch_mappings": {}, @@ -37,19 +37,13 @@ { "path_to_root": "_themes", "url": "https://github.com/Microsoft/templates.docs.msft", - "branch": "master", + "branch": "main", "branch_mapping": {} }, { "path_to_root": "_themes.pdf", "url": "https://github.com/Microsoft/templates.docs.msft.pdf", - "branch": "master", - "branch_mapping": {} - }, - { - "path_to_root": "PnP-Tools", - "url": "https://github.com/SharePoint/PnP-Tools.git", - "branch": "master", + "branch": "main", "branch_mapping": {} }, { @@ -66,11 +60,11 @@ ] }, "need_generate_pdf_url_template": true, - "Targets": { - "Pdf": { - "template_folder": "_themes.pdf" - } - }, + "Targets": { + "Pdf": { + "template_folder": "_themes.pdf" + } + }, "JoinTOCPlugin": [ { "ConceptualTOC": "/docs/toc.yml", @@ -86,4 +80,4 @@ "nuget_feed": "https://www.myget.org/F/op/api/v2" } ] -} \ No newline at end of file +} diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json new file mode 100644 index 000000000..78222f726 --- /dev/null +++ b/.openpublishing.redirection.json @@ -0,0 +1,274 @@ +{ + "redirections": [ + { + "source_path": "docs/apis/rest/complete-basic-operations-using-sharepoint-rest-endpoints.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/determine-sharepoint-rest-service-endpoint-uris.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/determine-sharepoint-rest-service-endpoint-uris", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/get-to-know-the-sharepoint-rest-service.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/make-batch-requests-with-the-rest-apis.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/make-batch-requests-with-the-rest-apis", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/navigate-the-sharepoint-data-structure-represented-in-the-rest-service.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/navigate-the-sharepoint-data-structure-represented-in-the-rest-service", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/set-custom-permissions-on-a-list-by-using-the-rest-interface.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/set-custom-permissions-on-a-list-by-using-the-rest-interface", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/synchronize-sharepoint-items-using-the-rest-service.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/synchronize-sharepoint-items-using-the-rest-service", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/upload-a-file-by-using-the-rest-api-and-jquery.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/upload-a-file-by-using-the-rest-api-and-jquery", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/use-odata-query-operations-in-sharepoint-rest-requests.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/use-odata-query-operations-in-sharepoint-rest-requests", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/working-with-folders-and-files-with-rest.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest", + "redirect_document_id": false + }, + { + "source_path": "docs/apis/rest/working-with-lists-and-list-items-with-rest.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/working-with-lists-and-list-items-with-rest", + "redirect_document_id": false + }, + { + "source_path": "docs/schema/index.md", + "redirect_url": "/sharepoint/dev/schema/upgrade-definition-schema", + "redirect_document_id": false + }, + { + "source_path": "docs/sp-add-ins/add-a-custom-content-type-to-a-sharepoint-hostedsharepoint-add-in.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/add-a-custom-content-type-to-a-sharepoint-hosted-sharepoint-add-in", + "redirect_document_id": false + }, + { + "source_path": "docs/sp-add-ins/add-custom-columns-to-a-sharepoint-hostedsharepoint-add-in.md", + "redirect_url": "/sharepoint/dev/sp-add-ins/add-custom-columns-to-a-sharepoint-hosted-sharepoint-add-in", + "redirect_document_id": false + }, + { + "source_path": "docs/spfx/web-parts/guidance/creating-team-manifest-manually-for-webpart.md", + "redirect_url": "/sharepoint/dev/spfx/deployment-spfx-teams-solutions", + "redirect_document_id": false + }, + { + "source_path": "docs/general-development/office-365-cdn.md", + "redirect_url": "/sharepoint/dev/office365/enterprise/use-office-365-cdn-with-spo", + "redirect_document_id": false + }, + { + "source_path": "docs/spfx/toolchain/scaffolding-projects-using-yeoman-sharepoint-generator.md", + "redirect_url": "/sharepoint/dev/spfx/yeoman-generator-for-spfx-intro", + "redirect_document_id": false + }, + { + "source_path": "docs/spfx/office-addins-create.md", + "redirect_url": "/sharepoint/dev/spfx/release-1.14", + "redirect_document_id": false + }, + { + "source_path": "docs/spfx/web-parts/get-started/office-addins-tutorial.md", + "redirect_url": "/sharepoint/dev/spfx/release-1.14", + "redirect_document_id": false + }, + { + "source_path": "docs/spfx/sharepoint-2019-support.md", + "redirect_url": "/sharepoint/dev/spfx/sharepoint-2019-and-subscription-edition-support", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/mslearn/m01-01-intro.md", + "redirect_url": "/training/modules/sharepoint-embedded-setup/", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/mslearn/m02-01-intro.md", + "redirect_url": "/training/modules/sharepoint-embedded-create-app/", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/adoptions-and-use.md", + "redirect_url": "/sharepoint/dev/embedded/scenarios-and-use-cases", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/billing.md", + "redirect_url": "/sharepoint/dev/embedded/concepts/admin-exp/billing/billing", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/cta.md", + "redirect_url": "/sharepoint/dev/embedded/concepts/admin-exp/consuming-tenant-admin/cta", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/dev-admin.md", + "redirect_url": "/sharepoint/dev/embedded/concepts/admin-exp/developer-admin/dev-admin", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/terms-and-def.md", + "redirect_url": "/sharepoint/dev/embedded/overview", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/getting-started/enable-sharepoint-embedded.md", + "redirect_url": "/sharepoint/dev/embedded/overview", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/terms-of-service.md", + "redirect_url": "/sharepoint/dev/embedded/overview", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/adminrole.md", + "redirect_url": "/sharepoint/dev/embedded/administration/adminrole", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/billing/billing.md", + "redirect_url": "/sharepoint/dev/embedded/administration/billing/billing", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/billing/billingmanagement.md", + "redirect_url": "/sharepoint/dev/embedded/administration/billing/billingmanagement", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/billing/meters.md", + "redirect_url": "/sharepoint/dev/embedded/administration/billing/meters", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/consuming-tenant-admin/cta.md", + "redirect_url": "/sharepoint/dev/embedded/administration/consuming-tenant-admin/cta", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/consuming-tenant-admin/ctaUX.md", + "redirect_url": "/sharepoint/dev/embedded/administration/consuming-tenant-admin/ctaUX", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/consuming-tenant-admin/ctapowershell.md ", + "redirect_url": "/sharepoint/dev/embedded/administration/consuming-tenant-admin/ctapowershell", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/admin-exp/developer-admin/dev-admin.md", + "redirect_url": "/sharepoint/dev/embedded/administration/developer-admin/dev-admin", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/security-and-compliance.md", + "redirect_url": "/sharepoint/dev/embedded/compliance/security-and-compliance", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/app-architecture.md", + "redirect_url": "/sharepoint/dev/embedded/development/app-architecture", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/auth.md", + "redirect_url": "/sharepoint/dev/embedded/development/auth", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/content-experiences/office-experience.md", + "redirect_url": "/sharepoint/dev/embedded/development/content-experiences/office-experience", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/content-experiences/search-content.md", + "redirect_url": "/sharepoint/dev/embedded/development/content-experiences/search-content", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/content-experiences/user-experiences-overview.md", + "redirect_url": "/sharepoint/dev/embedded/development/content-experiences/user-experiences-overview", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/fluid.md", + "redirect_url": "/sharepoint/dev/embedded/development/fluid", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/limits-calling.md", + "redirect_url": "/sharepoint/dev/embedded/development/limits-calling", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/sharing-and-perm.md", + "redirect_url": "/sharepoint/dev/embedded/development/sharing-and-perm", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/tutorials/doc-processing-acs.md", + "redirect_url": "/sharepoint/dev/embedded/development/tutorials/doc-processing-acs", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/tutorials/launch-experience.md", + "redirect_url": "/sharepoint/dev/embedded/development/tutorials/launch-experience", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/tutorials/metadata.md", + "redirect_url": "/sharepoint/dev/embedded/development/tutorials/metadata", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/tutorials/migrate-abs-to-spe.md", + "redirect_url": "/sharepoint/dev/embedded/development/tutorials/migrate-abs-to-spe", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/tutorials/using-file-preview.md", + "redirect_url": "/sharepoint/dev/embedded/development/tutorials/using-file-preview", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/tutorials/using-webhooks.md", + "redirect_url": "/sharepoint/dev/embedded/development/tutorials/using-webhooks", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/containertypes.md", + "redirect_url": "/sharepoint/dev/embedded/getting-started/containertypes", + "redirect_document_id": false + }, + { + "source_path": "docs/embedded/concepts/app-concepts/register-api-documentation.md", + "redirect_url": "/sharepoint/dev/embedded/getting-started/register-api-documentation", + "redirect_document_id": false + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..ed9462b7e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "markdownlint.config": { + "MD028": false, + "MD025": { + "front_matter_title": "" + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 21cd013b2..4e77f8fcb 100644 --- a/README.md +++ b/README.md @@ -1,111 +1,55 @@ -# Welcome to the SharePoint Framework! +# Welcome to the SharePoint Framework! The SharePoint Framework (SPFx) is a page and part model that enables client-side development for building SharePoint experiences. It facilitates easy integration with the SharePoint data, and provides support for open source tooling development. * [Official SharePoint Framework Documentation](https://aka.ms/spfx) -This repository contains the raw documents published to docs.microsoft.com site. +This repository contains the raw documents published to Microsoft Docs. ## Questions & Help Feel free to use [Issues]((https://github.com/SharePoint/sp-dev-docs/issues)) list to report us potential issues around the SharePoint Framework or gaps in our documentation. You can also submit directly pull requests towards our documentation. -We’ll also monitor [#spfx](http://sharepoint.stackexchange.com/tags/spfx/), [#spfx-webparts](http://sharepoint.stackexchange.com/tags/spfx-webparts/), and [#spfx-tooling](http://sharepoint.stackexchange.com/tags/spfx-tooling/) at [SharePoint StackExchange](http://sharepoint.stackexchange.com/) as well. - -You can also tweet / follow [@officedev](https://twitter.com/officedev) or [@officedevpnp](https://twitter.com/officedevpnp). +You can also tweet / follow [@Microsoft365Dev](https://twitter.com/Microsoft365Dev) or [@m365pnp](https://twitter.com/m365pnp). ## SharePoint Framework Releases -* **August 14, 2019** - * **SPFx v1.9.1** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/SharePoint-Framework-v1.9.1-release-notes) - -* **May 7, 2019** - * **SPFx v1.8.2** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/SharePoint-Framework-v1.8.2-release-notes) - -* **April 16, 2019** - * **SPFx v1.8.1** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/SharePoint-Framework-v1.8.1-release-notes) - -* **March 14, 2019** - * **SPFx v1.8** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/SharePoint-Framework-v1.8-release-notes) - -* **December 18, 2018** - * **SPFx v1.7.1** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-for-SPFx-Package-Version-1.7.1) - -* **November 8, 2018** - * **SPFx v1.7** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/SharePoint-Framework-v1.7-release-notes) -* **September 5, 2018** - * **SPFx v1.6** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/SharePoint-Framework-v1.6-release-notes) - -* **June 26, 2018** - * **SPFx v1.5.1** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-for-SPFx-Package-Version-1.5.1) - -* **June 5, 2018** - * **SPFx v1.5** - [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-for-SharePoint-Framework-Package-v1.5) - -* **February 15, 2018** - * **SPFx v1.4.1** [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-for-SPFx-Package-Version-1.4.1) +Review all the SPFx releases here from the [initial GA release in February 2017](https://learn.microsoft.com/sharepoint/dev/spfx/roadmap) -* **December 7, 2017** - * **SPFx v1.4**. [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-for-SPFx-Package-Version-1.4) - -* **September 25, 2017** - * **GA of Extensions and SPFx v1.3**. - -* **June 6, 2017** - * **Dev Preview of extensions is available**. [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes---Extensions-Dev-Preview-Drop-1) - -* **Feb 22, 2017** - * **GA is available**. [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-GA) - -* **Jan 9, 2017** - * **RC0 is available**. [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Release-Notes-RC0) - -* **Aug 17, 2016** - * **Drop 1 is available**. [See the release notes here](https://github.com/SharePoint/sp-dev-docs/wiki/Drop-1) - ## Get Started -* [Setup your Office 365 Developer Tenant](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-developer-tenant) -* [Setup your Machine](https://docs.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment) -* [Go build your first web part](https://docs.microsoft.com/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part) - -## Reference -* [sp-application-base](https://docs.microsoft.com/javascript/api/sp-application-base) -* [sp-component-base](https://docs.microsoft.com/javascript/api/sp-component-base) -* [sp-core-library](https://docs.microsoft.com/javascript/api/sp-core-library) -* [sp-dialog](https://docs.microsoft.com/javascript/api/sp-dialog) -* [sp-extension-base](https://docs.microsoft.com/javascript/api/sp-extension-base) -* [sp-http](https://docs.microsoft.com/javascript/api/sp-http) -* [sp-listview-extensibility](https://docs.microsoft.com/javascript/api/sp-listview-extensibility) -* [sp-odata-types](https://docs.microsoft.com/javascript/api/sp-odata-types) -* [sp-page-context](https://docs.microsoft.com/javascript/api/sp-page-context) -* [sp-webpart-base](https://docs.microsoft.com/javascript/api/sp-webpart-base) +* [Setup your Office 365 Developer Tenant](https://learn.microsoft.com/sharepoint/dev/spfx/set-up-your-developer-tenant) +* [Setup your Machine](https://learn.microsoft.com/sharepoint/dev/spfx/set-up-your-development-environment) +* [Go build your first web part](https://learn.microsoft.com/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part) ## Learn More -* [Background and Philosophy](https://docs.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview) -* [Design Great Web Parts](https://docs.microsoft.com/sharepoint/dev/design/design-guidance-overview) -* [API Docs](https://docs.microsoft.com/javascript/api/sp-application-base) +* [Background and Philosophy](https://learn.microsoft.com/sharepoint/dev/spfx/sharepoint-framework-overview) +* [Design Great Web Parts](https://learn.microsoft.com/sharepoint/dev/design/design-guidance-overview) +* [API Docs](https://learn.microsoft.com/javascript/api/sp-application-base) ## Updates & Feedback To keep track of improvements to the Office 365 Framework, please take a look at: -* [@SharePoint](https://twitter.com/sharepoint), [@OfficeDev](https://twitter.com/officedev) and [@OfficeDevPnP](https://twitter.com/officedevpnp) on Twitter -* [Office Developer Blog](https://developer.microsoft.com/en-us/office/blogs/) +* [@SharePoint](https://twitter.com/sharepoint), [@Microsoft365Dev](https://twitter.com/Microsoft365Dev) and [@m365pnp](https://twitter.com/m365pnp) on Twitter +* [Office Developer Blog](https://developer.microsoft.com/office/blogs/) Provide Feedback: * If you find issues or have new ideas and suggestions for SharePoint Framework, make sure you submit them [here](https://github.com/SharePoint/sp-dev-docs/issues). -* [SharePoint StackExchange](http://sharepoint.stackexchange.com/) (please use [#spfx](http://sharepoint.stackexchange.com/tags/spfx/), [#spfx-webparts](http://sharepoint.stackexchange.com/tags/spfx-webparts/), and [#spfx-tooling](http://sharepoint.stackexchange.com/tags/spfx-tooling/) tags) * [SharePoint Developer](https://techcommunity.microsoft.com/t5/SharePoint-Developer/bd-p/SharePointDev) group at Microsoft Tech Community * [SharePoint Developer UserVoice](https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform) -## Deployment Status -The SharePoint Framework is now generally available at Office 365. -- [SharePoint Framework reaches general availability—build and deploy engaging web parts today](https://blogs.office.com/2017/02/23/sharepoint-framework-reaches-general-availability-build-and-deploy-engaging-web-parts-today/) +## Contribute on the SharePoint Dev Docs + +Please see following guidance if you are planning to submit changes on the SharePoint developer documentation. We do welcome your pull requests! + +* [Contribution guidance](https://github.com/SharePoint/sp-dev-docs/blob/master/.github/CONTRIBUTING.md) +* [How to Create Good Pull Requests](https://github.com/SharePoint/sp-dev-docs/wiki/How-to-Create-Good-Pull-Requests) +* If you are a Microsoft contributor, please review official guidance from our [internal documentation](https://review.learn.microsoft.com/help/contribute/?branch=main) for Microsoft Docs contributors ## Have Fun -We look forward to seeing what you build! Please tweet us at @OfficeDev, @OfficeDevPnP or @SharePoint with the #SPFx tag! +We look forward to seeing what you build! Please tweet us at @Microsoft365Dev, @m365pnp or @SharePoint with the #SPFx tag! diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..e138ec5d6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + diff --git a/assets/MicrosoftSharePointClientComponentsEULA.docx b/assets/MicrosoftSharePointClientComponentsEULA.docx new file mode 100644 index 000000000..d7e06041f Binary files /dev/null and b/assets/MicrosoftSharePointClientComponentsEULA.docx differ diff --git a/assets/ace/URL.txt b/assets/ace/URL.txt new file mode 100644 index 000000000..7d3d66ec3 --- /dev/null +++ b/assets/ace/URL.txt @@ -0,0 +1 @@ +me/events?$select=subject,body,bodyPreview,organizer,attendees,start,end,location \ No newline at end of file diff --git a/assets/ace/calendar-top.png b/assets/ace/calendar-top.png new file mode 100644 index 000000000..d8cb719da Binary files /dev/null and b/assets/ace/calendar-top.png differ diff --git a/assets/ace/email-top.png b/assets/ace/email-top.png new file mode 100644 index 000000000..d9170e95a Binary files /dev/null and b/assets/ace/email-top.png differ diff --git a/assets/ace/events-quick-view.json b/assets/ace/events-quick-view.json new file mode 100644 index 000000000..fb16cb82b --- /dev/null +++ b/assets/ace/events-quick-view.json @@ -0,0 +1,85 @@ +{ + "type": "AdaptiveCard", + "version": "1.5", + "@odata.type": "#microsoft.graph.message", + "body": [ + { + "type": "Container", + "items": [ + { + "type": "Image", + "url": "https://raw.githubusercontent.com/SharePoint/sp-dev-docs/main/assets/ace/calendar-top.png" + }, + { + "type": "TextBlock", + "text": "This control displays the latest calendar events. You can open the event in Outlook or, if it's a meeting, you can join it simply clicking on the button next to the event.", + "wrap": true + } + ] + }, + { + "type": "Container", + "$data": "${value}", + "items": [ + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "${subject}", + "size": "Medium" + }, + { + "type": "TextBlock", + "text": "${location.displayName}", + "spacing": "None" + }, + { + "type": "TextBlock", + "text": "${formatDateTime(substring(start.dateTime,0,19), 'dd/MM/yyyy hh:mm')}-${formatDateTime(substring(end.dateTime,0,19), 'hh:mm')}", + "spacing": "None", + "size": "Small" + } + ] + }, + { + "type": "Column", + "width": "auto", + "items": [ + { + "type": "Image", + "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAvBJREFUSEvtVUtIalEUXdeKiDDIiIY1i7CIBkqRRrNCAqFM6AsRQhMLx5VSVvTBoqwIIqTIoCYV1aBZ/4EDk4gkmgg16iP9cFQaez+89N4zrz148AZvw+XCufectddeZ68tRCKRCP5iCP8MgM/nQ39/P9bX15Gfnw+bzYb6+nokJyfH5Z8Qg0AggObmZqjVarS2tsLr9WJ4eBhjY2PQ6/UMEA6H8fT0BJlMhoyMDAiCwOsJAayuroKehYUFZGZmgmSbm5vD+fk5HA4H3t/f0d3djcnJScjlcvT29sJisTC7hADcbjd2d3cxMzPDB1AsLS3h5OQEExMTODo64kNnZ2dxe3uLnp4eLC4uQqlUQgiHwxGPx4PDw0POJFbc3NzwhunpaTQ0NODy8hKdnZ1cHnqvra2JDB8fH7mcxKy0tBTC/f19pKmpiTP8TnR1dWFwcBDp6emIahQKhUCPRqPB+Pj4Dy0+A9DNqKys/A1nb28PfX190Gq1XIqioiLk5OSIQtKGh4cHbG1tMaBOp+M3i/wZYHl5GcTm1yANiLZCoUBxcTFSUlIkydbW1qK9vf1ngJKSEmRnZ6OmpgZmsxlOpxPb29u4u7vD6ekpCgoKYDQakZaWJgIEg0Fsbm6yHpQABWl2dXUFSiymBtRQVAq73Q6r1SoeVlVVxZuysrLEtajgU1NT3IAUx8fHvPc/AJfjj0pkMpnQ2NiIlZUVzM/Pf1uDg4MDDA0Nfa3BV3cwEZHf3t7YaV9fXzE6OhrfKigTioqKCiQlJXGjkaNGnZK+nZ2dwWAw8A0qKysD2TpZD92g8vLy+GZH7rmzsyO6aCxm9I/L5YJKpcLFxQUKCwu5h/Ly8qTtOuoxpElLSwt7/efw+/1oa2vjA2M5QELzYH9/HwRAndrR0YHc3Fy8vLxgY2MDIyMjqK6uFk0vFkPJeUDDhWxiYGCAx2U0qObU5XV1dUhNTf3SmyQBojsJ6Pn5GdfX1+xXZBdS8zihEknapsQPH6Mh/FGBh+hUAAAAAElFTkSuQmCC", + "selectAction": { + "type": "Action.OpenUrl", + "url": "${onlineMeeting.joinUrl}" + }, + "$when": "${isOnlineMeeting}" + } + ] + }, + { + "type": "Column", + "width": "auto", + "items": [ + { + "type": "Image", + "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAR5JREFUSEvtljGuRFAUhv8rIdGQSHQahc4ORG8PbMICVBZgE+xBL3agU2h0RIJCQsLkSt4kM2/e3Fu8ea+hPef4zvnOjYscx3Hggw95BizLgjAM4boufN/nQmdZhqIokCQJZFl+qCHzPB9pmmIcxzOwbRvyPIdpmrBtmwtQVRWapoHneRBF8axRVRVBEID0fX/QTilAURTs+466rqFpGnRd5wJ0XYdhGGBZFgRBwDRNJ4BOdgdEUQTHcfAbisqyRBzHrwF057QDSZK++fxpHNrUuq6nAUIIXgLoeIZhcClhJbVte2p+UPS1A1YxT/ztDnhewMp5uwNWMU/8AjAtXYouRUwDzIT/OUUf+9g9X5nM+TkT7lfmn/9VcDbInXYDn/BFftWPiLMAAAAASUVORK5CYII=", + "selectAction": { + "type": "Action.OpenUrl", + "url": "${webLink}" + } + } + ] + } + ] + } + ], + "separator": true + } + ], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json" +} \ No newline at end of file diff --git a/assets/ace/messages-quick-view.json b/assets/ace/messages-quick-view.json new file mode 100644 index 000000000..74e7f40a1 --- /dev/null +++ b/assets/ace/messages-quick-view.json @@ -0,0 +1,84 @@ +{ + "type": "AdaptiveCard", + "version": "1.5", + "@odata.type": "#microsoft.graph.message", + "body": [ + { + "type": "Container", + "items": [ + { + "type": "Image", + "url": "https://raw.githubusercontent.com/SharePoint/sp-dev-docs/main/assets/ace/email-top.png" + }, + { + "type": "TextBlock", + "text": "This control displays the last email message received in your inbox. To view the message, simply click on the button. The message will open directly in Outlook, allowing you to read and respond to it as needed.", + "wrap": true + } + ] + }, + { + "type": "Container", + "$data": "${value}", + "items": [ + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "${from.emailAddress.name}", + "size": "Medium", + "weight": "${if(isRead, 'normal', 'bolder')}" + }, + { + "type": "TextBlock", + "text": "${subject}", + "spacing": "None", + "weight": "${if(isRead, 'normal', 'bolder')}" + } + ] + }, + { + "type": "Column", + "width": "auto", + "items": [ + { + "type": "TextBlock", + "text": "${if(hasAttachments, '📎', '')} ${if(importance == 'normal', '', '❗')} ${if(flag.flagStatus == 'flagged', '🚩', '')}", + "horizontalAlignment": "Right" + }, + { + "type": "TextBlock", + "text": "{{DATE(${sentDateTime}, COMPACT)}} {{TIME(${sentDateTime})}}", + "spacing": "None", + "size": "Small" + } + ], + "verticalContentAlignment": "Center" + }, + { + "type": "Column", + "width": "auto", + "items": [ + { + "type": "Image", + "url": "${if(isRead, 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAY5JREFUSEvt1aGLwlAcB/DvQ2FNg6BFMPg3WDRZRayGLWkxKViUgUkYWgRNKy5psG52kxb/BoOwMtEwTaLwjudxntObb3onHMe9uvH97Pd9vDdCKaV44SK/Btjv9zAMAz6fD5lMBoIgeJqbOwELHo/HaLfbME3zFBqNRlGr1ZDNZrmQK3AZvFqtUKlUUCwWT0C/30e320U4HOZCN4BbcCAQcFSy3W49QWfAa/B18TyIHA4Hqus6Wq0WLqu4/mLejl5D9XoduVwOZL1eU1EUEYlE0Ol0EAqFeFl3n282G1SrVViWheFw+AnMZjMoioJSqQS/3/8UcjweoaoqZFlGMpl0AolEAqPRCOVy+SnkI7zX6yGfz2M+nzuBRqMBttFsgkeRy3A2ATuEzWbzFmBjTSYTFAoFLJfLh2qKxWLQNA3pdBqs7i+BVCoFdvctFovzqfWqsNMdj8dBCMF0OnUHvAbee+8f4Lb4RyuybRuPXnBuXbGLLxgMvh+03W5HB4MBGPCTiwGSJIH7y/wu+nLgDSewZ7NrDNFAAAAAAElFTkSuQmCC', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAARBJREFUSEvtlS2qhUAYhl+LRbALYhMsrsAF2MXmLhRsJpugu7CJ3QW4AotgE8EiBsFimYNevJxz8Th6YZpThpnv55nvnT+OEELAsHEPgKYue4nGcSS+76NtW9pibtkVRUEUReCGYSCO46Cua6y9KIq3Ev11nqYJaZpC07St/wUURQFd1+F5HmzbhiAIt0DzPCPLMsRxjKqqYJrmJ8B1XfR9vzms7SroPfEeJ0kSkiT5BARBAMMwcBRwVNGZX1mWCMPwGLDr8i3Bat+l+FbpJcARaFmWbZrn+VMJbwHeQXmeb0PLsk4Pwb8Ad47UA6CqdSiRqqqQZZkafMWh6zo0TfNzD5g/ds+PRtsT9j8a6z14AbwnH7bn+xIdAAAAAElFTkSuQmCC')}", + "selectAction": { + "type": "Action.OpenUrl", + "url": "${webLink}" + } + } + ] + } + ] + } + ], + "separator": true + } + ], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json" +} \ No newline at end of file diff --git a/assets/bot-powered/Media/Collect-Feedback.png b/assets/bot-powered/Media/Collect-Feedback.png new file mode 100644 index 000000000..16aecc8a0 Binary files /dev/null and b/assets/bot-powered/Media/Collect-Feedback.png differ diff --git a/assets/bot-powered/Media/Ok-Feedback.png b/assets/bot-powered/Media/Ok-Feedback.png new file mode 100644 index 000000000..ea5aa3a3b Binary files /dev/null and b/assets/bot-powered/Media/Ok-Feedback.png differ diff --git a/assets/bot-powered/TeamsAppManifest/icon-color.png b/assets/bot-powered/TeamsAppManifest/icon-color.png new file mode 100644 index 000000000..b8cf81afb Binary files /dev/null and b/assets/bot-powered/TeamsAppManifest/icon-color.png differ diff --git a/assets/bot-powered/TeamsAppManifest/icon-outline.png b/assets/bot-powered/TeamsAppManifest/icon-outline.png new file mode 100644 index 000000000..2c3bf6fa6 Binary files /dev/null and b/assets/bot-powered/TeamsAppManifest/icon-outline.png differ diff --git a/assets/bot-powered/TeamsAppManifest/manifest.json b/assets/bot-powered/TeamsAppManifest/manifest.json new file mode 100644 index 000000000..7a502770d --- /dev/null +++ b/assets/bot-powered/TeamsAppManifest/manifest.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.14/MicrosoftTeams.schema.json", + "manifestVersion": "1.16", + "version": "1.0.0", + "id": "", + "packageName": "collectfeedback.botpoweredace", + "developer": { + "name": "", + "websiteUrl": "", + "privacyUrl": "", + "termsOfUseUrl": "", + "mpnId": "" + }, + "name": { + "short": "Collect Feedaback Bot Powered ACE", + "full": "This is a basic sample of a Bot Powered ACE for Microsoft Viva Connections Dashboard to collect user's feedback" + }, + "description": { + "short": "Basic sample of a Bot Powered ACE for Microsoft Viva Connections Dashboard to collect user's feedback", + "full": "Basic sample of how to use the latest release of the Bot Framework SDK to build a Bot Powered ACE for Microsoft Viva Connections Dashboard to collect user's feedback" + }, + "icons": { + "outline": "icon-outline.png", + "color": "icon-color.png" + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "", + "needsChannelSelector": false, + "isNotificationOnly": false, + "supportsCalling": false, + "supportsVideo": false, + "supportsFiles": false, + "scopes": [ + "team", + "personal", + "groupchat" + ] + } + ], + "dashboardCards": [ + { + "id": "", + "displayName": "Collect Feedaback", + "description": "Bot Powered ACE to collect user's feedback", + "icon": { + "officeUIFabricIconName": "Feedback" + }, + "contentSource": { + "sourceType": "bot", + "botConfiguration": { + "botId": "" + } + }, + "defaultSize": "medium" + } + ], + "permissions": [ + "identity" + ], + "validDomains": [ + ".ngrok.io" + ] +} \ No newline at end of file diff --git a/assets/spfx/spfx-matrix.json b/assets/spfx/spfx-matrix.json new file mode 100644 index 000000000..66ddda059 --- /dev/null +++ b/assets/spfx/spfx-matrix.json @@ -0,0 +1,545 @@ +[ + { + "spfx": "1.21.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.21.1", + "node": [ + "v22" + ], + "typescript": [ + "v5.3" + ], + "react": [ + "v17.0.1" + ] + }, + { + "spfx": "1.21.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.21", + "node": [ + "v22" + ], + "typescript": [ + "v5.3" + ], + "react": [ + "v17.0.1" + ] + }, + { + "spfx": "1.20.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.20", + "node": [ + "v18" + ], + "typescript": [ + "v4.5", + "v4.7" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2024-09-26" + }, + { + "spfx": "1.19.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.19", + "node": [ + "v18" + ], + "typescript": [ + "v4.5", + "v4.7" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2024-05-01" + }, + { + "spfx": "1.18.2", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.18.2", + "node": [ + "v16", + "v18" + ], + "typescript": [ + "v4.5", + "v4.7" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-11-21" + }, + { + "spfx": "1.18.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.18.1", + "node": [ + "v16", + "v18" + ], + "typescript": [ + "v4.5", + "v4.7" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-11-07" + }, + { + "spfx": "1.18", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.18", + "node": [ + "v16", + "v18" + ], + "typescript": [ + "v4.5", + "v4.7" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-09-12" + }, + { + "spfx": "1.17.4", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.17.4", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ] + }, + { + "spfx": "1.17.3", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.17.3", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-06-21" + }, + { + "spfx": "1.17.2", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.17.2", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-05-08" + }, + { + "spfx": "1.17.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.17.1", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-04-12" + }, + { + "spfx": "1.17.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.17", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2023-04-04" + }, + { + "spfx": "1.16.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.16.1", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2022-11-30" + }, + { + "spfx": "1.16.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.16", + "node": [ + "v16.13+" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v17.0.1" + ], + "releaseDate": "2022-11-15" + }, + { + "spfx": "1.15.2", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.15.2", + "node": [ + "v12", + "v14", + "v16" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v16.13.1" + ], + "releaseDate": "2022-08-02" + }, + { + "spfx": "1.15.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.15", + "node": [ + "v12", + "v14", + "v16" + ], + "typescript": [ + "v4.5" + ], + "react": [ + "v16.13.1" + ], + "releaseDate": "2022-06-21" + }, + { + "spfx": "1.14.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.14", + "node": [ + "v12", + "v14" + ], + "typescript": [ + "v3.9" + ], + "react": [ + "v16.13.1" + ], + "releaseDate": "2022-02-17" + }, + { + "spfx": "1.13.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.13.1", + "node": [ + "v12", + "v14" + ], + "typescript": [ + "v3.9" + ], + "react": [ + "v16.13.1" + ], + "releaseDate": "2021-11-23" + }, + { + "spfx": "1.13.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.13", + "node": [ + "v12", + "v14" + ], + "typescript": [ + "v3.9" + ], + "react": [ + "v16.13.1" + ], + "releaseDate": "2021-10-21" + }, + { + "spfx": "1.12.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.12.1", + "node": [ + "v10", + "v12", + "v14" + ], + "typescript": [ + "v3.7" + ], + "react": [ + "v16.9.0" + ], + "releaseDate": "2021-04-28" + }, + { + "spfx": "1.12.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.12.0", + "node": [ + "v12", + "v10" + ], + "typescript": [ + "v3.7" + ], + "react": [ + "v16.9.0" + ], + "deprecated": true, + "releaseDate": "2021-03-15" + }, + { + "spfx": "1.11.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.11.0", + "node": [ + "v10" + ], + "typescript": [ + "v3.3" + ], + "react": [ + "v16.8.5" + ] + }, + { + "spfx": "1.10.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.10.0", + "node": [ + "v8", + "v10" + ], + "typescript": [ + "v3.3" + ], + "react": [ + "v16.8.5" + ], + "releaseDate": "2020-07-16" + }, + { + "spfx": "1.9.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.9.1", + "node": [ + "v8", + "v10" + ], + "typescript": [ + "v2.9" + ], + "react": [ + "v16.8.5" + ], + "releaseDate": "2019-08-14" + }, + { + "spfx": "1.8.2", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.8.2", + "node": [ + "v8", + "v10" + ], + "typescript": [ + "v2.9" + ], + "react": [ + "v16.7.0" + ], + "releaseDate": "2019-05-07" + }, + { + "spfx": "1.8.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.8.1", + "node": [ + "v8" + ], + "typescript": [ + "v2.7", + "v2.9", + "v3" + ], + "react": [ + "v16.7.0" + ], + "releaseDate": "2019-04-16" + }, + { + "spfx": "1.8.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.8.0", + "node": [ + "v8" + ], + "typescript": [ + "v2.7", + "v2.9", + "v3" + ], + "react": [ + "v16.7.0" + ], + "releaseDate": "2019-03-14" + }, + { + "spfx": "1.7.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.7.1", + "node": [ + "v8" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v16.3.2" + ], + "releaseDate": "2018-12-18" + }, + { + "spfx": "1.7.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.7", + "node": [ + "v8" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v16.3.2" + ], + "releaseDate": "2018-11-08" + }, + { + "spfx": "1.6.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.6", + "node": [ + "v6", + "v8" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ] + }, + { + "spfx": "1.5.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.5.1", + "node": [ + "v6", + "v8" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2018-06-26" + }, + { + "spfx": "1.5.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.5", + "node": [ + "v6", + "v8" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2018-06-05" + }, + { + "spfx": "1.4.1", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.4.1", + "node": [ + "v6", + "v8" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2018-02-18" + }, + { + "spfx": "1.4.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.4", + "node": [ + "v6" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2017-12-07" + }, + { + "spfx": "1.3.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.3", + "node": [ + "v6" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2017-08-25" + }, + { + "spfx": "1.1.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.1", + "node": [ + "v6" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2017-06-06" + }, + { + "spfx": "1.0.0", + "url": "https://learn.microsoft.com/sharepoint/dev/spfx/release-1.0.0", + "node": [ + "v6" + ], + "typescript": [ + "v2.4" + ], + "react": [ + "v15" + ], + "releaseDate": "2017-02-22" + } +] \ No newline at end of file diff --git a/assets/vc-backgrounds/01_Teal.png b/assets/vc-backgrounds/01_Teal.png new file mode 100644 index 000000000..98158b37b Binary files /dev/null and b/assets/vc-backgrounds/01_Teal.png differ diff --git a/assets/vc-backgrounds/02_Blue.png b/assets/vc-backgrounds/02_Blue.png new file mode 100644 index 000000000..a9c23fb91 Binary files /dev/null and b/assets/vc-backgrounds/02_Blue.png differ diff --git a/assets/vc-backgrounds/03_Orange.png b/assets/vc-backgrounds/03_Orange.png new file mode 100644 index 000000000..8e811de8f Binary files /dev/null and b/assets/vc-backgrounds/03_Orange.png differ diff --git a/assets/vc-backgrounds/04_Red.png b/assets/vc-backgrounds/04_Red.png new file mode 100644 index 000000000..b42888406 Binary files /dev/null and b/assets/vc-backgrounds/04_Red.png differ diff --git a/assets/vc-backgrounds/05_Purple.png b/assets/vc-backgrounds/05_Purple.png new file mode 100644 index 000000000..888e21a84 Binary files /dev/null and b/assets/vc-backgrounds/05_Purple.png differ diff --git a/assets/vc-backgrounds/06_Green.png b/assets/vc-backgrounds/06_Green.png new file mode 100644 index 000000000..494d7dd31 Binary files /dev/null and b/assets/vc-backgrounds/06_Green.png differ diff --git a/assets/vc-backgrounds/07_Gray.png b/assets/vc-backgrounds/07_Gray.png new file mode 100644 index 000000000..3ec725883 Binary files /dev/null and b/assets/vc-backgrounds/07_Gray.png differ diff --git a/assets/vc-backgrounds/08_Periwinkle.png b/assets/vc-backgrounds/08_Periwinkle.png new file mode 100644 index 000000000..23b6fa00a Binary files /dev/null and b/assets/vc-backgrounds/08_Periwinkle.png differ diff --git a/assets/vc-backgrounds/09_Black.png b/assets/vc-backgrounds/09_Black.png new file mode 100644 index 000000000..4a1837aa9 Binary files /dev/null and b/assets/vc-backgrounds/09_Black.png differ diff --git a/assets/vc-backgrounds/10_Cerulean.png b/assets/vc-backgrounds/10_Cerulean.png new file mode 100644 index 000000000..86c8be663 Binary files /dev/null and b/assets/vc-backgrounds/10_Cerulean.png differ diff --git a/assets/vc-backgrounds/11_Cobalt.png b/assets/vc-backgrounds/11_Cobalt.png new file mode 100644 index 000000000..a2f354798 Binary files /dev/null and b/assets/vc-backgrounds/11_Cobalt.png differ diff --git a/assets/vc-backgrounds/12_Dark Yellow.png b/assets/vc-backgrounds/12_Dark Yellow.png new file mode 100644 index 000000000..224126c84 Binary files /dev/null and b/assets/vc-backgrounds/12_Dark Yellow.png differ diff --git a/assets/vc-backgrounds/13_Dark Blue.png b/assets/vc-backgrounds/13_Dark Blue.png new file mode 100644 index 000000000..f38b33e1f Binary files /dev/null and b/assets/vc-backgrounds/13_Dark Blue.png differ diff --git a/assets/vc-backgrounds/14_Custom_Color.png b/assets/vc-backgrounds/14_Custom_Color.png new file mode 100644 index 000000000..624e7605d Binary files /dev/null and b/assets/vc-backgrounds/14_Custom_Color.png differ diff --git a/assets/vc-backgrounds/15_Hero_Connections_Dark.png b/assets/vc-backgrounds/15_Hero_Connections_Dark.png new file mode 100644 index 000000000..90cf818b5 Binary files /dev/null and b/assets/vc-backgrounds/15_Hero_Connections_Dark.png differ diff --git a/docs/apis/addin-management-apis.md b/docs/apis/addin-management-apis.md new file mode 100644 index 000000000..f5cab6571 --- /dev/null +++ b/docs/apis/addin-management-apis.md @@ -0,0 +1,346 @@ +--- +title: SharePoint Add-in related APIs +description: We provided some Add-in related APIs to get Add-in's installation info and uninstall the Add-in. +audience: admin +ms.date: 03/25/2023 +ms.localizationpriority: medium +--- + +# SharePoint Add-in Management APIs + +This documentation will introduce some APIs which related to SharePoint Add-ins. They could help to have a clear view +and better management of the Add-ins in tenant level, including these: + +- Get available Add-ins in sites +- Get Add-in permissions in site collections +- Get tenant ACS service principals +- Get Add-in principals in site collections +- Uninstall Add-ins +- Get uninstall Add-in job status + +For more information about SharePoint Add-in, see [SharePoint Add-ins](../sp-add-ins/sharepoint-add-ins.md). + +## Prerequisites + +- App-only mode token. [Get token example](https://github.com/pnp/pnpcore/blob/dev/docs/polyglot/Getting%20started%20-%20application%20permissions.ipynb) +- Called on the admin site. Example: https://www.contoso-admin.sharepoint.com +- For uninstall Add-in API, the app needs to have Sites.FullControl.All permission. For others, the app needs at least Sites.Read.All permission. + +## Get available Add-ins in sites + +This API will return the Add-ins that could be used on the given sites. This contains two kinds of install, one is the Add-in installed on the site. +The other is the Add-in installed on the tenant level app catalog site, and it matches the conditions to use the Add-in. +For more information, see [Tenancies and deployment scopes for SharePoint Add-ins](../sp-add-ins/tenancies-and-deployment-scopes-for-sharepoint-add-ins.md). + +This API needs the app to have at least Sites.Read.All permission. + +### HTTP request + +```HTTP +POST {adminSiteUrl}/_api/web/AvailableAddIns +``` + +### Request body + +| Name | Required | Type | Description | +|--------------------|----------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| serverRelativeUrls | no | string[] | List of the server relative url of sites that want to get the available Add-ins. Maximum size is 500. | +| urls | no | string[] | List of the url of sites that want to get the available Add-ins, both server relative url and absolute url are acceptable. Maximum size is 500. | + +When urls is not null, serverRelativeUrls will be disregarded. + +### Responses + +| Name | Type | Description | +|-----------------------------|--------------------------------|--------------------------------------------------------------------------------------| +| addins | SPAddinInstanceInfo[] | Available Add-in instance object. | +| errorsWithServerRelativeUrl | SPErrorWithServerRelativeUrl[] | Server relative urls that failed to get available add-ins and corresponding reasons. | + +#### SPAddinInstanceInfo + +| Name | Type | Description | +|-------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| title | string | Title of the Add-in. | +| appInstanceId | Guid | Id of the installation. | +| launchUrl | String | The Add-in's launch page address. | +| installedSiteId | Guid | Site collection id where the Add-in installed. | +| installedWebId | Guid | Site id where the Add-in installed. | +| installedWebName | string | Site name where the Add-in installed. | +| installedWebUrl | string | Site url where the Add-in installed. | +| currentSiteId | Guid | Site collection id of current site. | +| currentWebId | Guid | Site id of current site. | +| currentWebName | string | Site name of current site. | +| currentWebUrl | string | Site url of current site. | +| status | string | The status of current Add-in. | +| appWebFullUrl | string | The full url of the app web. The SharePoint components are generally in a special child web of the host web called the app web. The app web will be created during install the add-in. | +| appWebId | Guid | Id of the app web. | +| appWebName | string | Name of the app web. | +| installedBy | string | User name of who installed the add-in. | +| appIdentifier | string | The identifier of the app principal. It could be used to get the Add-in's permission. | +| creationTimeUtc | DateTime | Date time when installed the add-in. | +| productId | Guid | The global unique id of the add-in. It is same for all tenants. | +| assetId | string | The id of the app in the office store, this will be empty for app catalog user uploaded apps. | +| purchaserIdentity | string | The identify of person who bought the license of the add-in. | +| licensePurchaseTime | DateTime | When purchased the app license. | +| locale | string | which locale installed on the site. | +| appSource | string | Indicate where the app come from. | +| tenantAppData | string | After the Add-in installed in the tenant app catalog site. It could enable tenant level usage. This data indicates the conditions how to filter the sites. If this field is not empty, it means this Add-in installed on tenant app catalog site, deployed to tenant level, and current site matches the conditions. For more information, see [Tenancies and deployment scopes for SharePoint Add-ins](../sp-add-ins/tenancies-and-deployment-scopes-for-sharepoint-add-ins.md). | +| tenantAppDataUpdateTime | DateTime | The tenant app data update time. | + +### SPErrorWithServerRelativeUrl + +| Name | Type | Description | +|-------------------|--------|--------------------------------------------------------| +| serverRelativeUrl | string | The serverRelativeUrl or url in the request body. | +| errorMessage | string | The error message why fetch the site's Add-ins failed. | + +## Get Add-in permissions in site collections + +This API will return the permissions that were granted to the add-in. For more information, see [Add-in permissions in SharePoint](../sp-add-ins/add-in-permissions-in-sharepoint.md). + +This API needs the app to have at least Sites.Read.All permission. + +### HTTP request + +```HTTP +POST {adminSiteUrl}/_api/web/AddinPermissions +``` + +### Request body + +| Name | Required | Type | Description | +|--------|----------|----------------------------|----------------------------------------------------------------------------------| +| addins | yes | SPAddinPermissionRequest[] | List of the Add-in that want to get the permissions. Maximum Add-in size is 500. | + +#### SPAddinPermissionRequest + +| Name | Type | Description | +|-------------------|----------|-------------------------------------------------------------------------------------------| +| serverRelativeUrl | string | The server relative url of the site collection. | +| url | string | The url of the site collection, both server relative url and absolute url are acceptable. | +| appIdentifiers | string[] | The identifier list of the Add-ins. | + +The serverRelativeUrl and url can't be both null. If both serverRelativeUrl and url are provided, the url will be used. + +### Responses +| Name | Type | Description | +|------------------|-------------------------------|-----------------------------------------------------------------------| +| addinPermissions | SPAddinPermissionInfo[] | The returned permissions. | +| failedAddins | SPAddinPermissionFailedInfo[] | The Add-ins that failed to get permissions and corresponding reasons. | + +#### SPAddinPermissionInfo + +| Name | Type | Description | +|---------------------------------|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| tenantScopedPermissions | SPTenantScopedPermissionInfo[] | This is the permissions grant in tenant scope level. | +| siteCollectionScopedPermissions | SPSiteCollectionScopedPermissionInfo[] | This is the permissions grant in site collection scope level. | +| appIdentifier | string | The identifier of the Add-in. | +| serverRelativeUrl | string | The server relative url of the site collection. | +| absoluteUrl | string | The absolute url of the site collection. | +| allowAppOnly | bool | This identifies if the Add-in allows app only mode. For more information, see [Add-in authorization policy types in SharePoint](../sp-add-ins/add-in-authorization-policy-types-in-sharepoint.md). | + +#### SPTenantScopedPermissionInfo + +| Name | Type | Description | +|---------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| feature | string | The feature name of the permissions, it should be one of these:
  • Taxonomy
  • Social
  • ProjectServer
  • Search
  • BcsConnection
  • Content
| +| scope | string | The scope of the permission. | +| right | string | The right of the permission. | +| id | Guid | The id of the resource that the Add-in have permission to. For example, it may be the id of one specific project when the feature is ProjectServer and the scope is projectserver/projects/project. | + + +#### SPSiteCollectionScopedPermissionInfo + +| Name | Type | Description | +|--------|--------|------------------------------------------------------------------------------------------------------------------------------------------------| +| siteId | Guid | The site collection id which the Add-in has access to. | +| webId | Guid | The site id which the Add-in has access to. If this field is empty, then the permission grant in site collection level. | +| listId | Guid | The list id which the Add-in has access to. If this field is empty, then the permission grant in site collection level or grant is site level. | +| right | string | Available rights: Guest, Read, Write, Manage, FullControl. | + + +#### SPAddinPermissionFailedInfo + +| Name | Type | Description | +|-------------------|--------|-----------------------------------------------------------------| +| serverRelativeUrl | string | The server relative url or absolute url of the site collection. | +| appIdentifier | string | The identifier list of the Add-in. | +| errorMessage | string | The error message why fetch the Add-in permission failed. | + +## Get tenant ACS service principals + +This API takes the app id list as input, it will filter the ones that present ACS service principals. +For more information, see [Register SharePoint Add-ins](../sp-add-ins/register-sharepoint-add-ins.md). + +This API needs the app to have at least Sites.Read.All permission. + +### HTTP request + +```HTTP +POST {adminSiteUrl}/_api/web/GetACSServicePrincipals +``` + +### Request body + +| Name | Required | Type | Description | +|--------|----------|--------|------------------------------------| +| appIds | yes | Guid[] | List app ids. Maximum size is 500. | + +### Responses + +| Name | Type | Description | +|------|-----------------------------|-------------------------------------| +| | SPACSServicePrincipalInfo[] | The SPACSServicePrincipalInfo list. | + +#### SPACSServicePrincipalInfo + +| Name | Type | Description | +|---------------|----------|-----------------------------------------------------------------------------------------------| +| appIdentifier | string | The app identifier of the Add-in. | +| appId | Guid | The app id of the Add-in. | +| title | string | A user friendly title. | +| redirectUri | string | The endpoint in your remote application or service to which ACS sends an authentication code. | +| appDomains | string[] | The host name of the remote component of the SharePoint Add-in. | + +## Get Add-in principals in site collections + +This API takes the site collections' server relative url as input, it will return the Add-in principals that have permissions in given sites. + +This API needs the app to have at least Sites.Read.All permission. + +### HTTP request + +```HTTP +POST {adminSiteUrl}/_api/web/GetAddinPrincipalsHavingPermissionsInSites +``` + +### Request body + +| Name | Required | Type | Description | +|--------------------|----------|----------|------------------------------------------------------------------------------------------------------------| +| serverRelativeUrls | no | string[] | List site collections' server relative url. Maximum size is 500. | +| urls | no | string[] | List site collections' url, both server relative url and absolute url are acceptable. Maximum size is 500. | + +When urls is not null, serverRelativeUrls will be disregarded. + +### Responses + +| Name | Type | Description | +|-----------------------------|--------------------------------|-------------| +| addinPrincipals | SPAddinPrincipalInfo[] | | +| errorsWithServerRelativeUrl | SPErrorWithServerRelativeUrl[] | | + +#### SPAddinPrincipalInfo + +| Name | Type | Description | +|-------------------|--------|-------------------------------------------------| +| title | string | The title of the Add-in. | +| appIdentifier | string | The app identifier. | +| serverRelativeUrl | string | The server relative url of the site collection. | +| absoluteUrl | string | The absolute url of the site collection. | + + +#### SPErrorWithServerRelativeUrl + +| Name | Type | Description | +|-------------------|--------|------------------------------------------------------------| +| serverRelativeUrl | string | The site collection's server relative url or absolute url. | +| errorMessage | string | The error message why fetch the Add-in principal failed. | + +## Uninstall Add-ins + +This API will trigger an async job to uninstall the Add-in. If the job triggered successfully, the job id will be returned. + +This API needs the app to have Sites.FullControl.All permission. + +### HTTP request + +```HTTP +POST {adminSiteUrl}/_api/web/UninstallAddins +``` + +### Request body + +| Name | Required | Type | Description | +|-----------------|----------|---------------------------|---------------------------------------------------------------| +| uninstallAddins | yes | SPUninstallAddinRequest[] | List of Add-ins need to uninstall. Maximum Add-in size is 50. | + +#### SPUninstallAddinRequest + +| Name | Type | Description | +|-------------------|--------|---------------------------------------------------------------------------| +| serverRelativeUrl | string | The site's server relative url. | +| url | string | The site's url, both server relative url and absolute url are acceptable. | +| appInstanceIds | Guid[] | The instance ids of the Add-ins. | + +The serverRelativeUrl and url can't be both null. If both serverRelativeUrl and url are provided, the url will be used. + +### Responses + +| Name | Type | Description | +|-----------|--------------------------------------------|---------------------------------------------------------------------------| +| executing | SPTriggeredUninstallAddinJobResponse[] | This field contains the ones that successed to trigger the uninstall job. | +| failed | SPFailToTriggerUninstallAddinJobResponse[] | This field contains the ones that failed to trigger the uninstall job. | + +#### SPTriggeredUninstallAddinJobResponse + +| Name | Type | Description | +|-------------------|--------|---------------------------------| +| appInstanceId | Guid | The instance id of the Add-in. | +| serverRelativeUrl | string | The site's server relative url. | +| absoluteUrl | string | The site's absolute url. | +| uninstallJobId | Guid | The triggered uninstall job id. | + +#### SPFailToTriggerUninstallAddinJobResponse + +| Name | Type | Description | +|-------------------|--------|---------------------------------------------------------| +| appInstanceId | Guid | The instance id of the Add-in. | +| serverRelativeUrl | string | The site's server relative url. | +| errorMessage | Guid | The error message why the uninstall job trigger failed. | + + +## Get uninstall Add-in job status + +Since the uninstall Add-in is an async process, this API will provide the ability to check if the uninstall ends successfully. +If the job ends successfully, then the job will be not found. If the job ends with failure, then it will return the error detail. + +This API needs the app to have at least Sites.Read.All permission. + +### HTTP request + +```HTTP +POST {adminSiteUrl}/_api/web/GetAddinUninstallJobDetail +``` + +### Request body + +| Name | Required | Type | Description | +|-------------------|----------|--------|----------------------------------------------------------------------------| +| jobId | yes | Guid | This uninstall job id. | +| serverRelativeUrl | no | string | The site's server relative url. | +| url | no | string | The site's url, both server relative url and absolute url are acceptable. | + +The serverRelativeUrl and url can't be both null. If both serverRelativeUrl and url are provided, the url will be used. + +### Responses + +| Name | Type | Description | +|-------------------|-------------------------------|--------------------------------------------------| +| serverRelativeUrl | string | The site's server relative url. | +| absoluteUrl | string | The site's absolute url. | +| taskStartTime | DateTime | The time when the task starts executing. | +| jobId | Guid | The uninstall job id. | +| siteId | Guid | The site collection id. | +| appInstanceId | Guid | The id of the app instance. | +| errorDetails | SPUninstallAddinErrorDetail[] | The error details for the job ends with failure. | + +#### SPUninstallAddinErrorDetail + +| Name | Type | Description | +|------------------|--------|-------------------------------------| +| detail | string | The error detail. | +| exceptionMessage | string | The exception message of the error. | +| source | string | The source of the error. | +| type | string | The type of the error. | +| correlationId | Guid | The job's correlation id. | diff --git a/docs/apis/alm-api-for-spfx-add-ins.md b/docs/apis/alm-api-for-spfx-add-ins.md index ca589ac7c..41afaff9a 100644 --- a/docs/apis/alm-api-for-spfx-add-ins.md +++ b/docs/apis/alm-api-for-spfx-add-ins.md @@ -1,15 +1,15 @@ --- -title: Application Lifecycle Management (ALM) APIs +title: Application Lifecycle Management (ALM) APIs description: ALM APIs provide simple APIs to manage deployment of your SharePoint Framework solutions and add-ins across your tenant. -ms.date: 11/16/2019 -ms.prod: sharepoint +ms.date: 06/28/2022 +ms.subservice: migration-tool ms.assetid: fdf7ecb2-8851-425b-b058-3285fba77b68 -localization_priority: Priority +ms.localizationpriority: high --- # Application Lifecycle Management (ALM) APIs -ALM APIs provide simple APIs to manage deployment of your SharePoint Framework solutions and add-ins across your tenant. ALM APIs support the following capabilities: +ALM APIs provide simple APIs to manage deployment of your SharePoint Framework solutions and add-ins across your tenant. ALM APIs support the following capabilities: - Add SharePoint Framework solution or SharePoint Add-in to tenant or site collection app catalog. - Remove SharePoint Framework solution or SharePoint Add-in from tenant or site collection app catalog. @@ -23,29 +23,96 @@ ALM APIs provide simple APIs to manage deployment of your SharePoint Framework s ALM APIs can be used to perform exactly the same operations that are available from a UI perspective. When these APIs are used, all typical actions are performed. Following are some of the characteristics of ALM APIs: - `Install` and `UnInstall` events are being fired for provider-hosted add-ins when corresponding operations occur. -- ALM APIs support app-only-based operations for SharePoint Framework solutions only. +- ALM APIs support app-only-based operations for SharePoint Framework solutions only. -ALM APIs are natively provided by using REST APIs, but there are additional CSOM extensions, PowerShell cmdlets, and the cross-platform Office 365 CLI available through SharePoint PnP Community channels. +ALM APIs are supported for the tenant-scoped site collections and [site collection app catalog](../general-development/site-collection-app-catalog.md). Use the corresponding app catalog's URL to target a specific app catalog. You must first enabled a site collection app catalog before targeting it with the actions documented on this page. > [!IMPORTANT] -> Tenant-scoped permissions which require [tenant administrative approval](https://docs.microsoft.com/sharepoint/dev/solution-guidance/how-to-provide-add-in-app-only-tenant-administrative-permissions-in-sharepoint-online) are not supported with the ALM APIs. +> Tenant-scoped permissions which require [tenant administrative permissions](../solution-guidance/how-to-provide-add-in-app-only-tenant-administrative-permissions-in-sharepoint-online.md) are not supported with the ALM APIs. -## REST API +## Options for working with ALM APIs -> [!TIP] -> ALM APIs are also supported for the [site collection app catalog](../general-development/site-collection-app-catalog.md). URLs for the site collection app catalog operations are exactly the same, but you can change the `tenantappcatalog` to `sitecollectionappcatalog`. Notice also that you will need to enable the site collection app catalog in your site collection or you will get an exception when trying to use these APIs. +ALM APIs are natively provided by using REST APIs, but there are additional client-side object model (CSOM) extensions, PowerShell cmdlets, and the cross-platform CLI for Microsoft 365 available through SharePoint PnP Community channels. -### Add solution package to the app catalog +### SharePoint REST API -This API is designed to be executed in the context of the app catalog site. +The ALM APIs are natively provided as endpoints on the SharePoint REST API. -#### HTTP Request +The app catalog must be included in all HTTP requests when using the REST API as shown in the examples below. Replace the `{app-catalog-scope}` placeholder in the endpoint with the scope of the app catalog. The available scope options are `tenantappcatalog` and `sitecollectionappcatalog`. + +For example: + +| Scope | Endpoint | +| :-------------- | :------------------------------------------------------------------------------------------- | +| tenant | `https://contoso.sharepoint.com/sites/AppCatalog/_api/web/tenantappcatalog/{command}` | +| site collection | `https://contoso.sharepoint.com/sites/Marketing/_api/web/sitecollectionappcatalog/{command}` | + +- when targeting the tenant app catalog located at `https://contoso.sharepoint.com/sites/AppCatalog`, the endpoint would be ** + +Learn more here: [SharePoint REST API](../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) + +### PnP CSOM (also known as: PnP Sites Core) + +The PnP CSOM implements the ALM APIs by calling the SharePoint REST API. + +Before using any of the ALM APIs in PnP CSOM, you need to obtain an authenticated client context using the [Microsoft.SharePointOnline.CSOM](https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM). Then use the authenticated client context to get an instance of the PnP CSOM's **AppManager** object to call the ALM commands: + +```csharp +using Microsoft.SharePoint.Client; +using OfficeDevPnP.Core.ALM; + +// ... + +using (var context = new ClientContext(webURL)) { + context.Credentials = new SharePointOnlineCredentials(username, securePassword); + var appManager = new AppManager(context); + // execute PnP CSOM ALM command +} +``` + +In all PnP Core methods, it's assumed the request targets the tenant app catalog in the tenant you connect to using the SharePoint CSOM `ClientContext` object. you can override the scope of all commands with an optional scope argument, for example + +```csharp +appManager.Install('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx', AppCatalogScope.Site); +``` + +Learn more here: [PnP PowerShell](https://github.com/pnp/PnP-Sites-Core) + +### PnP PowerShell + +PnP PowerShell implements the ALM APIs by calling the PnP CSOM. + +Before using any of the cmdlets in the PnP PowerShell module, you must first connect to SharePoint Online using the `Connect-PnPOnline` cmdlet. + +In all PnP PowerShell cmdlets, it's assumed the request targets the tenant app catalog in the tenant you connect to using the `Connect-PnPOnline` cmdlet. You can override the scope of the command using the `-Scope` parameter to target a site collection app catalog. + +Learn more here: [PnP PowerShell](https://aka.ms/sppnp-powershell) + +[!INCLUDE [pnp-powershell](../../includes/snippets/open-source/pnp-powershell.md)] + +### CLI for Microsoft 365 + +The CLI for Microsoft 365 is a cross-platform command-line interface that can be used on any platform, including Windows, macOS, and Linux. The CLI implements the ALM APIs by calling the SharePoint REST API. + +Before using any of the commands in the CLI for Microsoft 365, you must first connect your Microsoft 365 tenant using the `m365 login` command. + +Learn more here: [CLI for Microsoft 365](https://pnp.github.io/cli-microsoft365?utm_source=msft_docs&utm_medium=page&utm_campaign=Use+SharePoint+Online+tenant+properties) + +[!INCLUDE [pnp-o365cli](../../includes/snippets/open-source/pnp-o365cli.md)] + +## Add solution package + +First add an app package (**\*.sppkg** or **\*.app**) to an app catalog in order to make it available to SharePoint sites. + +# [SharePoint REST API](#tab/sprest) + +### HTTP request ```http -POST /_api/web/tenantappcatalog/Add(overwrite=true, url='test.txt') +POST /_api/web/{scope}appcatalog/Add(overwrite=true, url='sharepoint-solution-package.sppkg') ``` -#### Request headers +### Request headers | Header | Value | | :---------------------- | :---------------------------------- | @@ -55,21 +122,50 @@ POST /_api/web/tenantappcatalog/Add(overwrite=true, url='test.txt') | X-RequestDigest | `{form digest}` | | binaryStringRequestBody | `true` | -#### Request body +### Request body Byte array of the file -### Deploy solution packages in the app catalog +# [PnP CSOM](#tab/pnpcsom) + +```csharp +// read file +var filePath = "c:\path\to\file\sharepoint-solution-package.sppkg"; +// get an instance of the PnP CSOM's AppManager as shown above +var result = appManager.Add(filePath); +``` + +# [PnP PowerShell](#tab/pnpposh) + +```powershell +Add-PnPApp -Path ./sharepoint-solution-package.sppkg +``` -This enables the solution to be available to install to specific sites. This API is designed to be executed in the context of the app catalog site. +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Add-PnPApp.html) for complete details and examples on this cmdlet. -#### HTTP Request +# [CLI for Microsoft 365](#tab/o365cli) + +```console +m365 spo app add --filePath ./sharepoint-solution-package.sppkg +``` + +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-add/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. + +--- + +## Deploy solution packages + +Deployment of the solution makes it available to install in sites. + +# [SharePoint REST API](#tab/sprest) + +### HTTP request ```http -POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Deploy +POST /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Deploy ``` -#### Request headers +### Request headers | Header | Value | | :-------------- | :------------------------------------------------ | @@ -78,29 +174,57 @@ POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-x | Content-Type | `application/json;odata=nometadata;charset=utf-8` | | X-RequestDigest | `{form digest}` | -#### Request body +### Request body ```json -{"skipFeatureDeployment":true} +{ + "skipFeatureDeployment": true +} ``` > [!NOTE] -> This operation is required to be completed after Add, before you can install packages to specific sites. +> This operation can only be completed after calling the `Add` endpoint and before you can install packages to specific sites. -> [!NOTE] -> It is currently not supported to deploy several packages in parallel - make sure to serialize your deployment operations to avoid deployment errors. +> [!IMPORTANT] +> Deploying multiple packages in parallel is not supported. Make sure to serialize your deployment operations to avoid deployment errors. -### Retract solution packages in the app catalog +# [PnP CSOM](#tab/pnpcsom) -This retracts the solution to be available from the sites. This API is designed to be executed in the context of the app catalog site. +```csharp +appManager.Deploy('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') +``` + +# [PnP PowerShell](#tab/pnpposh) + +```powershell +Publish-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Publish-PnPApp.html) for complete details and examples on this cmdlet. + +# [CLI for Microsoft 365](#tab/o365cli) + +```console +m365 spo app deploy --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-deploy/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. + +--- -#### HTTP Request +## Retract solution packages + +This is the inverse of the **deploy** step above. Once retracted, the solution can't be installed in sites. + +# [SharePoint REST API](#tab/sprest) + +### HTTP request ```http -POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Retract +POST /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Retract ``` -#### Request headers +### Request headers | Header | Value | | :---------------------- | :---------------------------------- | @@ -109,131 +233,227 @@ POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-x | X-RequestDigest | `{form digest}` | > [!NOTE] -> If you run this operation after you have installed solutions to the site, they stop working because the solution is disabled from the tenant level. +> This operation will block installing the solution in sites and disable existing installations. + +# [PnP CSOM](#tab/pnpcsom) + +```csharp +// get an app package +appManager.Retract('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') +``` + +# [PnP PowerShell](#tab/pnpposh) + +```powershell +Unpublish-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Unpublish-PnPApp.html) for complete details and examples on this cmdlet. -### Remove solution packages from the app catalog +# [CLI for Microsoft 365](#tab/o365cli) -This API is designed to be executed in the context of the app catalog site. +```console +m365 spo app retract --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-retract/?utm_source=msft_docs&utm_medium=page&utm_campaign=Use+SharePoint+Online+tenant+properties) for complete details and examples on this command. + +--- + +## Remove solution packages + +This is the inverse of the **add** step above. One removed from the app catalog, the solution can't be deployed. -#### HTTP Request +# [SharePoint REST API](#tab/sprest) + +### HTTP request ```http -POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Remove +POST /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Remove ``` -#### Request headers +# [PnP CSOM](#tab/pnpcsom) -| Header | Value | -| :---------------------- | :---------------------------------- | -| Authorization | `Bearer {token}` | -| Accept | `application/json;odata=nometadata` | +```csharp +appManager.Remove('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') +``` +# [PnP PowerShell](#tab/pnpposh) + +```powershell +Remove-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Remove-PnPApp.html) for complete details and examples on this cmdlet. + +# [CLI for Microsoft 365](#tab/o365cli) + +```console +m365 spo app remove --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-remove/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. + +--- > [!NOTE] > If the Retract operation is not performed before the Remove operation, the solution is automatically retracted. -### List available packages from the app catalog +## List available packages + +This operation will return a list of all available SharePoint Framework solutions or add-ins in the app catalog. -Use this REST API for getting a list of available SharePoint Framework solutions or add-ins in the app catalog. +# [SharePoint REST API](#tab/sprest) -#### HTTP Request +### HTTP request ```http -GET /_api/web/tenantappcatalog/AvailableApps +GET /_api/web/{scope}appcatalog/AvailableApps ``` -#### Request headers +### Request headers | Header | Value | | :---------------------- | :---------------------------------- | | Authorization | `Bearer {token}` | | Accept | `application/json;odata=nometadata` | -### Get details about individual solution packages in the app catalog +### Response -Use this REST API for getting details about individual SharePoint Framework solutions or add-ins available in the app catalog. +```json +{ + "value": [ + { + "AadAppId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "ContainsTenantWideExtension": false, + "CurrentVersionDeployed": true, + "Deployed": true, + "ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "IsClientSideSolution": true, + "IsEnabled": true, + "IsPackageDefaultSkipFeatureDeployment": false, + "IsValidAppPackage": true, + "ShortDescription": "", + "SkipDeploymentFeature": false, + "Title": "sharepoint-solution-package" + }, + { + "AadAppId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "ContainsTenantWideExtension": false, + "CurrentVersionDeployed": true, + "Deployed": true, + "ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "IsClientSideSolution": true, + "IsEnabled": true, + "IsPackageDefaultSkipFeatureDeployment": false, + "IsValidAppPackage": true, + "ShortDescription": "", + "SkipDeploymentFeature": false, + "Title": "sharepoint-solution-package2" + } + ] +} +``` -#### HTTP Request +# [PnP CSOM](#tab/pnpcsom) -```http -GET /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') +```csharp +var allAppPackages = appManager.GetAvailable(); ``` -#### Request headers - -| Header | Value | -| :---------------------- | :---------------------------------- | -| Authorization | `Bearer {token}` | -| Accept | `application/json;odata=nometadata` | +# [PnP PowerShell](#tab/pnpposh) -### Install solution package from the app catalog to a SharePoint site +```powershell +Get-PnPApp +``` -Install a solution package with a specific identifier from the app catalog to the site based on URL context. This REST call can be executed in the context of the site where the install operation should happen. +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Get-PnPApp.html) for complete details and examples on this cmdlet. -#### HTTP Request +# [CLI for Microsoft 365](#tab/o365cli) -```http -POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Install +```console +m365 spo app list ``` -#### Request headers +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-list/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. -| Header | Value | -| :---------------------- | :---------------------------------- | -| Authorization | `Bearer {token}` | -| Accept | `application/json;odata=nometadata` | -| X-RequestDigest | `{form digest}` | +--- + +## Get a specific solution -### Upgrade solution packages on the SharePoint site +This action will return details about a specific SharePoint Framework solution or add-in available in the app catalog. -Upgrade a solution package from the site to a newer version available in the app catalog. This REST call can be executed in the context of the site where the upgrade operation should happen. +# [SharePoint REST API](#tab/sprest) -#### HTTP Request +### HTTP request ```http -POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Upgrade +GET /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') ``` -#### Request headers +### Request headers | Header | Value | | :---------------------- | :---------------------------------- | | Authorization | `Bearer {token}` | | Accept | `application/json;odata=nometadata` | -| X-RequestDigest | `{form digest}` | -### Uninstall solution packages from the SharePoint site +### Response -This REST call can be executed in the context of the site where the uninstall operation should happen. +```json +{ + "AadAppId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "ContainsTenantWideExtension": false, + "CurrentVersionDeployed": true, + "Deployed": true, + "ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "IsClientSideSolution": true, + "IsEnabled": true, + "IsPackageDefaultSkipFeatureDeployment": false, + "IsValidAppPackage": true, + "ShortDescription": "", + "SkipDeploymentFeature": false, + "Title": "sharepoint-solution-package" +} +``` -#### HTTP Request +# [PnP CSOM](#tab/pnpcsom) -```http -POST /_api/web/tenantappcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Uninstall +```csharp +var appPackage = appManager.GetAvailable('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx'); ``` -#### Request headers +# [PnP PowerShell](#tab/pnpposh) -| Header | Value | -| :---------------------- | :---------------------------------- | -| Authorization | `Bearer {token}` | -| Accept | `application/json;odata=nometadata` | -| X-RequestDigest | `{form digest}` | +```powershell +Get-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` -> [!NOTE] -> When you use the REST API to uninstall a solution package from the site, it is not relocated to the recycle bin. +> Refer to the [PnP PowerShell documentation](/powershell/module/sharepoint-pnp/Get-PnpApp) for complete details and examples on this cmdlet. + +# [CLI for Microsoft 365](#tab/o365cli) + +```console +m365 spo app get --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx +``` + +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-get/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. + +--- -### Synchronize a solution to the Microsoft Teams App Catalog +## Install solution package in a site -This REST call requires that you refer the **list item id** of the solution in the app catalog site. +Install a solution package with a specific identifier from the app catalog to the site based on URL context. -#### HTTP Request +# [SharePoint REST API](#tab/sprest) + +### HTTP Request ```http -POST /_api/web/tenantappcatalog/SyncSolutionToTeams(id=xxxxx) +POST /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Install ``` -#### Request headers +### Request headers | Header | Value | | :---------------------- | :---------------------------------- | @@ -241,133 +461,168 @@ POST /_api/web/tenantappcatalog/SyncSolutionToTeams(id=xxxxx) | Accept | `application/json;odata=nometadata` | | X-RequestDigest | `{form digest}` | -## SharePoint PnP PowerShell cmdlets - -By using [PnP PowerShell](https://docs.microsoft.com/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps), you can automate deploying, publishing, installing, upgrading, and retracting your apps. - -> [!NOTE] -> Support for scope option was released on the April 2018 release of PnP PowerShell. +# [PnP CSOM](#tab/pnpcsom) -### Add and publish your app to the app catalog +```csharp +// get an app package +appManager.Install('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') +``` -Adding your app (.sppkg file, .app file) to the app catalog is a prerequisite to making your app available for use on your SharePoint sites. You can do this by using the following cmdlet: +# [PnP PowerShell](#tab/pnpposh) ```powershell -Add-PnPApp -Path ./myapp.sppkg -Scope Tenant +Install-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx ``` -Once added, you need to continue with publishing your app, effectively making the app available to be used by the users of your tenant. The following PnP PowerShell cmdlet shows how this can be done: +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Install-PnPApp.html) for complete details and examples on this cmdlet. -```powershell -Publish-PnPApp -Identity -SkipFeatureDeployment -Scope Tenant +# [CLI for Microsoft 365](#tab/o365cli) + +```console +m365 spo app install --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx --siteUrl ``` -> [!NOTE] -> Use the `SkipFeatureDeployment` flag to allow an app that was developed for tenant-wide deployment to be actually available as a tenant-wide deployed app. +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-install/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. -### Remove the app from the app catalog +--- -To remove an app added earlier, use the following cmdlet: +## Upgrade installed solution packages -```powershell -Remove-PnPApp -Identity -Scope Tenant -``` +Upgrade a solution package from the site to a newer version available in the app catalog. -### Use apps on your site +# [SharePoint REST API](#tab/sprest) -After the app is added to the app catalog and published, you can install the app to your site: +### HTTP request -```powershell -Install-PnPApp -Identity -Scope Tenant +```http +POST /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Upgrade ``` -To upgrade the app: +### Request headers -```powershell -Update-PnPApp -Identity -Scope Tenant +| Header | Value | +| :---------------------- | :---------------------------------- | +| Authorization | `Bearer {token}` | +| Accept | `application/json;odata=nometadata` | +| X-RequestDigest | `{form digest}` | + +# [PnP CSOM](#tab/pnpcsom) + +```csharp +// get an app package +var appPackage = appManager.GetAvailable('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx'); +if (appPackage.CanUpgrade) { + appManager.Upgrade(appPackage) +} ``` -To uninstall the app from your site: +# [PnP PowerShell](#tab/pnpposh) ```powershell -Uninstall-PnPApp -Identity -Scope Tenant +Update-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx ``` -> [!NOTE] -> When you uninstall an app from your site, the app is completely deleted, so it does not end up in the site's recycle bin. -### Know which apps are there for you to use +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Update-PnPApp.html) for complete details and examples on this cmdlet. -You can get a list of apps that can be added to the site by using: +# [CLI for Microsoft 365](#tab/o365cli) -```powershell -Get-PnPApp -Scope Tenant +```console +m365 spo app upgrade --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx --siteUrl ``` -## Office 365 CLI commands to add, deploy, and manage SharePoint apps cross-platform +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-upgrade/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. -Using the [Office 365 CLI](https://pnp.github.io/office365-cli?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs), you can automate deploying, publishing, installing, upgrading, and retracting your apps. The Office 365 CLI is a cross-platform command-line interface that can be used on any platform, including Windows, MacOS, and Linux. To learn more about these commands, see the following sections. +--- -### Add and publish your app to the app catalog +## Uninstall solution packages from a site -Adding your app (.sppkg file, .app file) to the tenant app catalog is a prerequisite to making your app available for use on your SharePoint sites. Use the [add](https://pnp.github.io/office365-cli/cmd/spo/app/app-add/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command to do this: +This action is the inverse of the **install** command above. -```shell -spo app add --filePath ./spfx.sppkg -``` +> [!NOTE] +> When you use the uninstall a solution package from the site with any of the methods below, it's permanently deleted; it'sn't placed in the recycle bin. -Once added, you need to continue with publishing your app, effectively making the app available to be used by the users of your tenant. Use the [deploy](https://pnp.github.io/office365-cli/cmd/spo/app/app-deploy/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command to do this: +# [SharePoint REST API](#tab/sprest) -```shell -spo app deploy --id --skipFeatureDeployment +### HTTP request + +```http +POST /_api/web/{scope}appcatalog/AvailableApps/GetById('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx')/Uninstall ``` -> [!NOTE] -> Use the **SkipFeatureDeployment** flag to allow an app that was developed for tenant-wide deployment to be actually available as a tenant-wide deployed app. +### Request headers + +| Header | Value | +| :---------------------- | :---------------------------------- | +| Authorization | `Bearer {token}` | +| Accept | `application/json;odata=nometadata` | +| X-RequestDigest | `{form digest}` | + +# [PnP CSOM](#tab/pnpcsom) -### Remove the app from the app catalog +```csharp +appManager.Uninstall('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') +``` -You may want to remove an app that you added earlier, and you can do this by using the [remove](https://pnp.github.io/office365-cli/cmd/spo/app/app-remove/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command: +# [PnP PowerShell](#tab/pnpposh) -```shell -spo app remove --id +```powershell +Uninstall-PnPApp -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx ``` -### Use apps on your site +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Uninstall-PnPApp.html) for complete details and examples on this cmdlet. -After the app is added to the app catalog and published, you can install the app to your site by using the [install](https://pnp.github.io/office365-cli/cmd/spo/app/app-install/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command: +# [CLI for Microsoft 365](#tab/o365cli) -```shell -spo app install --id --siteUrl +```console +m365 spo app uninstall --id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx --siteUrl ``` -To upgrade the app, use the [upgrade](https://pnp.github.io/office365-cli/cmd/spo/app/app-upgrade/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command: +> Refer to the [CLI for Microsoft 365 documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/app/app-uninstall/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) for complete details and examples on this command. -```shell -spo app upgrade --id --siteUrl -``` +--- -To uninstall the app from your site, use the [uninstall](https://pnp.github.io/office365-cli/cmd/spo/app/app-uninstall/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command: +## Synchronize a solution to the Microsoft Teams app catalog -```shell -spo app uninstall --id --siteUrl +This action requires that you refer the **list item ID** of the solution in the app catalog site. + +# [SharePoint REST API](#tab/sprest) + +### HTTP request + +```http +POST /_api/web/{scope}appcatalog/SyncSolutionToTeams(id=xxxxx) ``` -> [!NOTE] -> When you uninstall an app from your site, the app is completely deleted, so it will not end up in the site's recycle bin. +### Request headers -### List and get apps in the app catalog -You can see what apps have been added to the app catalog by using the [list](https://pnp.github.io/office365-cli/cmd/spo/app/app-list/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command: +| Header | Value | +| :---------------------- | :---------------------------------- | +| Authorization | `Bearer {token}` | +| Accept | `application/json;odata=nometadata` | +| X-RequestDigest | `{form digest}` | + +# [PnP CSOM](#tab/pnpcsom) -```shell -spo app list +```csharp +appManager.SyncToTeams('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx') ``` -You can get a single app's details by using the [get](https://pnp.github.io/office365-cli/cmd/spo/app/app-get/?utm_source=msft_docs&utm_medium=page&utm_campaign=Application+Lifecycle+Management+ALM+APIs) command: +# [PnP PowerShell](#tab/pnpposh) -```shell -spo app get --id +```powershell +Sync-PnPAppToTeams -Identity xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx ``` +> Refer to the [PnP PowerShell documentation](https://pnp.github.io/powershell/cmdlets/Sync-PnPAppToTeams.html) for complete details and examples on this cmdlet. + +# [CLI for Microsoft 365](#tab/o365cli) + +*Not Supported* + +--- + ## See also - [Get to know the SharePoint REST service](../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) +- [PnP PowerShell](https://aka.ms/sppnp-powershell) +- [CLI for Microsoft 365](https://pnp.github.io/cli-microsoft365?utm_source=msft_docs&utm_medium=page&utm_campaign=Use+SharePoint+Online+tenant+properties) diff --git a/docs/apis/amr-api-reference.md b/docs/apis/amr-api-reference.md new file mode 100644 index 000000000..2c3e44aa8 --- /dev/null +++ b/docs/apis/amr-api-reference.md @@ -0,0 +1,253 @@ +--- +title: "SharePoint Asynchronous Metadata Read (AMR) API Reference Guide" +description: "This article provides in-depth information on how to use the SharePoint AMR API." +ms.date: 04/18/2024 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- +# SharePoint Asynchronous Metadata Read (AMR) API Reference Guide + +Use this document as the guide when using SharePoint Asynchronous Metadata Read (AMR) API. + +AMR API aggregates SharePoint metadata into a manifest package. Use the package for incremental migration, structure creation, post-migration validation, or permission management. + +## CSOM and REST + +AMR API supports both SharePoint Client Side Object Model (CSOM) and REST. + +### Use NuGet Packages with CSOM + +To reference the SharePoint Client Side Object Model (CSOM) in your solution, use NuGet packages. + +Manage dependencies easily and ensure your solution is using the latest version of the CSOM library with NuGet packages. + +Get the latest version of the CSOM package at the [SharePoint Client-side Object Model Libraries](https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM) with the ID `Microsoft.SharePointOnline.CSOM`. + +Check [Get to know SharePoint REST service](/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service) for instructions on REST API. + +## CreateSPAsyncReadJob method + +Creates an AMR job to read all the metadata of the specified SharePoint URL and its children into the specified manifest container. + +### CreateSPAsyncReadJob syntax + +```csharp +public SPAsyncReadJobInfo CreateSPAsyncReadJob(String url, +SPAsyncReadOptions readOptions, +EncryptionOption encryptionOption, +string azureContainerManifestUri, +string azureQueueReportUri) +``` + +### CreateSPAsyncReadJob parameters + +#### url + +Required. + +A **String** value containing the full path URL of the path of the SharePoint List, files/folders, or Document Library **to read**. AMR API returns all the metadata of files, folders, and root objects, **including subfolders and any children content**. + +##### Example + +This example `url` returns all metadata of Shared Document, and its children: + +```http +https://www.contoso.com/Shared%20Document +``` + +#### readOptions + +Required. + +A `SPAsyncReadOptions` structure, with `readOption` values specifying the types of metadata to read. + +##### IncludeVersions + +Optional. + +A **Bool** value to indicate if AMR API reads multiple versions of files and List Items. + +Default value is `false`. When absent or set to `false`, AMR API only reads the latest version of items. + +##### IncludeSecurity + +Optional. + +A **Bool** value to indicate if AMR API reads Users and Groups information related to a Site. + +Default value is `false`. + +AMR API reads Users and Groups as Authors or Modifiers as part of the metadata of the objects. + +If set to `true`, AMR API reads all Users in Site Collections. When reading multiple Document Libraries under the same Site Collection, the same Users and Group might appear in the read package multiple times. + +##### IncludeDirectDescendantsOnly + +Optional. + +A **Bool** value to indicate if AMR API reads only the metadata of the direct descendants. + +Default value is `false`. + +If set to `true`, AMR API reads only the metadata of the direct descendants. + +Use this `readOption` along with `IncludeSecurity` `readOption` together to improve performance when reading metadata from a Document Library containing large number of items, as described in [Best practice](export-amr-api.md) to avoid slow performance. + +##### IncludeExtendedMetadata + +Optional. + +Default value is `false`. + +When set to `false`, AMR API reads basic metadata: + +- List +- Folder +- File +- List Item +- Roles +- Role Assignments + +When set to `true`, AMR API reads all metadata available: + +For Files: + +- Web Part +- Web Part personalization +- Links +- Version events +- Event receivers +- Attachment metadata + +For Lists: + +- Custom actions +- List shortcuts + +For List Items: + +- Comments +- Documents set links +- Activities +- List Item shortcuts + +Including extended metadata slows down the read significantly. For file share migrations, keep the default value `false`. Set to `true` only when necessary, for complex migration projects. + +##### IncludePermission + +Optional. + +A **Bool** value to indicate if permissions read is needed. Default value is `false`. + +When set to `true`, AMR API reads permission metadata in `RoleAssignments` tags in `Manifest.xml` files. The file includes all distinguished permission metadata for each read SharePoint object, along with property `ScopeId`. + +##### StartChangeToken + +Optional. + +A **Integer** value containing the changeToken item. + +By default, when no `StartChangeToken` is provided, `CreateSPAsyncReadJob` method returns all items available, based on the parameters. A `CurrentChangeToken` value is returned every time. + +To read only the items that changed since last read, set a `StartChangeToken` in subsequent calls to `CreateSPAsyncReadJob`. Use `CurrentChangeToken` returned from last call as the value of `StartChangeToken`. + +AMR API returns an error and stops the read, if it receives an invalid `StartChangeToken` value. + +Be careful when using this feature with large number of items. The read job could run for extended duration. AMR API cancels jobs that run over 10 minutes to protect the SharePoint infrastructure. + +#### encryptionOption + +Optional. + +A `EncryptionOption` object, containing the AES-256-CBC Key used to decrypt the output. + +By default, AMR API doesn't encrypt the output and event queue. If set with AES-256-CBC Key, AMR API encrypts the output with the key supplied. + +See [`EncryptionOption`](/dotnet/api/microsoft.sharepoint.client.encryptionoption) class for details. + +#### azureContainerManifestUri + +Required. + +A **String** value, which is the destination URL of the Azure Blob Storage Container containing the output manifest package. + +See [Azure](migration-azure.md) for instructions of using Azure Blob Storage Container in migration. + +#### azureQueueReportUri + +Required. + +A **String** value, which is the URL of the Azure Queue to receive read status messages. + +Share `azureQueueReportUri` among different jobs if necessary. AMR API returns `JobID` to identify individual jobs created. + +See [Azure](migration-azure.md) for instructions of using Azure Queue in migration. Check [Migration events in Azure Queue](migration-events.md) for types of events. + +### CreateSPAsyncReadJob return values + +#### Job ID + +A **Guid** value, which contains Job ID, the unique identifier of the migration job. The method returns a `null` value, if it fails to create the job. + +AMR API generates a `JobEnd` event when it estimates item count for each `url`. Check [Events](migration-events.md) for details. + +#### AzureContainerManifest + +A **Uri** value that contains the URL to access the Azure Blob Storage Container, which contains the metadata read. + +#### JobQueueUri + +A **Uri** value that contains the URL of the Azure Queue used for read status. + +#### EncryptionKey + +A **Byte Array** value that contains the AES-256-CBC Key for decrypting the manifest files and messages in the Azure Queue. + +## CreateSPAsyncReadJobWithMultiUrl method + +Creates an AMR job to read all the metadata of all SharePoint URLs specified, and their children into the specified manifest container. + +### CreateSPAsyncReadJobWithMultiUrl syntax + +```csharp +public SPAsyncReadJobInfo CreateSPAsyncReadJobWithMultiUrl( + String[] urls, + SPAsyncReadOptions readOptions, + EncryptionOption encryptionOption, + String azureContainerManifestUri, + String azureQueueReportUri) +``` + +### CreateSPAsyncReadJobWithMultiUrl parameters + +See `CreateSPAsyncReadJob` method for details of `readOptions`, `encryptionOption`, `azureContainerManifestUri`, and `azureQueueReportUri`. + +#### urls + +Required. + +A **Uri** **Array** containing the full path URLs of the root paths of the SharePoint Lists, files/folders, or Document Libraries to read. AMR API returns all the metadata of files, folders, and root objects, **including subfolders and any children content**. + +Specify multiple URLs when needed. Aggravated call with multiple URLs might improve the performance. See [Performance](export-amr-api.md#performance) for details. + +## Errors + +### -2146232832 + +The changeToken refers to a time before the start of the current change log. + +The change log is limited to 60 days immediately before the current date. AMR API returns this error code when the specified `changeToken` refers to a time outside the 60-day window. + +### -2147213196 + +Operation canceled. + +AMR API received a cancellation request from the client and cancels the read operation. diff --git a/docs/apis/csom-methods-for-applying-retention-labels.md b/docs/apis/csom-methods-for-applying-retention-labels.md new file mode 100644 index 000000000..ddde1e391 --- /dev/null +++ b/docs/apis/csom-methods-for-applying-retention-labels.md @@ -0,0 +1,143 @@ +--- +title: CSOM methods for retention labels +description: CSOM methods are available to apply (set) a retention label (ComplianceTag) on one or many items (ListItems) in SharePoint. Also includes settings of retention labels in ODB and SPO. +author: kyracatwork +ms.author: kyrachurney +ms.date: 9/30/2024 +--- + +# CSOM methods for applying retention labels and managing settings of record labels + +Retention labels let you apply retention settings for governance control at the item level, and are part of the Microsoft Purview compliance solutions. [Learn more about retention labels.](/microsoft-365/compliance/retention#retention-labels) + +Retention labels may classify contents as records, which place restrictions on what actions are allowed or blocked. [Learn more about declaring records by using retention labels](/microsoft-365/compliance/declare-records) + +CSOM methods are available to apply (set) a retention label (ComplianceTag) on one or many items (ListItems) in SharePoint, and change retention labels settings for deleting, versioning, and changing properties of records. Retention labels can be applied using this method without being published to the location by an existing label policy. + +## SetComplianceTagOnBulkItems + +This method can be used to set a ComplianceTag on one or many ListItems. It is strongly recommended to use this method for this purpose. + +```c# +public List SetComplianceTagOnBulkItems( + List itemIds, + string listUrl, + string complianceTagValue) +``` + +### Parameters + +- 'List' [Int](/en-us/dotnet/api/system.int32) +- 'ItemsIds' [String](/dotnet/api/system.string) +- 'ListURL' [String](/dotnet/api/system.string) +- 'ComplianceTagValue' [String](/dotnet/api/system.string) + +Attribute [RemoteAttribute](/dotnet/api/microsoft.sharepoint.client.remoteattribute) + +## GetAllowFilesWithKeepLabelToBeDeletedODB + +Get whether files with Keep Label can be deleted in ODB. + + +```c# + +public static bool GetAllowFilesWithKeepLabelToBeDeletedODB() +``` + +## SetAllowFilesWithKeepLabelToBeDeletedODB + +Set whether files with Keep Label can be deleted in ODB + + +```c# +public static void SetAllowFilesWithKeepLabelToBeDeletedODB(bool allowDeletion) +``` + +Parameters + +- 'allowDeletion' [Boolean](/dotnet/api/system.boolean) + +## GetAllowFilesWithKeepLabelToBeDeletedSPO +Get whether files with Keep Label can be deleted in SPO. + +```c# + +public static bool GetAllowFilesWithKeepLabelToBeDeletedSPO() +``` + +## SetAllowFilesWithKeepLabelToBeDeletedSPO + +Set whether files with Keep Label can be deleted in SPO. + +```c# +public static void SetAllowFilesWithKeepLabelToBeDeletedSPO(bool allowDeletion) +``` + +Parameters + +- 'allowDeletion' [Boolean](/dotnet/api/system.boolean) + +## GetAdvancedRecordVersioningDisabled + +Get whether advanced record versioning is disabled. + +```c# + +public static bool GetAdvancedRecordVersioningDisabled() +``` + +## SetAdvancedRecordVersioningDisabled + +Set to enable or disable the advanced record versioning. + +```c# +public static void SetAdvancedRecordVersioningDisabled(bool disabled) +``` + +Parameters + +- 'disabled' [Boolean](/dotnet/api/system.boolean) + +## GetMetadataEditBlockingEnabled + +Get whether metadata edit blocking is enabled. + +```c# + +public static bool GetMetadataEditBlockingEnabled() + +``` + +## SetMetadataEditBlockingEnabled + +Set metadata edit blocking enabled setting. + + +```c# +public static void SetMetadataEditBlockingEnabled(bool enabled) +``` + +Parameters + +- 'enabled' [Boolean](/dotnet/api/system.boolean) + +### Applies to + +|Product|Versions| +|:---|:---| +|SharePoint CSOM|latest| + +## Other + +> [!NOTE] +> It is strongly recommended to use SetComplianceTagOnBulkItems instead of these methods. + +The following methods are also available, but are no longer updated and may be subject to deprecation in the future. If you are using these methods, we strongly recommend use of the SetComplianceTagOnBulkItems method instead. + +* [SetComplianceTag](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetag) +* [SetComplianceTagWithExplicitMetaInfo](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetagwithexplicitmetasupdate) +* [SetComplianceTagWithExplicitMetasUpdate](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetagwithexplicitmetasupdate) +* [SetComplianceTagWithHold](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetagwithhold) +* [SetComplianceTagWithMetaInfo](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetagwithmetainfo) +* [SetComplianceTagWithNoHold](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetagwithnohold) +* [SetComplianceTagWithRecord](/dotnet/api/microsoft.sharepoint.client.listitem.setcompliancetagwithrecord) diff --git a/docs/apis/export-amr-api-permission-guide.md b/docs/apis/export-amr-api-permission-guide.md new file mode 100644 index 000000000..55a921cc2 --- /dev/null +++ b/docs/apis/export-amr-api-permission-guide.md @@ -0,0 +1,167 @@ +--- +title: "SharePoint Migration Export (Asynchronous Metadata Read) API permission guide" +description: This article targets ISVs and any third-party vendors/developers who are developing and maintaining a migration tool and explains the permission details and options in the export API. +ms.date: 08/25/2023 +ms.author: jhendr +author: JoanneHendrickson +manager: Serdars +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- + +# AMR Export Permission Guide + +The Asynchronous Metadata Read (AMR) API export permission lets you export SharePoint Online metadata permission info using a new export option. This guide will show you how to use this option and what changes have been introduced to the export result. + +## How to use AMR export permission option + +For both CSOM and RESTFul calls, add the below option to enable/disable AMR export permission: + +- For CSOM, when building `AsyncReadOptions` object, set `IncludePermission` property to `true` or `false`. + - If you cannot use `IncludePermission` property, please update your CSOM nuget package to the latest version. +- For RESTFul, add `IncludePermission` key to the request JSON payload's `readOptions` section, and set it to `true` or `false`. + - For example: `{..., "readOptions":{...,"IncludePermission":true,...}...}` + +## What changes have been introduced to the export result + +The new `IncludePermission=true` option will involve an additional tag called `` into **Manifest.xml** file in the export result, which includes all distinguished permission info for each exported SPO object with property `ScopeId`, like below: + +```xml +<...> + + + + + ... + + +<...> +``` + +The `RoleAssignments` tag is a list of `RoleAssignment` tags, each `RoleAssignment` tag represents a unique permission scope from exported SPO objects, identified by `ScopeId`. Each `RoleAssignment` tag contains multiple `Assignment` tags, representing an entity within that specific unique permission scope each, such as a user, a group, etc., with a principal ID. + +In the meantime, all involved entities will be listed in **UserGroup.xml** file in the export result, to help further user resolution. + +Here is an example of **Manifest.xml** file and **UserGroup.xml** with `IncludePermission=true` option: + +```xml + +<...> + + + +<...> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<...> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +## Option interaction between `IncludeSecurity` and `IncludePermission` + +Before the `IncludePermission` option, the `IncludeSecurity` option has been already used to get a full list of all user & group information of the target site. It isn't necessary that you use the `IncludePermission` option with `IncludeSecurity` option. However, if you still want to get a full list of all user and group information of target sites with permission information, you can use `IncludePermission` option with `IncludeSecurity` option together, here are the 4 combinations of the two options with expected results: + +- `IncludeSecurity=true` only: get a full list of all user & group information of the target site without permission information. +- `IncludePermission=true` only: get exported items' permission information, with a list of corresponding user & group information of exported permissions. +- `IncludeSecurity=true` + `IncludePermission=true`: get exported items' permission information, with a full list of all user & group information of the target site. +- None of them is used: get no permission, nor related user & group information. diff --git a/docs/apis/export-amr-api.md b/docs/apis/export-amr-api.md index 3941c6eb0..fe7248b8f 100644 --- a/docs/apis/export-amr-api.md +++ b/docs/apis/export-amr-api.md @@ -1,267 +1,123 @@ --- -title: "SharePoint Migration Export (Asynchronous Metadata Read) API" -ms.reviewer: -ms.author: jhendr -author: JoanneHendrickson -manager: pamgreen +title: "SharePoint Asynchronous Metadata Read (AMR) API Introduction" +description: Overview how to read metadata from SharePoint, targeted to SharePoint migration tool developers. +ms.date: 07/23/2025 +ms.author: ranren +author: underreview +manager: dapodean audience: ITPro +ms.subservice: migration-tool ms.topic: article -localization_priority: Priority -ms.collection: -- SPMigration -- m365-collaboration -description: "SharePoint Migration Export (Asynchronous Metadata Read) API" +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration --- +# SharePoint Asynchronous Metadata Read (AMR) API Introduction -# SharePoint Migration Export (Asynchronous Metadata Read) API +The SharePoint Asynchronous Metadata Read (AMR) API enables the asynchronous export of metadata from SharePoint and OneDrive. +Use AMR API to export metadata from SharePoint for incremental migration and post-migration validation. -## Overview -The goal of the new Migration Asynchronous Metadata Read API is to reduce the number of CSOM calls, reduce throttling, and improve overall migration performance. Instead of calling thousands of CSOM calls to query information from SPO, the new Migration Asynchronous Metadata Read can return the same amount of data in a single read. +AMR is designed exclusively for import scenarios. It exhibits poor scalability when handling requests for metadata, permissions, or versions. We can't provide performance assurances for AMR usage in data export scenarios, such as cross-tenant migrations. -When the new SharePoint Migration Export (Asynchronous Metadata Read) API performs a read operation of a provided URL, the Microsoft backend software aggregates all the information into a designated manifest. The ISV can read back from the manifest and parse the metadata without sending thousands of CSOM calls individually. +## What's new -This document targets ISVs and any third-party vendors/developers who are developing and maintaining a migration tool. +### January 2024 +We reformatted this document to bring clarity and correct errors. +## Export steps overview -### Background: -Currently, the SharePoint Online Migration API, [CreateMigrationJob](https://docs.microsoft.com/sharepoint/dev/apis/migration-api-overview), lets your migration tool efficiently migrate large amounts data to SharePoint Online. However, the lack of an official API to read content from SharePoint Online means that these tools must rely on CSOM function calls to perform individual metadata read operations. +Export metadata from SharePoint in three steps: -
-Large numbers of CSOM calls increase the likelihood of throttling which impacts migration performance and customer experience. Ineffective CSOM usage results in large SQL round trip per function calls that can potentially bring down the database and impact its reliability. +### Provision the destination containers and the queue -A migration performance study identified four areas where CSOM calls are heavily used: -- **Incremental migration** relies on CSOM calls to retrieve the SharePoint online (SPO) content. It compares it with the source location to determine if there have been any changes to the content and whether to proceed with migration. -- **Structure creation** leverages CSOM calls for site, webpart and navigation creation. -- **After migration verification** is done when migration is completed and is used to ensure the source and destination file metadata matches. -- **Permission settings** are CSOM function calls made getting user permission information. +> [!IMPORTANT] +> Use [GetMigrationJobProgress API](migration-job-progress-api-reference.md) to retrieve migration job status. +> +> Provisioning Azure Queues for migration job status tracking is no longer required. Deprecation of Azure Queues is planned for the second half of 2026. Until then, Azure Queues will remain available for status retrieval. -## SharePoint Migration Export (Asynchronous Metadata Read) API +Use `ProvisionMigrationContainers` method to provision the containers. Check [Use Azure Blob Storage Containers and Azure Queues with Migration API](migration-azure.md) for details. You can also use your own containers and queues if needed. -The SharePoint Migration Export (Asynchronous Metadata Read) API aims to reduce the CSOM calls in areas: incremental migration, after migration verification and permission settings. +### Use `CreateSPAsyncReadJob` method to start the export ->[!Note] ->The first version of the SharePoint Migration Export (Asynchronous Metadata Read) API supports files, folders, lists, list items, and the document library. Permissions are expected to be covered in a subsequent version. +Use `CreateSPAsyncReadJob` method to export metadata from a single URL, or `CreateSPAsyncReadJobWithMultiUrl` from multiple URLs if needed. Check [AMR API Reference](amr-api-reference.md) for details. -Key supported features: +Get incremental updates with `ChangeToken` feature. -- Ability to read up to 1 million items with a single API call. For more information, see Limitations. -- Incremental migration feature support returning of item changed since last query with changeToken feature -- Ability to include a rich set of metadata per item -- Ability to return only top-level structure without subfolders or children. +Both methods return the Job ID, which can be used to track the export status. -More detailed information about the features and the API description is covered in the section below. +Check [AMR API Reference](amr-api-reference.md) for details. -The new Migration Asynchronous Read API is: +### Checking status -```csharp +> [!IMPORTANT] +> Use [GetMigrationJobProgress API](migration-job-progress-api-reference.md) to retrieve migration job status. +> +> Provisioning Azure Queues for migration job status tracking is no longer required. Deprecation of Azure Queues is planned for the second half of 2026. Until then, Azure Queues will remain available for status retrieval. - public SPAsyncReadJobInfo CreateSPAsyncReadJob( - Uri rootObjectUri, - SPAsyncReadOptions readOptions, - EncryptionOption encryptionOption, - string azureContainerManifestUri, - string azureQueueReportUri) - -``` +Check Azure Queue supplied for export status. Monitor events as listed in [Events](migration-events.md) for details. -The API is made up of five input parameters and one output structure field. +AMR API exports metadata in the manifest container supplied, under a folder named by `JobID`. Check [Manifest files](migration-manifest.md) for the format and validation of the metadata. +AMR API splits manifest packages larger than 25 MB into multiple manifest files per request. +## Best practice -## Input Parameters +AMR API is powerful. Ensure good performance to achieve the scale for large migration projects. -### URL - -The full path URL lets your migration tool to specify the root URL path of the SharePoint list, files/folder document library to be read. By default, the server-side code will read and return all the metadata of files, folders and root objects including subfolders and their children content. +### Export security and permissions on top level if possible -*Example:* -This document library URL, https://www.contoso.com/Shared%20Document, will be read back for metadata of any files or folders that live under the root URL. +Exporting security with `IncludeSecurity` consumes more resources and slows down the export. It's faster to export this metadata at the upper-level folder first, then export the children without them. -https://www.contoso.com/Shared%20Documents/FolderA/, will be read back for children metadata in FolderA. +### Metadata export on a single item -#### readOptions Flag -The read asynchronous function will include the SPAsyncReadOptions structure which covers the optional flags to allow the user to specify version and security setting on the site level more is described below. +Use Microsoft Graph instead of AMR. - IncludeVersions{ get; set; } +### Folders with less than 10,000 items -If set, this indicates all the files and list item version history is to be included in the export operation. If absent, only the most recent version is provided. -
-
+Use `CreateSPAsyncReadJobWithMultiUrl` to combine the URLs of multiple folders into a single export job. - IncludeSecurity{ get; set; } +### Folders with 10,000 to 1 million items -This flag indicates whether to include all user or group information from a site. By default, it assumes the security is not set, hence no user or group information is provided. +Use `CreateSPAsyncReadJob`, and set **readOption** `IncludeDirectDescendantsOnly` to `false`. This value is the default setting. +### Nested folders with over 1 million items - public bool IncludeDirectDescendantsOnly { get; set;} +Plan carefully when dividing folders into jobs. Object count in export jobs is the major factor of export performance. -If specified only the top level metadata item is read back. Example: The root URL contains file A and folder B. If this flag is specified, the manifest returns only file A and folder B metadata. It will not return any metadata included inside folder B. +This example shows how to export metadata from nested folders with over 1 million items. AMR API has the highest performance when the item count is large. -The use case for this function: The ISV can issue a default read to retrieve the top-level items and then issue multiple *CreateSPAsyncReadJob* to read back all the sub folder content in parallel to improve throughput. +- Use `CreateSPAsyncReadJob` method at the root URL, for example: `www.contoso.com/my-resource-document`, and set **readOption** `IncludeDirectDescendantsOnly` to `true`. +- Utilize `SMTotalFileCount` attribute to get the file count in folders. +- Continue to use `createSPAsyncReadJob` method at subfolder level, on each of the subfolders, if the folder has more than 10,000 items. +- Use `CreateSPAsyncReadJobWithMultiUrl` method, combining subfolders with less than 10,000 items. +## Performance - public bool IncludeExtendedMetadata { get; set; } +AMR API processes jobs through a queue mechanism with preconfigured workload management settings. AMR API processes the jobs on a best-effort basis, without Service Level Agreement (SLA) or guaranteed performance. -This flag indicates whether to return the extended set of metadata content of object query. By default this option is off and only basic content is provided (e.g. names, URL, author, modifier, dates) . Turning this flag on provides all the metadata content; however, it will also impact the performance as query will take longer. +### Lab-tested performance baseline -Recommendation is to keep the default for file share migration, but consider setting this flag on for SharePoint on-premises or other more complex migration. +We tested the performance in a lab setting. AMR API exported about 400 items per second for every 250-K objects, in the average case. The peak performance reached 700 items per second. - public string StartChangeToken { get; set; } +Multiple factors affect real-life performance. These factors include: -This option applies to input URL of list or document library only. - -One of the key CSOM contributor is incremental migration. ChangeToken idea is introduced to reduce the unnecessary CSOM calls. If StartChangeToken is not specified, the CreateSPAsyncReadJob will query and read back all the items specified by the API function. Once specified with the ChangeToken value, only the item changed since last query is returned. - -During incremental migration, instead of query everything again, by populating StartChangeToken with the change token received from the CurrentChangeToken output in returning job info, createSPAsyncReadJob then returns only the items that got changed since the specified StartChangeToken, reducing the overall CSOM calls. +- The number of items that are being exported +- The way AMR API is implemented +- Throttling -Below is a sample of how the *startChangeToken* might work. This example uses the optional feature setting for initial call and the parameter setting for incremental passes. +### Optimize migration performance -![Export API process](../images/async-read-api-flow.png) +In order to ensure optimal performance for your migration projects, it's important to plan carefully, especially when dealing with large-scale migrations. For more information on how to estimate timespans and optimize performance, see our [performance guide](/sharepointmigration/sharepoint-online-and-onedrive-migration-speed). -#### Invalid Value +### I'm seeing throttling messages -If an invalid value is detected, other than NULL, an error will be generated, and the operation will be terminated. +To ensure good user experiences for all Microsoft 365 customers, SharePoint uses throttling to protect the SharePoint infrastructure. Avoid getting throttled by following [throttling guidance](https://aka.ms/spo429). -#### encryptionOption +### Tenant-to-Tenant migrations -This is an optional parameter. If it is specified, the AES256CBCKey is used to encrypt output files and queue messages. Otherwise, there is no encryption. +AMR isn't intended for scenarios where contents from a SharePoint tenant are moved to another. This type of migration requires the use of many resource-heavy read options. The long processing time of these read options slows down the overall migration significantly. -For more information, see [EncryptionOption Class](https://docs.microsoft.com/dotnet/api/microsoft.sharepoint.client.encryptionoption). - - -#### azureContainerManifestUri - -The valid URL including SAS token for accessing the Azure Blob Storage Container which contains the block blobs for the manifest and other package describing XML files. This location will also be used for the log output response. The SAS token must have been created with only Read and Write permissions or the asynchronous metadata read job will fail. The SAS token should at least have a lifetime that starts at from no later than when the job was submitted, until a reasonable time for successful import to have concluded. - -#### azureQueueReportUri -The valid URL including SAS token for accessing the user provided Azure Queue used for returning notifications of asynchronous metadata read job progress. If this value is not null and proper access is granted in the SAS token in this URI, it will be used for real time status update. The SAS token must have been created with Add permissions or the migration job will be unable to add events to the queue. - -Once accepted, the job ID will be written to the notification queue if it was provided and access is valid. The notification queue can be used for multiple migration jobs at the same time, as each job will identify itself in values sent back to the notification queue. - - -## Output Parameters - -### CurrentChangeToken - - public string CurrentChangeToken { get; set; } - -This function returns the changeToken associates with this query. By specifying this changeToken in the input field with subsequent read, the API will return only items changed since this last query. - -#### Manifest Output - -After the asyncMigrationRead function finishes execution, the final manifest will be placed in the container specified, under a folder named **JobId**. Manifest export package structure will be like the *createMigration* Import Package structure. The general output structure is summarized in table below. - -Below is an example on how to query the folder: - - CloudBlobDirectory folder = blobContainerObj.GetDirectoryReference(jobid); - CloudBlockBlob blob = folder.GetBlockBlobReference(manifestFileName); - -|**XML file**|**Schema File**|**Description**| -|:-----|:-----|:-----| -|ExportSettings.XML|DeploymentExportSettings Schema|ExportSettings.XML does the following:

- Contains the export settings specified by using the SPExportSettings class and other classes that are part of the content migration object model.

- Ensures that the subsequent export process (at the migration target site) enforces the directives specified in the export settings.

- Maintains a catalog of all objects exported to the migration package.| -|LookupListMap.XML|DeploymentLookupListMap Schema|Provides validation for the LookupListMap.XML file exported into the content migration package. LookupListMap.XML maintains a simple lookup list that records SharePoint list item (list item to list item) references.| -|Manifest.XML|DeploymentManifest Schema|Provides validation for the Manifest.xml file that is exported into the content migration package.Provides a comprehensive manifest containing listings of both the contents and the structure of the destination site (E.g. SPO) . | -|Requirements.XML|DeploymentRequirements Schema|"Provides validation for the Requirements.xml file exported into the content migration package. Requirements.xml maintains list of deployment requirements in the form of installation requirements on the migration target, such as feature definitions, template versions, Web Part assemblies, and language packs."| -|RootObjectMap.XML|DeploymentRootObjectMap Schema|"Provides validation for the RootObjectMap.xml file exported into the content migration package.RootObjectMap.xml maintains a list of mappings of secondary (dependent) objects, which allows the import phase of the migration operation to correctly place the dependent objects relative to the locations of the root object mappings."| -|SystemData.XML|DeploymentSystemData Schema|Provides validation for the SystemData.xml file exported into the content migration package.SystemData.xml does the following: Collects a variety of low-level system data. Records the number and names of Manifest.xml files (in cases where the migration uses multiple manifests).| -|UserGroupMap.XML|DeploymentUserGroupMap Schema|Provides validation for the UserGroup.xml file exported into the content migration package. UserGroup.xml maintains a list of users and user security groups with respect to access security and permissions.| -|ViewFormsList.XML|DeploymentViewFormsList Schema|Provides validation for the ViewFormsList.xml file exported into the content migration package.ViewFormsList.xml maintains a list of Web Parts and tracks whether each is a view or form.| - -#### JobQueueUri - - public Uri JobQueueUri { get; set; } - -The reporting features are the same as they are for **CreateMigrationJob**. Logging is provided to track the status of the asynchronous metadata read. After a scan of the database and an estimate of your tools, the log provides an estimate of the number of items to be read per URL. By default, blob queue permissions and settings are set to "all access", the same as when the ISV calls **ProvisionMigrationContainer** during the **CreateMigrationJob**. - -In addition to the events supported by the Import API (CreationMigrationJob), a new job event called **FinishManifestFileUpload** will be added to the status queue in real time. This is added after the manifest file is generated and uploaded. - -As it’s a real time event, ISVs and developers can also immediately download and parse the manifest files once **FinishManifestFileUpload** is generated. Use the field *ManifestFileName* to parse this event to get every manifest file name, including systemdata.xml, usergroup.xml, etc. - -The new event will look like this: - -```XML - -{"Event", "FinishManifestFileUpload"}, -   {"JobId", “f8d7d577-676e-47ce-ab69-ae7803979883”}, -   {"Time", “2019-09-03T19:11:33.903”}, -   {"ManifestFileName", “f8d7d577-676e-47ce-ab69-ae7803979883/ExportSettings.xml”} - -``` - -#### EncryptionKey: -public byte[] EncryptionKey { get; set; }

-It returns the AES256CBC encryption key used to decrypt the message in azureManifest container and azureReport Queue. - -|**Output parameter**|**Description**| -|:-----|:-----| -|JobID/GUID|Return a unique Job ID associated with this asynchronous read| -|AzureContainerManifest|Return the URL for accessing the async read manifest| -|JobQueueUri|URL for accessing Azure queue used for returning notification of migration job process| -|EncryptionKey|AES256CBC encryption key used to decrypt messages from job/manifest queue| - -## Set up Guidelines -The following provides high level guidelines for implementing the asynchronous metadata migration function. This documentation does not go into details on how to interact with SharePoint RESTful service. It is assumed that the ISV has prior knowledge and will be able to access the target website with proper permission.
,
For more information on how to access the SharePoint website, refer to [Get to Know the SharePoint Rest Service](https://docs.microsoft.com/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service). - -1. Install and update the latest Microsoft.SharePointOnline.CSOM version. The minimum version requirement is V16.1.9119.1200 or later. -2. ISVs figure out the folder, document library or files of interested to be query and issued with CreateSPAsyncReadJob function. -3. Once successfully created, query the job status using the *jobQueueUri*. It provides the job process status and any error logging. After job completion, parse the Manifest to retrieve the metadata. - -### SharePoint Migration Export (Asynchronous Metadata Read) API Example - -#### Scenario: Large file share with nested files/folders - -Suggestion: - -1. Issue CreateSPAsyncReadJob:
- a. URL = root URL (e.g. www.contoso.com/my-resource-document)
- b. Optional Flag: IncludeDirectDescendantsOnly(true) - -2. For each of the sub folders, issues createSPAsyncReadJob , for example if there are sub folder A and B
- a. Issue CreateSPAsyncReadJob with URL = root URL (e.g. www.contoso.com/my-resource-document/a)
- b. Issue CreateSPAsyncReadJob with URL = root URL (e.g. www.contoso.com/my-resource-document/b) - ->[!NOTE] ->This scenario is only recommended for top level folders or if the sub-folder contains greater than 100k of objects. The performance of the asynchronous metadata read api is not as effective when reading a small set of items. - -#### Scenario: Tenant to tenant or large SharePoint Migration - -1. Issue CreateSPAsyncReadJob:
- a. URL = root URL (e.g. www.contoso.com/my-resource-item)
- b. Optional Flag: IncludeDirectDescendantsOnly(true) , IncludeFullMetadata(true) - - -#### Scenario: Incremental Migration of FileShare for a sub folder - -1. Issue CreateSPAsyncReadJob:
- a. URL = root URL (e.g. www.contoso.com/my-resource-document/a)
- b. Remembered the CurrentChangeToken - -2. After some time, the software wishes to perform incremental migration. Issue CreateSPAsyncReadJob with following term:
- a. URL = root URL (e.g. www.contoso.com/my-resource-document/a)
- b. Optional Flag: StartChangeToken(CurrentChangeToken) - - -## Limitations - - -Asynchronous Metadata Read (Export API) now supports unlimited list, document library, file, and folder metadata export. - - -## Performance Expectation - -The preliminary performance test provides a rough estimate of more than 400 items per second throughput for every 250K of objects read. We have seen over 700 items per second throughput in a testing environment. However, this is highly dependent on the number of items that are being read plus the implementation of the AMR API. This does not account for any potential throttle over the network. If the asynchronous read function fails to reach the server due to throttling, then performance will be impacted. - -This measure of throughput assumes the software package has a sufficient number of items per read. Microsoft recommends the following: - -|**Folder size**|**Recommendation**| -|:-----|:-----| -|Less than 10,000 items|Combine the URLs of multiple folders into a single call| -|Greater than 10,000 items but less than 1,000,000|Run AMR at the root folder level| -|Greater than 1,000,000|Method is at the discretion of the ISV| - -For a single read query, it is faster to use the Graph API or a RESTful/CSOM query. - -One of the key performance benefits of using the asynchronous metadata read is the ability to balance the server-side load and the backend query. It is much more efficient than using individual CSOM load reducing to lessen your chance of throttling. - +Microsoft provides no performance guarantee in this scenario. Use Graph or CSOM as needed. diff --git a/docs/apis/migrate-webparts-with-migrationapi.md b/docs/apis/migrate-webparts-with-migrationapi.md index 7702e6bd4..25114eea9 100644 --- a/docs/apis/migrate-webparts-with-migrationapi.md +++ b/docs/apis/migrate-webparts-with-migrationapi.md @@ -1,17 +1,18 @@ --- title: "Migrating web parts using the Migration API" -ms.reviewer: +description: "Migrating web parts using the Migration API" ms.author: jhendr author: JoanneHendrickson manager: pamgreen audience: ITPro +ms.date: 06/28/2022 +ms.subservice: migration-tool ms.topic: conceptual -localization_priority: Normal +ms.localizationpriority: medium search.appverid: MET150 -msCollection: +msCollection: - SPMigration - M365-collaboration -description: "Migrating web parts using the Migration API" --- # Migrating web parts using the Migration API @@ -24,151 +25,145 @@ An advantage in using the Migration API for your web part migration is the abili There are two attributes that are handled in a unique way that requires using the WebPart User Properties Serializer DLL. There is a technical challenge to generate the property values for *AllUsersProperties* and *PerUserProperties* when building the PRIME package. This challenge is because the property values are BASE64 encoded blob, which is serialized web part properties and web part connection info. - To get the Serializer .dll, perform following steps: - 1. Install the SPMT Client on your local computer: [Install SPMT](https://aka.ms/spmt-GA-page). -2. Browse to the install location of SPMT -3. Locate and copy the *microsoft.sharepoint.migration.webpart.serializer.dll* and you can copy it into your project. +1. Browse to the install location of SPMT +1. Locate and copy the *microsoft.sharepoint.migration.webpart.serializer.dll* and you can copy it into your project. For a complete list of the supported web parts, see: -- [SPMT & Migration API supported SharePoint web parts](https://docs.microsoft.com/sharepointmigration/spmt-supported-webparts) - - +- [SPMT & Migration API supported SharePoint web parts](/sharepointmigration/spmt-supported-webparts) ## Schema: For an explanation of the **SPWebPart** fields see: -- [SPWebPart](https://docs.microsoft.com/openspecs/sharepoint_protocols/ms-primepf/25cfceeb-7769-4331-9936-ce3b9ced87ad) - - +- [SPWebPart](/openspecs/sharepoint_protocols/ms-primepf/25cfceeb-7769-4331-9936-ce3b9ced87ad) ### PRIME Web Part Schema example ```xml - - - - - - - - - - - …… - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + +…… + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ``` ## Security controls Due to the security control design on the server side, the following behavior: - + - If the NoScript is off, then go on migrating all web part as currently - If NoScript is on, then first check web part level safety - - If SafeAgainstScript is false, do not import it - - If SafeAgainstScript is true, then check the web part property level safety - - If the web part has any property with ‘RequiresDesignerPermission’, then ignore this web part (or ignore this property if feasible) - - Otherwise, go on migrating this web part - - + - If SafeAgainstScript is false, do not import it + - If SafeAgainstScript is true, then check the web part property level safety + - If the web part has any property with ‘RequiresDesignerPermission’, then ignore this web part (or ignore this property if feasible) + - Otherwise, go on migrating this web part + + Here is the list of web parts that will be ignored by server-side code (treated as untrusted webpart) when NoScript is turned ON: - XsltListViewWebPart @@ -195,141 +190,138 @@ Here is the list of web parts that will be ignored by server-side code (treated ## FAQ *Question:* How do I fetch the web part properties as the input for serialization API? -*Answer:* The web part properties can be found in element in the response of operation ‘GetWebPartProperties2’ in ‘WebPartPagesWebService’. Find the payload details in WSDL ‘/_vti_bin/WebPartPage.asmx?WSDL’. +*Answer:* The web part properties can be found in \ element in the response of operation ‘GetWebPartProperties2’ in ‘WebPartPagesWebService’. Find the payload details in WSDL ‘/_vti_bin/WebPartPage.asmx?WSDL’. *Question:* How to fetch the web part connection info as the input for serialization API? -*Answer:* The web part connections could be found in elements from the web part page in the response of operation ‘GetWebPartPage’ in ‘WebPartPagesWebService’. +*Answer:* The web part connections could be found in \ elements from the web part page in the response of operation ‘GetWebPartPage’ in ‘WebPartPagesWebService’. -View flags: refer to this https://docs.microsoft.com/openspecs/sharepoint_protocols/ms-wssfob/252d2086-6571-430f-863d-bcaf9d267e62, for example, all the view flags https://docs.microsoft.com/openspecs/sharepoint_protocols/ms-wssfob/16a9d8ca-185d-40ec-956e-bb6bf3488cf7. You will need to convert all flag values to PRIME element ‘flags’. +View flags: refer to [this](/openspecs/sharepoint_protocols/ms-wssfob/252d2086-6571-430f-863d-bcaf9d267e62), for example, all the [view flags](/openspecs/sharepoint_protocols/ms-wssfob/16a9d8ca-185d-40ec-956e-bb6bf3488cf7). You will need to convert all flag values to PRIME element ‘flags’. ## Appendix -### Sample Web Part Properties v2 XmlNode Element +### Sample Web Part Properties v2 XmlNode Element ```xml - - - Content Editor - Default - Allows authors to enter rich text content. - true - wpz - 0 - Normal - - - true - true - true - true - true - true - true - - - Modeless - Default - - - /_layouts/15/images/mscontl.gif - - true - 00000000-0000-0000-0000-000000000000 - g_d6def51c_7a91_40fe_9f59_de9ceed5c347 - Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c - Microsoft.SharePoint.WebPartPages.ContentEditorWebPart - - - - + + Content Editor + Default + Allows authors to enter rich text content. + true + wpz + 0 + Normal + + + true + true + true + true + true + true + true + + + Modeless + Default + + + /_layouts/15/images/mscontl.gif + + true + 00000000-0000-0000-0000-000000000000 + g_d6def51c_7a91_40fe_9f59_de9ceed5c347 + Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c + Microsoft.SharePoint.WebPartPages.ContentEditorWebPart + + + + ``` ### Sample Web Part Properties v3 XmlNode Element ```xml - - - - - - - - - False - - - True - - - False - - a316c9a6-e664-426b-9069-77cabd22429c - /Lists/TestPromotedLinks - False - NotSet - False - Html, TabularView, Hidden, Ordered - True - {A316C9A6-E664-426B-9069-77CABD22429C} - - True - Normal - True - - - All - False - True - True - - Modeless - - True - 86400 - Default - - - /_layouts/15/images/itgen.png?rev=23 - - True - - -1 - True - - - False - - PAGE_NORMALVIEW - - True - False - 00000000-0000-0000-0000-000000000000 - - main.xsl - True - - False - <View Name="{2B37E456-6FD3-4708-AC83-5D7B0D13E9B4}" Type="HTML" Hidden="TRUE" OrderedView="TRUE" DisplayName="" Url="/SitePages/TestPage.aspx" Level="1" BaseViewID="3" ContentTypeID="0x" ><Query><OrderBy><FieldRef Name="TileOrder" Ascending="TRUE"/><FieldRef Name="Modified" Ascending="FALSE"/></OrderBy></Query><ViewFields><FieldRef Name="Title"/><FieldRef Name="BackgroundImageLocation"/><FieldRef Name="Description"/><FieldRef Name="LinkLocation"/><FieldRef Name="LaunchBehavior"/><FieldRef Name="TileOrder"/></ViewFields><RowLimit Paged="TRUE">30</RowLimit><JSLink>clienttemplates.js</JSLink><XslLink Default="TRUE">main.xsl</XslLink><Toolbar Type="Standard"/></View> - False - True - <ParameterBinding Name="dvt_sortdir" Location="Postback;Connection" /><ParameterBinding Name="dvt_sortfield" Location="Postback;Connection" /><ParameterBinding Name="dvt_startposition" Location="Postback" DefaultValue="" /><ParameterBinding Name="dvt_firstrow" Location="Postback;Connection" /><ParameterBinding Name="OpenMenuKeyAccessible" Location="Resource(wss,OpenMenuKeyAccessible)" /><ParameterBinding Name="open_menu" Location="Resource(wss,open_menu)" /><ParameterBinding Name="select_deselect_all" Location="Resource(wss,select_deselect_all)" /><ParameterBinding Name="idPresEnabled" Location="Resource(wss,idPresEnabled)" /><ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" /><ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" /> - List - 60 - False - - Cannot import this Web Part. - - - - - + + + + + + + + False + + + True + + + False + + a316c9a6-e664-426b-9069-77cabd22429c + /Lists/TestPromotedLinks + False + NotSet + False + Html, TabularView, Hidden, Ordered + True + {A316C9A6-E664-426B-9069-77CABD22429C} + + True + Normal + True + + + All + False + True + True + + Modeless + + True + 86400 + Default + + + /_layouts/15/images/itgen.png?rev=23 + + True + + -1 + True + + + False + + PAGE_NORMALVIEW + + True + False + 00000000-0000-0000-0000-000000000000 + + main.xsl + True + + False + <View Name="{2B37E456-6FD3-4708-AC83-5D7B0D13E9B4}" Type="HTML" Hidden="TRUE" OrderedView="TRUE" DisplayName="" Url="/SitePages/TestPage.aspx" Level="1" BaseViewID="3" ContentTypeID="0x" ><Query><OrderBy><FieldRef Name="TileOrder" Ascending="TRUE"/><FieldRef Name="Modified" Ascending="FALSE"/></OrderBy></Query><ViewFields><FieldRef Name="Title"/><FieldRef Name="BackgroundImageLocation"/><FieldRef Name="Description"/><FieldRef Name="LinkLocation"/><FieldRef Name="LaunchBehavior"/><FieldRef Name="TileOrder"/></ViewFields><RowLimit Paged="TRUE">30</RowLimit><JSLink>clienttemplates.js</JSLink><XslLink Default="TRUE">main.xsl</XslLink><Toolbar Type="Standard"/></View> + False + True + <ParameterBinding Name="dvt_sortdir" Location="Postback;Connection" /><ParameterBinding Name="dvt_sortfield" Location="Postback;Connection" /><ParameterBinding Name="dvt_startposition" Location="Postback" DefaultValue="" /><ParameterBinding Name="dvt_firstrow" Location="Postback;Connection" /><ParameterBinding Name="OpenMenuKeyAccessible" Location="Resource(wss,OpenMenuKeyAccessible)" /><ParameterBinding Name="open_menu" Location="Resource(wss,open_menu)" /><ParameterBinding Name="select_deselect_all" Location="Resource(wss,select_deselect_all)" /><ParameterBinding Name="idPresEnabled" Location="Resource(wss,idPresEnabled)" /><ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" /><ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" /> + List + 60 + False + + Cannot import this Web Part. + + + + + ``` -4 - Sample Web Part Connection XmlNode Element +### Sample Web Part Connection XmlNode Element ```xml - ``` diff --git a/docs/apis/migration-api-azure-container-and-queue.md b/docs/apis/migration-api-azure-container-and-queue.md index 21ea2f23e..1dff25363 100644 --- a/docs/apis/migration-api-azure-container-and-queue.md +++ b/docs/apis/migration-api-azure-container-and-queue.md @@ -1,16 +1,16 @@ --- title: SPO provided Migration Azure container and queue +description: "One of the Main requirement for using our Migration API is the usage of an Azure container as a temporary storage. We now provide a default container that can be used for using the migration API." +ms.date: 07/08/2022 ms.author: jhendr author: JoanneHendrickson manager: pamgreen -ms.date: 6/20/2018 -description: "One of the Main requirement for using our Migration API is the usage of an Azure container as a temporary storage. We now provide a default container that can be used for using the migration API." -localization_priority: Normal +ms.subservice: migration-tool +ms.localizationpriority: medium --- - # SPO provided Migration Azure container and queue -Microsoft’s Migration API requires the use of an Azure container for temporary storage. To simplify the process, you are now provided with a default container while using the migration API. If you choose, you can still provide your own Azure container. +Microsoft’s Migration API requires the use of an Azure container for temporary storage. To simplify the process, you are now provided with a default container while using the migration API. To use the provided container you will need to [decorate your traffic correctly](/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online#how-to-decorate-your-http-traffic) to avoid throttling. If you choose, you can still provide your own Azure container. ## Encryption is required @@ -18,38 +18,38 @@ For the Migration API to accept a Migration Job coming from a SPO provided Azure ## Advantages -|Advantage|Description| -|:-----|:-----| -|Cost of Azure container goes to SPO|Since we are providing the containers, those containers are now part of the basic SharePoint online Offering. Every tenant who signs up for SharePoint Online will get this for free).| -|Containers and queues are unique per request and not reused|Once a container is given to a customer this container will not be reused or shared.| -|Containers and queue are automatically deleted|As per the standard SharePoint Online Compliance, we will destroy the container within 30 to 90 days automatically.| -|Containers and queues are in the customer’s datacenter location|We make sure to provision containers that are in the same physical location than their SharePoint online tenant.| -|They are obtainable programmatically|There is no need to interact with Azure unless the user chooses. +| Advantage | Description | +| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cost of Azure container goes to SPO | Since we are providing the containers, those containers are now part of the basic SharePoint online Offering. Every tenant who signs up for SharePoint Online will get this for free). | +| Containers and queues are unique per request and not reused | Once a container is given to a customer this container will not be reused or shared. | +| Containers and queue are automatically deleted | As per the standard SharePoint Online Compliance, we will destroy the container within 30 to 90 days automatically. | +| Containers and queues are in the customer’s datacenter location | We make sure to provision containers that are in the same physical location than their SharePoint online tenant. | +| They are obtainable programmatically | There is no need to interact with Azure unless the user chooses. | ## How to use it ### Getting Containers ```csharp - public SPProvisionedMigrationContainersInfo ProvisionMigrationContainers() +public SPProvisionedMigrationContainersInfo ProvisionMigrationContainers() ``` -The call will return an object that contains two strings containing two SAS tokens for accessing the two required containers and a byte array for the AES256CBC encryption. +The call will return an object that contains two strings containing two SAS tokens for accessing the two required containers and a byte array for the AES256CBC encryption. This key will need to be used when encrypting the data. We forget the key once we give it out, therefore you must keep it to pass it again for the Submit Migration Job call. ```csharp - Uri DataContainerUri +Uri DataContainerUri - Uri MetadataContainer Uri +Uri MetadataContainer Uri - byte[] EncryptionKey +byte[] EncryptionKey ``` ### Getting Queue ```csharp - public SPProvisionedMigrationQueueInfo ProvisionMigrationQueue() +public SPProvisionedMigrationQueueInfo ProvisionMigrationQueue() ``` This method will return a string containing the SAS token for accessing the Azure queue. @@ -57,9 +57,18 @@ This method will return a string containing the SAS token for accessing the Azur The queue can be reused across multiple migration jobs so this call should not be that frequently as the `SPProvisionedMigrationContainersInfo()` call. ```csharp - Uri JobQueueUri +Uri JobQueueUri ``` ### After getting the Container and the Queue: Once those calls have been made, the rest of the flow remains the same for using the Migration API. + +### Required endpoints for goverment cloud + +If your tenant is hosted in a government cloud (GCC), you must have the proper endpoints set when calling the API. For example: `usgovcloudapi.net`. + +| **Required Endpoint** | **Why** | +| :--------------------------------------- | :----------------------------------------- | +| `https://*.blob.core.usgovcloudapi.net` | Migration API Azure Government requirement | +| `https://*.queue.core.usgovcloudapi.net` | Migration API Azure Government requirement | diff --git a/docs/apis/migration-api-encryption.md b/docs/apis/migration-api-encryption.md index 792eec4e2..c46879621 100644 --- a/docs/apis/migration-api-encryption.md +++ b/docs/apis/migration-api-encryption.md @@ -1,11 +1,12 @@ --- title: OneDrive for Business and SharePoint Online Migration API – Encryption +description: "How to pass encrypted content at rest to the API securely." +ms.date: 6/20/2022 ms.author: jhendr author: JoanneHendrickson manager: pamgreen -ms.date: 6/20/2018 -description: "How to pass encrypted content at rest to the API securely." -localization_priority: Normal +ms.subservice: migration-tool +ms.localizationpriority: medium --- # OneDrive for Business and SharePoint Online Migration API encryption @@ -20,18 +21,19 @@ Content - Files - Manifest - - Metadata - - Permissions - - List items - - Taxonomy - - Logs (created by SharePoint Online to report back on the migration results) + - Metadata + - Permissions + - List items + - Taxonomy + - Logs (created by SharePoint Online to report back on the migration results) - Queue - - Real time reportig on the progress + - Real time reportig on the progress ## What is the encryption feature? -When using the encryption parameter, everything listed above will be encrypted at rest and the key will need to be preserved in order to read the logs and the real time progress. -The main benefits is making the content useless for a malicious user who would manage to breach into the Azure container. +When using the encryption parameter, everything listed above will be encrypted at rest and the key will need to be preserved in order to read the logs and the real time progress. + +The main benefits is making the content useless for a malicious user who would manage to breach into the Azure container. This comes with a small cost of performance. This feature is optional when using the API and it is recommended to only use it for the most confidential information since it does reduce the speed of the migration by a small portion. Microsoft destroys the key once the migration job is finished and there is no way to recover the key if lost, not even from support. @@ -58,10 +60,10 @@ Example: ## Extra requirement -For the encryption, each file must be encrypted and have an IV assigned to it. The encryption method should follow the AES CBC 256 Standard. The IV should be different for every file including the manifests in the package and should be stored as a property on each files. +For the encryption, each file must be encrypted and have an IV assigned to it. The encryption method should follow the AES CBC 256 Standard. A unique, cryptographically-random IV must be generated for every file including the manifests in the package and should be stored as a property on each files. Use the AesCryptoServiceProvider.GenerateIV method to generate a unique random IV for each file. -- Name = [IV] -- Value = [Base64encoded byte array of the IV] +- **Name**: [IV] +- **Value**: [Base64encoded byte array of the IV] ## Reading the queue when encrypted @@ -72,13 +74,13 @@ It is important to remember the Job ID. Without the specific key used for the jo Here is the JSON content in the queue message ```json -{"Label", "Encrypted"}, -{"JobId", "[JobId value]"}, -{"IV", "[IV value in base64format]"}, -{"Content", "[encrypted message in base64string]"} +{"Label": "Encrypted"}, +{"JobId": "[JobId value]"}, +{"IV": "[IV value in base64format]"}, +{"Content": "[encrypted message in base64string]"} ``` Once the messages are decrypted, they will be the same as the API without encryption. ->[!NOTE] ->The **Migration** is not available for users of Office 365 operated by 21Vianet in China. It is also not available for users of Office 365 with the German cloud using the data trustee, *German Telekom*. However, it is supported for users in Germany whose data location is not in the German data center. +> [!NOTE] +> The **Migration** is not available for users of Office 365 operated by 21Vianet in China. It is also not available for users of Office 365 with the German cloud using the data trustee, *German Telekom*. However, it is supported for users in Germany whose data location is not in the German data center. diff --git a/docs/apis/migration-api-overview.md b/docs/apis/migration-api-overview.md index 38f918a43..d09416b7e 100644 --- a/docs/apis/migration-api-overview.md +++ b/docs/apis/migration-api-overview.md @@ -1,1462 +1,131 @@ --- -title: "SharePoint Online Import Migration API" -ms.author: jhendr -author: JoanneHendrickson -manager: pamgreen -search.appverid: MET150 -description: "This document is to give more in depth information about how to use the SPO Migration API." -localization_priority: Priority +title: "SharePoint Import Migration API" +description: "This article provides an overview of how to use the SharePoint Migration API." +ms.date: 07/16/2025 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration --- -# SharePoint Import Migration API (CreationMigrationJob) +# SharePoint Migration API Introduction -## API Documention +The SharePoint Migration API imports content into SharePoint at scale. It processes content and manifest packages as jobs in a queue. The API provides process status and logs, making it easy to monitor the progress of each migration job. -The following API description is based upon use of the SharePoint Client Side Object Model (CSOM). We do recommend using NuGet packages when you reference CSOM in your solution. You can find latest version of the SharePoint Online CSOM package from the NuGet library using id of `Microsoft.SharePointOnline.CSOM`. +Use Migration API to migrate content from file shares, SharePoint Server, and other cloud-based services. -> [!NOTE] -> You can find latest version of the SharePoint Online Client Side Object Model from [NuGet gallery](https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM/). +## What's new ->[!NOTE] ->The **SharePoint Migration Tool** is not available for users of Office 365 operated by 21Vianet in China. It is also not available for users of Office 365 with the German cloud using the data trustee, *German Telekom*. However, it is supported for users in Germany whose data location is not in the German data center. +### December 2024 -## Methods +We applied quota on *Share with Me* items per user. Check [ShareWithMe event quota](/sharepoint/dev/apis/migration-api-shared#quota) for more detail. -### CreateMigrationJob +### November 2024 -This method creates a new migration import job and queues it up for later processing by a separate timer job. The job will consume a well formed (pre-defined format) import package that is located in the Azure Blob Storage Containers specified in this method. The SLA for migration job processing is be controlled through pre-configured queue and work load throttling settings, and there is no guaranteed SLA or return time for a submitted job. +We enabled logging all file-level events during migration, such as file deletion, to support auditing. -#### Syntax +### July 2024 -```csharp -public Guid CreateMigrationJob( - Guid gWebId, - string azureContainerSourceUri, - string azureContainerManifestUri, - string azureQueueReportUri) -``` +We started enforcing HTTPS connections to SharePoint-provided Azure Blob Storage Containers by adding a `spr=https` field in SAS tokens. This enforcement will be fully effective on July 21, 2024. Check [Use Azure Blob Storage Containers and Azure Queues with SharePoint Migration API](migration-azure.md) for details. -#### Parameters +### April 2024 -##### gWebID +We added new fields in `JobEnd` events to indicate the count and bytes imported for files. Check [Migration events in Azure Queue](migration-events.md#jobend-import) for details. -The unique identifier of the destination web targeted for the package import. Addition information and identifiers for the import are specified within the import package itself. This identifier can be found programmatically by querying the target web using CSOM calls. +### January 2024 -##### azureContainerSourceUri +We reformatted this document to bring clarity and correct errors. -The valid URL including SAS token for accessing the Azure Blob Storage Container which contains the binary files of type block. The SAS token must have been created with only Read and List permissions or the migration job will fail. The SAS token should at least have a lifetime that starts at from no later than when the job was submitted, until a reasonable time for successful import to have concluded.
+## Migration steps overview -The required permissions are as follows in the Azure Storage API: +Start a migration job with three steps. Check the guidance in each of the steps in this section. -```csharp - (SharedAccessBlobPermissions.Read | - SharedAccessBlobPermissions.List) -``` +### Provision the destination containers and the queue -**Note:** The change to enforce Read and List permissions on the SAS token is coming in a future build. Until then it will not be enforced. However, it is a best practice to use these values. +> [!IMPORTANT] +> Use [GetMigrationJobProgress API](migration-job-progress-api-reference.md) to retrieve migration job status. +> +> Provisioning Azure Queues for migration job status tracking is no longer required. Deprecation is planned for the second half of 2026. Until then, Azure Queues will remain available for status retrieval. -All files in the container must have at least a single snapshot applied to them to ensure that no file modification can occur from the customer during import. Any file that does not have a snapshot will be skipped during import and an error thrown, although the job will attempt to continue to import. The import pipeline will use the latest snapshot of the file available at the time of import. The following is an example of code that might be used to create a snapshot on a file after it is uploaded to Azure Blob Storage: +Use the `ProvisionMigrationContainers` method to provision the containers. Check [Use Azure Blob Storage Containers and Azure Queues with Migration API](migration-azure.md) for details. You can also use your own containers and queues if needed. -```csharp -CloudBlockBlob blob = blobContainerObj.GetBlockBlobReference(file); -blob.UploadFromStream(stm); -blob.CreateSnapshot(); -``` +### Prepare the content -> [!NOTE] -> The change to require and use the latest SnapShots on all files is coming in a future build, and until then will be ignored. +Package the contents in the defined format and upload them to Azure Blob Storage Containers as the content package. -##### azureContainerManifestUri +Check [Content package](migration-content-package.md) to see the detailed requirements. -The valid URL including SAS token for accessing the Azure Blob Storage Container which contains the block blobs for the manifest and other package describing XML files. This location will also be used for the log output. This container cannot be the same as the one used for the azureContainerSourceUri. The SAS token must have been created with only Read, List and Write permissions or the migration job will fail. The SAS token should at least have a lifetime that starts at from no later than when the job was submitted, until a reasonable time for successful import to have concluded. +### Create the manifest files -> [!NOTE] -> The change to enforce Read, List and Write permissions on the SAS token is coming in a future build, and until then will be not be enforced, however it is best practice to use these values. If an issue arises using a current build, try removing the List permission as a temporary workaround, noting that it will become required soon. +Based on the contents, create manifest files in XML format, and upload them to Azure Blob Storage Containers as the manifest package. -All files in the container must have at least a single snapshot applied to them to ensure that no file modification can occur from the customer during import. Any file that does not have a snapshot will cause failures during import and errors thrown, potentially failing the entire migration job. +Check [Manifest files](migration-manifest.md) to see the detailed requirements. -> [!NOTE] -> The change to require and use the latest SnapShots on all files is coming in a future build. Until then they will be ignored. +### Use Migration API to start the migration and get status -##### azureQueueReportUri +The `CreateMigrationJob` method creates a migration job, which is queued up for processing. Migration API manages the queue and returns status and logs. Use the `CreateMigrationEncrypted` method to migrate encrypted contents. Check [SharePoint Migration API Reference](migration-api-reference.md) for details. -The valid URL including SAS token for accessing the user provided Azure Queue used for returning notifications of migration job progress. This value can be null if no notification queue will be used during import. If this value is not null and proper access is granted in the SAS token in this URI, it will be used for real time status update. The SAS token must have been created with only Add, Read and Update permissions or the migration job will be unable to add events to the queue. The required permissions are as follows in the Azure Storage API: +> [!IMPORTANT] +> Use GetMigrationJobProgress API to track migration job status. - (SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update) +Upon creation of a new migration job, Migration API returns the Job ID. Track the status of the import with [GetMigrationJobProgress API](migration-job-progress-api-reference.md). -Once accepted, the job ID will be written to the notification queue if it was provided and access is valid. The notification queue can be used for multiple migration jobs at the same time, as each job will identify itself in values sent back to the notification queue. +Migration API generates logs in the manifest container. Check the log entries for migration results. -#### Return values +Migration API also generates logs of file-level activities performed by migration. The supported file-level activities include FileUploaded, FileDeleted, FileRenamed, FileMoved. Check M365 Admin Center for activity details when needed. -The unique identifier for the migration job is returned if the job is successfully queued, or if unsuccessful, a null value will be returned. The migration job unique identifier can be used to query the migration job status while it is in the queue or being processed by using the GetMigrationJobStatus method. +## Best Practice -**Example:** +### Use app-based authentication -```csharp -Guid MigrationJobId = TargetSite.CreateMigrationJob( - TargetWebId, - azureContainerSourceUri, - azureContainerManifestUri, - azureQueueReportUri); -``` +Migration generates workload to the SharePoint backend differently from end user-generated traffic. To properly allocate resources with our elastic capability, only use app-based authentication in your migration solution. -### GetMigrationJobStatus +Don't use user mode in your migration solution. Running migration in user mode triggers increased throttling, resulting in poor performance. -This method queries the queue status for the specified migration job. It is an optional check after calling the CreateMigrationJob method. Once the migration job has completed, it will no longer show up in the queue and the notification queue and/or log output should be checked for detailed status. +To learn more about how to register an app ID and how to implement app-based authentication, check [How to register an app ID](/azure/active-directory/develop/active-directory-v2-registration-portal) and [Microsoft Graph Auth guidance](/graph/auth). -#### Syntax +### Microsoft Entra ID Permissions -```xml -[ClientNS.ClientCallableMethod] -public SPMigrationJobState GetMigrationJobStatus(Guid MigrationJobId) -``` +Microsoft Entra ID provides two types of permission: Delegated Permission and Application Permissions. Check[ +Permissions and consent in the Azure Active Directory v1.0 endpoint](/azure/active-directory/develop/v1-permissions-and-consent) for details. -#### Parameters +For SharePoint and OneDrive migration scenarios, follow the Microsoft Entra ID permission specification. -##### Id +For migration tools that rely on end-user sign-in and presence, use Delegated permission. -The unique identifier of the migration job returned from CreateMigrationJob method. +For service-based migration tools that run without a signed-in user present, such as applications that run as background services, use Application permission. -#### Return values +### App IDs -The migration job status is returned using a SPMigrationJobState object if the job is found in the queue, or if unsuccessful, a value of none (0) will be returned. +You can choose to share a single App ID to cover multiple migration solutions created or create an individual App ID for each of the products. Make sure to register App IDs. Sharing App IDs doesn't affect performance or throttling. -**Example** +### Keep destination SharePoint Site unactivated -```csharp -SPMigrationJobState CurrentJobState = TargetSite.GetMigrationJobStatus(MigrationJobId); -``` -  -## Enumerations +To avoid migration issues, deactivate the target site for users until migration completion. The source could remain active, allowing read and write access to keep productivity. Switch users to the new SharePoint destination sites after migration completion. -### SPMigrationJobState +## Performance -SPMigrationJobState is an enumeration that tracks possible major states in the import queue. +Migration API processes jobs through a queue mechanism with preconfigured workload management settings. Migration API processes the jobs on a best-effort basis, without Service Level Agreement (SLA) or guaranteed performance. -#### Members +### Optimize migration performance -|**Member name**|**Description**| -|:-----|:-----| -|None |Migration job is currently unknown to the queue, either through completion and removal, or invalid job identifier. Value=0.| -|Queued |Migration job is currently known by the queue and not being processed. Value=2.| -|Processing |Migration job is currently known by the queue and is being actively processed. Value=4.| -  -## Import Package Structure +In order to ensure optimal performance for your migration projects, it's important to plan carefully, especially when dealing with large-scale migrations. For more information on how to estimate timespans and optimize performance, see our [performance guide](/sharepointmigration/sharepoint-online-and-onedrive-migration-speed). -Package structure is based on a constrained version of the Content Deployment package schema. Documentation for the original full schema can be found at [docs.microsoft.com](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). Until published on docs.microsoft.com, the constrained structure can be found in this document in the appendix. +### I'm seeing throttling messages -|XML file |Schema File |Description -|:-----|:-----|:-----| -|ExportSettings.XML|DeploymentExportSettings Schema |Provides validation for the ExportSettings.XML file exported into the content migration package. ExportSettings.XML does the following:
- Contains the export settings specified by using the SPExportSettings class and other classes that are part of the content migration object model.
- Ensures that the subsequent import process (at the migration target site) enforces the directives specified in the export settings.
- Maintains a catalog of all objects exported to the migration package. -|LookupListMap.XML |DeploymentLookupListMap Schema |Provides validation for the LookupListMap.XML file exported into the content migration package. LookupListMap.XML maintains a simple lookup list that records SharePoint list item (list item to list item) references. -|Manifest.XML |DeploymentManifest Schema|Provides validation for the Manifest.xml file that is exported into the content migration package.Provides a comprehensive manifest containing listings of both the contents and the structure of the source site. The migration operation uses the manifest file to reconstitute the source site and its components when it is imported to the destination site.| -|Requirements.XML|DeploymentRequirements Schema|Provides validation for the Requirements.xml file exported into the content migration package. Requirements.xml maintains list of deployment requirements in the form of installation requirements on the migration target, such as feature definitions, template versions, Web Part assemblies, language packs, and so forth.| -|RootObjectMap.XML|DeploymentRootObjectMap Schema|Provides validation for the RootObjectMap.xml file exported into the content migration package.RootObjectMap.xml maintains a list of mappings of secondary (dependent) objects, which allows the import phase of the migration operation to correctly place the dependent objects relative to the locations of the root object mappings.| -|SystemData.XML|DeploymentSystemData Schema|Provides validation for the SystemData.xml file exported into the content migration package.SystemData.xml does the following: Collects a variety of low-level system data. Records the number and names of Manifest.xml files (in cases where the migration uses multiple manifests).| -|UserGroupMap.XML|DeploymentUserGroupMap Schema|Provides validation for the UserGroup.xml file exported into the content migration package. UserGroup.xml maintains a list of users and user security groups with respect to access security and permissions.| -|ViewFormsList.XML|DeploymentViewFormsList Schema|Provides validation for the ViewFormsList.xml file exported into the content migration package.ViewFormsList.xml maintains a list of Web Parts and tracks whether each is a view or form.| +To ensure good user experiences for all Microsoft 365 customers, SharePoint uses throttling to protect the SharePoint infrastructure. Avoid getting throttled by following [throttling guidance](https://aka.ms/spo429). -### Content structure +## Special articles -File content that is referenced within the manifest of the package structure must be stored in either a flat or hierarchical structure within the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerSourceUri` parameter. For example, import packages generated form a legacy version export will not be hierarchical, and will instead have all files stored at the root level with a pattern like ########.dat where the # symbols are hexadecimal characters starting at 0 and no file names are repeated within a package. Alternately, a package generated from a file share can have the source folder hierarchy and file names preserved in the same hierarchy. +### Migrating sharing events of files and folders -The main requirement for the structure is that the FileValue references in the **Manifest.XML** file must refer to the exact name and physical hierarchy that the content is stored in within the Azure Blob Store location for import. The destination file names and folder hierarchy from the import operation are not directly related to the physical naming and hierarchy and are instead defined through the **Manifest.XML** file. - -### ExportSettings.XML - -The **ExportSettings.XML** file is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerManifestUri` parameter. This required file is validated using the constrained DeploymentExportSettings.XSD, which has some limited changes from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -The main requirement is that the ExportSettings `SiteUrl` value must be populated with a URL consistent with the source URL used for the rest of the import package. In the case of file shares as a source, the URL would be pre-specified to be the source URL in the rest of the package, whereas a package generated through an export operation at a source site would be its original source site collection URL. - -### LookupListMap.XML - -The **LookupListMap.XML** file, if included, is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s azureContainerManifestUri parameter. This optional file is validated using the constrained **DeploymentLookupListMap.XSD**, which has no change from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -Since an import package for the pipeline does not include defining fields or views on a list or document library, the **LookupListMap.XML** file will normally include no child nodes under the root and as such can also be excluded from the package if not required, although a warning may be logged in this case. - -### Manifest.XML - -All instances of the **Manifest.XML** file for a package are expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerManifestUri` parameter. This required file is validated using the constrained **DeploymentManifest.XSD**, which has multiple major changes and significant reduction in types from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -The **Manifest.XML** is the primary descriptor for metadata within the package, and provides the list/folder/item hierarchy, along with metadata for the items including references back to users and groups defined in the **UserGroupMap.XML** file. There may be more than one **Manifest.XML** file (which can be identified using different file names to uniquely identify them), and all are found by the import pipeline through references within the **SystemData.XML** file’s ManifestFile entries. - -The main requirements for **Manifest.XML** to be possible to successfully import through the pipeline is that the Web Id and Document Library ID/List ID be consistent with the target location. If a Web ID is used which doesn’t match the target location, errors will occur because the parent web for the import operation cannot be found. - -Likewise, an incorrect Document Library ID/List ID will prevent the importation into the target Document Library or List. IDs should never be reused within the same site collection, so same packages should not be imported to the same target site collection regardless of the destination web. - -For individual files and folders within the document library or list, their identifiers should be consistent between import events to the same location. Specifically, performing an import of a package generated form a file share would initially require generating new GUIDs for each file and folder, along with matching GUIDs for the list items that represent them. Therefore, performing a second import against the same target using the same package would keep the same IDs, but performing a second import against the same target using a new package for the same content would result in ID conflicts and import errors for all items in conflict. - -The initial generated package from a file share is effectively a form of record for the original generated IDs and can potentially be used as a reference for follow up package generation to prevent ID collisions when unintended, and to allow like IDs to ensure correct overwrite, deletion or move activities. - -### Requirements.XML - -The **Requirements.XML** file is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s azureContainerManifestUri parameter. This optional file is validated using the constrained DeploymentRequirements.XSD, which has no change from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -For file shares this is expected to normally include no child nodes under the root and as such can also be excluded from the package if not required, although a warning will be logged in this case. - -### RootObjectMap.XML - -The **RootObjectMap.XML** file is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerManifestUri` parameter. This required file is validated using the constrained **DeploymentRootObjectMap.XSD**, which has some limited changes from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). The most common `RootObject` that will be included will be a single object of type List. The Id for this item should be the List Id for the target list, and the `ParentWebID` should match the Id of the parent target web containing this list in order for migration to be successful. The Id, WebUrl and Url values of this object must also match the related structure laid out in the **Manifest.XML** file. - -### SystemData.XML - -The **SystemData.XML** file is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerManifestUri` parameter. This required file is validated using the constrained **DeploymentSystemData.XSD**, which has no change from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -The `SchemaVersion` information is expected to reference the current Build and DatabaseVersion of the target farm, a Version of “15.0.0.0”, and the `SiteVersion` value is expected to always match the target site collection `UIVersion` (i.e. most commonly this will be “15”). Each **Manifest.XML** file for the package is expected to be listed in this file within the `ManifestFile` entries. - -The SystemObjects that define dependent objects that should remain immutable by the migration code should also be listed here to ensure correct behavior of the import operation. The following is an example of the common objects in the **SystemObjects.XML** file from a file share based import, noting that the IDs are expected to be different for each package, and the URLs may be different. - -#### Table 1: Example SystemData.XML file - -```xml - - - - - - - - - - - - - - -``` - -### UserGroupMap.XML - -The **UserGroupMap.XML** file is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerManifestUri` parameter. This required file is validated using the constrained **DeploymentUserGroupMap.XSD**, which has no change from current published full 2013 package schema. - -The **UserGroupMap.XML** file may not contain any User or Group entries but doing so will prevent author or security information from being populated during import and warnings will be logged in this case. Login and SID values for users must be either adjusted to match the values in SharePoint Online, or if the account no longer should exist can be listed as `IsDeleted = “true”` to prevent lookup failures and additional slowdown during the import operation. - -### ViewFormsList.XML - -The **ViewForms.XML** file, if included, is expected to be at the root of the Azure Blob Store Container defined by the CreateMigrationJob’s `azureContainerManifestUri` parameter. This optional file is validated using the constrained **DeploymentViewFormsList.XSD**, which has no change from current published full 2013 package schema. - -Since an import package for the pipeline does not include defining fields or views on a list or document library, the **ViewFormsList.XML** file will normally include no child nodes under the root and as such can also be excluded from the package if not required, although a warning may be logged in this case. - -## Logging - -The logs that the import pipeline creates must be easily parsed by machine with a goal of being able to pinpoint when and where failures occur, including errors and warnings, and will tell the consumer or the ISV where and why the failure occurred. As the import is processed by the import pipeline, the job results are placed into log files at the server side file system. - -Upon completion, these logs will be copied to the `azureContainerManifestUri` location as the SAS token specified in the URI allows write access. The same output logs are also placed at the *“_catalogs/Maintenance Logs”* location of the target site collection as a text file. The logs will only be copied to the destination locations once the job has finished and removed from the queue. - -Several log types can be included such as the full import log, along with warning and error files that contain only the subset of import warnings or errors respectively. Log files have unique `datetime` and `job id` stamps to allow each attempted import event to have a unique log for better debugging purposes. -  -## Changes for those using the "Ship Disk" option - -To use the Migration API, you must have a temporary storage container in Azure. When uploading files into the temporary storage, an MD5 is required as a property on every file. However, when shipping the data on hard drives this MD5 property doesn’t get assigned automatically. As a work around, we have adapted the Migration API to allow the MD5 to be passed for every file as part of the manifest. This also applies for IV values when encrypting the data. - -Since the MD5 is generated at the source instead of at the upload time in Azure, Microsoft can confirm the integrity of the file directly against the source MD5. - -### What is stored in those Azure Blob Containers? - -The Migration API requires the Azure Container for content passing and also for log and queue reporting. It can be split down as a summary as follows:
- -|**Content**|**Manifest**| -|:-----|:-----| -|Files and folders|XML files| - - -There are two new optional parameters in manifest.xml: - -- MD5Hash
-- InitializationVector - - -#### Preparing the package -The method for calling the migration job doesn’t change; only the package generation needs to be changed. - -In the Manifest container one file is named Manifest.xml. There are 2 optional attributes added to the file node: *MD5Hash* and *InitializationVector*.
- -Example: - -```xml - -``` - -## Best Practices and Special Mentions - -### Package size - -Even if the API support 15GB files, we recommend package sizes of up to 250 MB OR 250 items (depending which one comes first). If you have one large files larger than that recommended size limit you should send it in its own package. The same applies to versions; each version counts against the size limit and item count. Additionally all the versions of a file should be in the same package. - -### File size - -Currently the import pipeline supports individual files of **15 GB** maximum size. - -### Only un-compressed packages are supported - -The import pipeline does not support compressed packages. The file content must be stored in a different Azure Storage container from the manifest and related descriptive XML files. This decision was made to prevent the overhead of processing time on both ends of the migration (to compress and decompress), and also to ease package creation and modification. Compression of individual files such as into zip archives is supported as long as they are referenced in the import package as the archive itself, not the contents. - -### API supports import of multiple file versions - -Import packages can have references to multiple versions of a file, major and minor, up to regular limits imposed within SharePoint. It is important that each version of that file be included in the package even if some of the versions already exist in SPO. - -### API supports preservation of identifiers - -The identifiers used within the import package explicitly are used during import to identify content. This allows preservation of existing identifiers for document library contents from a source environment. However, it also imposes a complexity during import package creation or transformation that mandates that the package explicitly reference the target web and list identifiers. Content type identifiers, file/folder item GUIDs, and list item integer identifiers are all preserved during import. If incorrect identifiers are specified in the package, import will fail. - -Additionally, due to identifier preservation, import events can potentially be done in successive iterations using different packages, allowing items to potentially move in location if their identifiers have not changed. - - - -### This is an overwrite API - -The import pipeline does support import of versioning data on files and list item metadata, but as of now if you submit a file and then resubmit the same file with changes the import process will delete and replace the original and all versions with the ones included in the ones in the current package being imported. - -### We do not support Active-Active scenario - -This means we expect that the target site will remain non-active for users until the migration is over. The source may be kept in a read write state until the final migration event, as a method of reducing downtime for end users, but once the migration is complete there should be a switch for the users to start using their new SPO destinations and stop using the previous repository. - -### Permissions in Azure - -To ensure immutability of source blobs, the import pipeline will accept a SAS key with only the Read and List access flags set for the File container. Likewise, the import pipeline requires a SAS key with Read, List and Write access for the Manifest container so that we can write back log files at the end of the import operation. If these criteria are not met, the pipeline will reject it during job creation. - -### All files in Azure must have snapshot created to import successfully - -To prevent unintended file modification of the source blobs, the import pipeline will only import files if they have a snapshot created for them within Azure. If they do not, then the import pipeline will skip the files in this state and throw errors. The import pipeline will use the latest snapshot of the file available at the time of import. - -### Security and encryption - -The import pipeline is using Azure Blob Storage security model as is. This means we will not do any special treatment for those azure containers that would differentiate from any other azure containers. Additionally, the import pipeline currently does not accept encryption keys for content from the customer. Any encrypted content will be treated as opaque files that SharePoint may list, but be unable to index, the same as if encrypted files were uploaded through the UI to the environment. - -### Events and event handlers - -The import pipeline allows event handlers to be referenced on list items but doesn’t allow defining event handlers at the list level at this time. The import pipeline does not fire events as items are imported, so existing event handlers will not fire due to the import event. - -### Resolving Users - -If the Migration API was unable to resolve a user using the login provided in the UserGroup.xml and no System ID is provided, then: -a) This user will be replaced by “System Account” in the associated metadata within the package ( author, editor etc.). -b) A warning will be reported in the ImportLogs – “Failed to ensure user 'user@contoso.com'” - -If the migration API was unable to resolve a user using the login provided in the UserGroup.xml and the System ID is provided (which is the SID for the user in the on-premises AD), then: -a) A new deleted user with the provided login and SystemId is created and is used in the associated metadata within the package. -b) A warning will be reported in the ImportLogs- “Failed to retrieve user 'user@contoso.com' attributes from the SiteUsers; falling back to passed in values” - - -## Appendices - -### Acronyms Defined - -|Acronym|Definition| -|:-----|:-----| -|BOT |SharePoint server running timer jobs| -|CDB |Content database, containing site collections and content| -|CFE |Content farm front end server| -|SPO |SharePoint Online| -|ABS |Azure Blob Storage| -  -### Helpful Resources - -* [SharePoint Online Client Components SDK](https://www.microsoft.com/download/details.aspx?id=42038) - -* [Azure Windows Azure SDK for .NET - 2.4](https://www.microsoft.com/download/details.aspx?id=43709) - -* [Bulk Creation of OneDrive for Business sites](https://msdn.microsoft.com/library/office/jj163783(v=office.15).aspx) - -* [Restrictions and limitations when you sync SharePoint libraries to your computer through OneDrive for Business](https://support.office.com/article/restrictions-and-limitations-when-you-sync-files-and-folders-7787566e-c352-4bd4-9409-fd100a0165f6) - -* [Types of files that cannot be added to a list or library](https://support.office.com/Article/Types-of-files-that-cannot-be-added-to-a-list-or-library-30be234d-e551-4c2a-8de8-f8546ffbf5b3?ui=en-US&rs=en-US&ad=US) - -  -## Working with import package security structures - -This section covers a brief overview of what is contained within an export package that includes security with regard to permissions. This can allow the system to determine user and group membership along with roles, and specific assignments (unique permissions set at the object level and its children unless overridden at a deeper child object). - -### How to interpret the security identifiers in the package files - -UserGroup.xml file defines all users and groups within the exported web(s). The items within this file do the following: - -- User objects include the information about specific users, including identification of a specific security principle as a domain group or not, login, and the base 64 encoded SystemId (SID) of the security principle. -- Group objects include the information about specific groups and the direct membership list of that group. -- Owner values on group objects and UserId values on member objects within group objects map to other Id values of other user or group objects respectively. - -#### Table 2: Users and Groups annotated in UserGroupMap - -```xml - - - - - … - - - - - - - - - - … - - -``` - -**Manifest.xml** contains the metadata about all the content within the exported web(s). The items within this file do the following: - -- Roles objects include the list of defined roles on the web. -- Role objects define the individual role, including ID, internal permissions rights mask flags and display information. - - RoleId values define the identifiers of the Role objects. - - PermMask values contain the rights mask flags. -- RoleAssignments objects include the list of unique permissions (RoleAssignment objects). -- RoleAssignment objects include the list of distinct Assignment objects (if any). -- Individual RoleAssignment objects contain the actual membership of one distinct user or group and their actual Role. - - RoleId values map to the RoleId values of the Role objects. - - PrincipalId values map to Id values of user or group objects respectively in UserGroups.xml. - -#### Table 3: Roles and RoleAssignments annotated in manifest - -```xml - - … - - - - - - - - - - - - - - … - - - … - -``` - -## Constrained XSD structures - -Included below are the XSD files used for package validation in the import pipeline, when different than the original 2013 full schema which can be found at [official SharePoint documentation](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -### DeploymentExportSettings.XSD - -#### Table 4: Constrained DeploymentExportSettings.XSD - -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - - - -### DeploymentLookupListMap.XSD -There is no change from current published full 2013 package schema. - -### DeploymentManifest.XSD - -##### Table 5: Constrained DeploymentManifest.XSD - -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - - - -### DeploymentRequirements.XSD - -There is no change from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -### DeploymentRootObjectMap.XSD - -#### Table 6: Constrained DeploymentRootObjectMap.XSD - -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -### DeploymentSystemData.XSD - -There is no change from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -### DeploymentUserGroupMap.XSD - -There is no change from current published full 2013 [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -### DeploymentViewFormsList.XSD - -There is no change from current published [full 2013 package schema](https://docs.microsoft.com/sharepoint/dev/schema/content-migration-schemas). - -## Sample: Using REST to call the API - - -https://yourtenanthere.sharepoint.com/sites/importSite/_api/site/CreateMigrationJobEncrypted - -{ - "options": { - "AES256CBCKey": "000000000000000000000000000000000000000000000000000000=" - }, - "gWebId": "00000000-0000-0000-0000-000000000000", - "azureContainerSourceUri": "https://tenant.blob.core.windows.net:443/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000=rw", - "azureContainerManifestUri": "https://tenant.blob.core.windows.net:443/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000=rw" -} - -For the container -https://yourtenanthere.sharepoint.com/sites/importSite/_api/site/ProvisionMigrationContainers - - ->[!NOTE] ->The **Migration API** is not available for users of Office 365 operated by 21Vianet in China. It is also not available for users of Office 365 with the German cloud using the data trustee, *German Telekom*. However, it is supported for users in Germany whose data location is not in the German data center. +Check [Sharing events](/sharepoint/dev/apis/migration-api-shared) article for instructions when migrating shared events metadata with files and folders. +### Web Parts +Use SharePoint Migration Tool (SPMT)'s Web Part serializer DLL to migrate Web Parts into SharePoint. Check [Migrate Web Parts](/sharepoint/dev/apis/migrate-webparts-with-migrationapi) for instructions. diff --git a/docs/apis/migration-api-reference.md b/docs/apis/migration-api-reference.md new file mode 100644 index 000000000..0db09f400 --- /dev/null +++ b/docs/apis/migration-api-reference.md @@ -0,0 +1,232 @@ +--- +title: "SharePoint Migration API Reference Guide" +description: "This article provides in-depth information on how to use the SharePoint Migration API." +ms.date: 07/16/2025 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- + +# SharePoint Migration API Reference Guide + +This guide describes the usage of SharePoint Migration API, which imports content into SharePoint, based on manifest files. + +## CSOM and REST + +Migration API supports both SharePoint Client Side Object Model (CSOM) and REST. + +### Use NuGet Packages with CSOM + +To reference the SharePoint Client Side Object Model (CSOM) in your solution, use NuGet packages. + +Manage dependencies easily and ensure your solution is using the latest version of the CSOM library with NuGet packages. + +Get the latest version of the CSOM package at the [SharePoint Client-side Object Model Libraries](https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM) with the ID `Microsoft.SharePointOnline.CSOM`. + +Check [Get to know SharePoint REST service](/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service) for instructions on REST API. + +## CreateMigrationJob method + +Creates a new migration import job with the import package specified in `azureContainerSourceUri` parameter. + +### CreateMigrationJob syntax + +```csharp +public Guid CreateMigrationJobEncrypted( +Guid gWebId, +string azureContainerSourceUri, +string azureContainerManifestUri, +string azureQueueReportUri, +EncryptionOption AES256CBCKey +) +``` + +```rest +POST https://{site_url}/_api/site/CreateMigrationJobEncrypted +{ + "options": { + "AES256CBCKey": "000000000000000000000000000000000000000000000000000000=" + }, + "gWebId": "00000000-0000-0000-0000-000000000000", + "azureContainerSourceUri": "https://tenant.blob.core.windows.net:443/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000=rw", + "azureContainerManifestUri": "https://tenant.blob.core.windows.net:443/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000=rw" +} +``` + +### CreateMigrationJob parameters + +#### gWebID + +Required. + +A **String** value that contains the unique identifier of the destination web targeted for the package import. The import package itself specifies additional information and identifiers for the import. You can programmatically find this identifier by querying the target web using CSOM calls. + +#### azureContainerSourceUri + +Required. + +A **String** value that contains the valid URI, including the SAS token, to access the Azure Blob Storage Container that contains the binary files of type block. + +See [Use Azure Blob Storage Containers and Azure Queues with SharePoint Migration API](migration-azure.md) for instructions on using Azure Blob Storage Containers in migration. + +When using content containers not provided by this method, Migration API requires `Read`, and `List` permissions only. Ensure that the start time of the SAS token is set at or before the job submission. Also, when setting the expiration time, allow a reasonable duration for the import process to complete. + +Migration API doesn't require `List` permission from containers provisioned with `ProvisionMigrationContainers` method. + +#### azureContainerManifestUri + +Required. + +A **String** value that contains the valid URI, including the SAS token, to access the Azure Blob Storage Container, which contains the block blobs for the manifest and other packages describing XML files. Migration API writes log to this container. This container can't be the same as the one used for the `azureContainerSourceUri`. + +See [Use Azure Blob Storage Containers and Azure Queues with SharePoint Migration API](migration-azure.md) for instructions on using Azure Blob Storage Containers in migration. + +When using content containers not provided by this method, Migration API requires `Read`, `List`, and `Write` permissions only. Ensure that the start time of the SAS token is set at or before the job submission. Also, when setting the expiration time, allow a reasonable duration for the import process to complete. + +#### azureQueueReportUri + +Optional. + +A **String** value that contains the valid URL, including the SAS token, to access the user-provided Azure Queue for migration job progress. Use `null` if receiving import status updates isn't necessary. + +If this value isn't `null`, and the SAS token contains the correct permissions, Migration API writes import status updates to the queue at the URL provided. + +Share the notification queue among multiple migration jobs. Migration API identifies each job with unique Job ID values in the notification queue. + +See [Azure](migration-azure.md) for instructions on using Azure Queue in migration. Check [Migration events in Azure Queue](migration-events.md) for types of events. + +Requires `Add`, `Read`, and `Update` permissions only. If the SAS token has other permissions, the migration job will be unable to add events to the queue. + +### CreateMigrationJob return value + +#### Job ID + +A **Guid** value, which contains Job ID, the unique identifier of the migration job. The method returns a `null` value, if it fails to create the job. Use Job ID to query the status of migration jobs with `GetMigrationJobStatus` method. + +### Example + +```csharp +Guid MigrationJobId = TargetSite.CreateMigrationJob( +TargetWebId, +azureContainerSourceUri, +azureContainerManifestUri, +azureQueueReportUri); +``` + +## CreateMigrationJobEncrypted method + +Creates a new migration import job with an encrypted PRIME package. + +Check the encryption instructions in [Azure](migration-azure.md) for Azure Blob Storage Container and Azure Queue encryption used. + +### CreateMigrationJobEncrypted syntax + +```csharp +public Guid CreateMigrationJobEncrypted( +Guid gWebId, +string azureContainerSourceUri, +string azureContainerManifestUri, +string azureQueueReportUri, +EncryptionOption AES256CBCKey +) +``` + +```rest +POST https://{site_url}/_api/site/CreateMigrationJobEncrypted +{ + "options": { + "AES256CBCKey": "000000000000000000000000000000000000000000000000000000=" + }, + "gWebId": "00000000-0000-0000-0000-000000000000", + "azureContainerSourceUri": "https://tenant.blob.core.windows.net:443/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000=rw", + "azureContainerManifestUri": "https://tenant.blob.core.windows.net:443/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000=rw" +} +``` + +### CreateMigrationJobEncrypted parameters + +`gWebID`, `azureContainerSourceUri`, `azureContainerManifestUri`, and `azureQueueReportUri` parameters have the same requirements as in `CreateMigrationJob` method. + +Provide `EncryptionOption` parameter as instructed below. + +#### EncryptionOption + +Required. + +A `EncryptionOption` object, containing the AES256CBCKey used to decrypt the output. + +Migration API encrypts the output with the AES256CBCKey key supplied. + +See `[EncryptionOption](https://learn.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.client.encryptionoption)` class for details. + +### CreateMigrationJobEncrypted return value + +See Return value in `CreateMigrationJob` method. + +## GetMigrationJobStatus method + +> [!IMPORTANT] +> Use [GetMigrationJobProgress API](migration-job-progress-api-reference.md) to retrieve migration job status. Deprecation of GetMigrationJobStatus API is planned for the second half of 2026. Until then, it will remain available for status retrieval. + +Retrieves the processing status for a designated migration job. + +Migration API removes completed migration jobs from the timer job queue. Check the notification queue and/or log outputs for import results. + +### GetMigrationJobStatus syntax + +```csharp +[ClientNS.ClientCallableMethod] +public SPMigrationJobState GetMigrationJobStatus(Guid MigrationJobId) +``` + +### GetMigrationJobStatus parameters + +#### ID + +Required. + +A **Guid** value, which contains the migration Job ID, is returned from `CreateMigrationJob`. + +### GetMigrationJobStatus return value + +A `SPMigrationJobState` object, which contains the status of the migration job. + +### GetMigrationJobStatus example + +```csharp +SPMigrationJobState CurrentJobState = TargetSite.GetMigrationJobStatus(MigrationJobId); +``` + +## SPMigrationJobState enumeration + +Contains members representing the status of migration jobs in the import queue. + +### SPMigrationJobState members + +#### None + +Value: 0 + +The queue doesn't contain the migration job with the Job ID. The possible reasons are: + +- Migration API has completed the job and removed it from the queue. +- The Job ID is invalid. + +#### Queued + +Value: 2 + +The queue contains the migration job. Migration API isn't processing the job. + +#### Processing + +Value: 4 + +The queue contains the migration job. Migration API is processing the job. diff --git a/docs/apis/migration-api-shared.md b/docs/apis/migration-api-shared.md index 964cf3187..dfcc26fd9 100644 --- a/docs/apis/migration-api-shared.md +++ b/docs/apis/migration-api-shared.md @@ -1,76 +1,84 @@ --- title: "SPO Migration API: Migrating shared files and folders" -ms.author: jhendr -author: JoanneHendrickson -manager: pamgreen -ms.topic: article description: "Migrating shared files and folders using item references." ---- - - +ms.date: 06/28/2022 +ms.author: jihongzuo +author: shiongzuo +manager: Dan.Podeanu +ms.topic: article +ms.subservice: migration-tool +--- # Migrating shared files and folders ## Implementation As documented in the Migration PRIME API, apply sharing metadata by using **item references**. The older method of using the *Shared With* column should not be used any further. -For an item that is shared with a user, add the **SharedWithEvents** block within its *ListItem* block. The **SharedWithEvents** block represents an occurrence when the item was shared, including the user who did the sharing (SharingInitatiorId and SharedById), as well as the time of sharing (SharedTime). +For an item that is shared with a user, add the **SharedWithEvents** block within its *ListItem* block. The **SharedWithEvents** block represents an occurrence when the item was shared, including the user who did the sharing (SharingInitatiorId and SharedById), as well as the time of sharing (SharedTime). Add a SharedWithMember block for each person that the item was shared with during that occurrence. All user ids must be valid entries in the UserGroup.xml. ```XML - - - - - - - - - - + + + + + + + + + + ``` + ## Best Practices + ### The basics + For each file or folder that was shared with a user in the source, create an item reference for that item in the recipient’s OneDrive. Every item reference created will appear in the user’s *Shared with Me* view in OneDrive. Remember to give the user permission to access the item as well. ### Inheritance -Be sure to use inheritance correctly for sharing. When creating an item reference for a file or folder, check if its parent folder (or higher) already has an item reference created for it. If so, do not create another one for the child item. This will prevent users from seeing duplicate items in their *Shared with Me* view and reduce migration and service load as well. -**Example:** When a folder is shared and the recipient can access all of the folder’s contents, an item reference should *only* be created for the shared folder -- not for its contents. The only item that should appear in the recipients *Shared with Me* is the shared folder. +Be sure to use inheritance correctly for sharing. When creating an item reference for a file or folder, check if its parent folder (or higher) already has an item reference created for it. If so, do not create another one for the child item. This will prevent users from seeing duplicate items in their *Shared with Me* view and reduce migration and service load as well. + +**Example:** When a folder is shared and the recipient can access all of the folder’s contents, an item reference should *only* be created for the shared folder -- not for its contents. The only item that should appear in the recipient's *Shared with Me* is the shared folder. -This same guidance should also be used for permissions (ACLs). Only apply permissions on a child item where the required permissions are different than its parent item. Make sure not to exceed 5000 unique ACLs on a site. It may be useful to check how many ACLs you create and warn the user prior to migration. There is also a hard limit of 50,000 unique ACL's that will be enforced. If you are close to reaching the 5000 limits, we recommend that the permission model be simplified on the source before migration. +This same guidance should also be used for permissions (*access control lists, also known as ACLs*). Only apply permissions on a child item where the required permissions are different than its parent item. Make sure not to exceed 5000 unique ACLs on a site. It may be useful to check how many ACLs you create and warn the user prior to migration. There is also a hard limit of 50,000 unique ACLs that will be enforced. If you are close to reaching the 5000 limits, we recommend that the permission model be simplified on the source before migration. ### Sharing with groups + For items shared with a group of individuals in the source, the content may be migrated into a shared library (eg. a team site) in which all of those individuals are given access. ### Anonymous sharing links + Do not migrate anonymous sharing links from the source; this is not useful as it’s not possible to know which users used that link in the source. Users should evaluate whether anonymous links are still needed and create new ones on the destination if so. ### Sharing with external users -Before starting migration, you must ensure all users are provisioned in the customer tenant. For users external to the tenant (ie. from a different organization), provision them as B2B collaboration users in Azure Active Directory. This is done in the Azure portal following these steps: -- [Add Azure Active Directory B2B collaboration users in the Azure portal](https://docs.microsoft.com/azure/active-directory/b2b/add-users-administrator). +Before starting migration, you must ensure all users are provisioned in the customer tenant. For users external to the tenant (ie. from a different organization), provision them as B2B collaboration users in Azure Active Directory. This is done in the Azure portal following these steps: + +- [Add Azure Active Directory B2B collaboration users in the Azure portal](/azure/active-directory/b2b/add-users-administrator). Once the external users are provisioned, share files and folders with them during migration the same way as internal users. ### Permission and Sharing -The per user sharing model in SharePoint relies on both permissions and “Shared With” data references for an object to be considered shared with an individual. If a user has access to content, but no “Shared With” references, they will not see the content show up in their Shared With Me view within their OneDrive For Business site. + +The per-user sharing model in SharePoint relies on both permissions and “Shared With” data references for an object to be considered shared with an individual. If a user has access to content, but no “Shared With” references, they will not see the content show up in their Shared With Me view within their OneDrive For Business site. However, if they are indicated in “Shared With” references but do not have any access to the content, they will either never see the content show up in their Shared With Me view within their OneDrive For Business site or when they try to use a link from there it will be denied access. To preserve sharing information, both the permissions and “Shared With” references will need to be correctly set. The permissions can be set at different levels of the content hierarchy using scopes (unique ACLs), that apply to that object and any of its children unless they themselves have unique permissions. -Using PRIME, content can be migrated by using SPFile/SPFolder objects with a document library followed by SPListItem objects that reference the imported File/Folder objects. During the ListItem import, the “Shared With” references data can be imported, and then the security can be applied afterward within the same migration package, by setting up scopes (ACLs) and role assignments (ACEs) for the content hierarchy as needed. +Using PRIME, content can be migrated by using SPFile/SPFolder objects with a document library followed by SPListItem objects that reference the imported File/Folder objects. During the ListItem import, the “Shared With” references data can be imported, and then the security can be applied afterward within the same migration package, by setting up scopes (ACLs) and role assignments (ACEs) for the content hierarchy as needed. Permissions migration is performed using the DeploymentRoleAssignments object with RoleAssignment entries representing specific scopes and Assignment entries representing assignments of specific roles to specific principals. Since this code ends up breaking inheritance for content and applying the specified role assignments, it has the same limitations as using other object model approaches to setting permissions in SharePoint. +> [!NOTE] +> The **Migration API** is not available for users of Office 365 operated by 21Vianet in China. + +### Quota ->[!NOTE] ->The **Migration API** is not available for users of Office 365 operated by 21Vianet in China. It is also not available for users of Office 365 with the German cloud using the data trustee, *German Telekom*. However, it is supported for users in Germany whose data location is not in the German data center. +Do not migrate more than 1,000 *Share with Me* events for any receiver within 24 hours. If a receiver already has 1,000 *Share with Me* events being imported within 24 hours, they will NOT receive any additional *Share with Me* events during the time window. And Import API will send back warning messages indicating some *Share with Me* events have been throttled. diff --git a/docs/apis/migration-api-video-transcripts.md b/docs/apis/migration-api-video-transcripts.md new file mode 100644 index 000000000..324d77d57 --- /dev/null +++ b/docs/apis/migration-api-video-transcripts.md @@ -0,0 +1,66 @@ +--- +title: "Exporting video transcripts when using the SharePoint Import Migration API" +description: "Learn how to export videos that contains a transcript as an alternate content stream." +ms.date: 06/30/2023 +ms.author: jhendr +author: JoanneHendrickson +manager: serdars +search.appverid: MET150 +ms.subservice: migration-tool +--- + +# How to export video transcripts using the SharePoint Important Migration API + +Transcripts of video files, like those in Teams meeting recordings, are stored in a format similar to a zip file. If you are migrating videos from one source to another, you must use a new flag to ensure the entire zip file is migrated to the destination. Otherwise, you will inadvertently leave behind the alternate content stream, the transcript. + +## Step 1: Check if the file contains alternate content streams + +1. Check to see if the SPFile object has the property **SPFile.HasAlternateContentStreams**. Use the [REST or CSOM API](/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest) to fetch this property value. +3. If set to **True**, the file contains alternate content streams. + + +***Example:*** + +```powershell + +GET https://{site_url}/_api/web/GetFileByServerRelativeUrl(‘/serverrelativeurl’)/HasAlternateContentStreams + +``` + +## Step 2: Download the file with alternate content streams + +A zip formatted stream including primary and alternate streams can be downloaded if the file request includes **SPOpenBinaryOptions.GetAsZipWithAltStreamsIfAvailable**. + +1. Use [REST or CSOM API](/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest) to download the zip formatted content stream. +2. You must include **SPOpenBinaryOptions.GetAsZipWithAltStreamsIfAvailable**. If this is not specified, only the primary file content stream is returned. + +***Example:*** + +```powershell + +GET https://{site_url}/_api/web/GetFileByServerRelativeUrl(‘/serverrelativeurl’)/OpenBinaryStreamWithOptions(openOptions=1048576) + +``` +Note: In the example above, "1048576" corresponds to the integer value of enum *SPOpenBinaryOptions.GetAsZipWithAltStreamsIfAvailable*. + +## Step 3: Import the file with alternate content streams + +Use the Migration API to import the zip formatted stream for a file with alternate content streams to SPO. The main steps involved are: + + +1. Upload the zip formatted stream downloaded with *SPOpenBinaryOptions.GetAsZipWithAltStreamsIfAvailable* as the primary file to the Azure location. +2. When preparing the migration Manifest .xml file, add the property **vti_hasAlternateContentStreams** to the SPFile object with the value of **TRUE**. +3. Call the Migration API as normal. Internally, SPO will unzip the provided content stream and set the primary file stream and associated alternate content streams correctly. +4. After the import, verify the property **SPFile.HasAlternateContentStreams** to confirm if it’s set to **True**. + +***Example:*** + +```powershell + + + + + + + +``` diff --git a/docs/apis/migration-api-whats-new.md b/docs/apis/migration-api-whats-new.md new file mode 100644 index 000000000..aec43a338 --- /dev/null +++ b/docs/apis/migration-api-whats-new.md @@ -0,0 +1,73 @@ +--- +title: "Migration API What's new" +description: "Learn about the new features and updates to the Migration API." +ms.date: 09/26/2023 +ms.reviewer: jhendr +author: JoanneHendrickson +ms.author: jhendr +manager: serdars +audience: ITPro +ms.topic: article +ms.subservice: migration-tool +localization_priority: Priority +ms.custom: admindeeplinkSPO +--- +# What's new in the Migration API + +Check here to see what features or updates have been added to the Migration API. Here's a summary of what's included. + +## Encoding invalid XML characters + +When invalid XML characters are detected in relevant fields, they're encoded. For any attribute that is XML encoded, decoding is needed for the value. Encoded fields are included in `EncodedAttributes`, in a comma-separated attribute list. + +**Example** + +In this example, these attributes are encoded: URL, ParentWebURL, Name, and Version. + +```xml + +``` + +>[!Warning] +>If XSD is replied on to parse manifest files, parsing may fail when **EncodedAttributes** is used. + + +## Updated reason code and descriptions + +We have updated Migration API to provide detailed reasons in case a job is postponed. We encourage ISVs take appropriate actions, based on the reasons. + +|Possible reasons |Code|Description| +|:-----|:-----|:-----| +|JobInQueue:Resource|1,2,3,4, 5, 6, 12|The job is now in a queue for resource allocation. It is expected to start in [P75] time.| +|JobInQueue:DBMaint|7|The destination tenant's database is currently in maintenance. The job is in a queue to be executed when the maintenance is completed. We expect the maintenance to be completed at [P75] time.| +|JobFailure:TenantBlock|10|Migration is blocked at the destination tenant. The job is cancelled. Please check tenant status before resubmitting.| +|JobCancelled:Unknown|11|The migration job is canceled for unknown reason.| + + +## New: Speed up small file migration + +The migration package includes multiple files, which are each uploaded/downloaded individually. If you have a large number of small-sized files, migration speed drops dramatically. By using the new **ArchivedFiles.XML** file in your prime package you can transfer files in batch resulting in a faster migration. [Learn more about using the ArchivedFiles.XML](/sharepoint/dev/apis/migration-api-overview#archivedfilessxml) + +## SourceType field required + +Beginning April 1, 2023, the SourceType field is mandatory when calling the Migration API. Starting October 1st, 2022, a warning message will be sent if the field is missing. + +To learn more, including examples, see: **[SharePoint Import Migration API - ExportSettings.xml](/sharepoint/dev/apis/migration-api-overview#exportsettingsxml)** + +## Fixes + +- **Changes to how Import API handles users**. As a response to issues arising from broken OneDrive scenarios when importing duplicate users, the API now blocks and detect duplicate user entries in UserGroup.xml. For details see: [Entering user identifiers in UserGroup.xml](/sharepoint/dev/apis/migration-api-overview#entering-user-identifiers-in-usergroup.xml). diff --git a/docs/apis/migration-azure.md b/docs/apis/migration-azure.md new file mode 100644 index 000000000..3dddc87b8 --- /dev/null +++ b/docs/apis/migration-azure.md @@ -0,0 +1,149 @@ +--- +title: "Use Azure Blob Storage Containers and Azure Queues with SharePoint Migration API" +description: "This article provides in-depth information on how to use the SharePoint Migration API with Azure Containers and Queues." +ms.date: 07/03/2024 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- + +# Use Azure Blob Storage Containers and Azure Queues with SharePoint Migration API + +Use Azure Blob Storage Containers to store contents, manifest files, and logs. Access migration status updates with Azure Queues. + +This guide provides provisioning, permission, and other requirements with SharePoint-provided Azure resources. + +## Azure Blob Storage Containers + +Migration API uses Azure Blob Storage Containers for temporary storage of content and manifest. SharePoint provides default containers for migration. Alternatively, you can provide your own containers. + +### Using SharePoint-provided containers + +SharePoint-provided containers have no extra cost to the customer. Provision SharePoint-provided containers with `ProvisionMigrationContainers` method, without the need to manually set up in the Azure admin console. + +Migration API provisions the containers in the same datacenter of the SharePoint instance. Migration API uses a container exclusively once for each request, to ensure security. + +Migration API destroys Used containers 30-90 days after completing migration jobs. + +#### Avoid throttling by decorating the traffic + +Avoid throttling by [decorating your HTTP traffic](/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online#how-to-decorate-your-http-traffic). + +#### Encryption + +The contents stored in SharePoint-provided containers are encrypted at rest with AES256CBC algorithm. This practice is mandatory. Migration API rejects migration jobs generated from unencrypted SharePoint-provided containers. + +This encryption requirement doesn't apply to user-provided containers. + +When using `CreateMigrationJobEncrypted` method, encrypt each file with AES CBC 256 standard as the encryption algorithm. + +Use the `AesCryptoServiceProvider.GenerateIV` method to generate a unique cryptographically random IV for each file, including the manifests in the package. Store the IV as a property on each file. + +##### Name + +IV + +##### Value + +A `BASE64` encoded **Byte Array** of the generated IV + +#### ProvisionMigrationContainers method + +Provisions new SharePoint-provided migration containers for content and manifest. + +##### Syntax + +```csharp +public SPProvisionedMigrationContainersInfo ProvisionMigrationContainers() +``` + +##### Return values + +An `SPProvisionedMigrationContainersInfo` object, containing the URI, access tokens, and encryption key of the provisioned containers. + +###### DataContainerUri value + +A **Uri** value containing the URI of the newly created container for storing migration **content**, along with the SAS access token. + +Pass this value to `CreateMigrationJob` method as `azureContainerSourceUri` parameter. + +The SAS access token contains `Read` and `Write` permissions only. It doesn't contain `List`. + +SharePoint enforces HTTPS connections to containers by setting `spr=https` field in SAS tokens. + +###### MetadataContainer value + +A **Uri** value containing the URI of the newly created container for storing **manifest** files, along with the SAS access token. + +Pass this value to `CreateMigrationJob` method as `azureContainerManifestUri` parameter. + +The SAS access token contains `Read` and `Write` permissions only. It doesn't contain `List`. + +SharePoint enforces HTTPS connections to containers by setting `spr=https` field in SAS tokens. + +###### EncryptionKey + +A **Byte Array** value containing the AES256CBC encryption key for both containers provisioned. + +### Use your own containers + +You can also provide your own Azure Blob Storage Containers. Provide the URI with SAS access tokens as required in the Migration API reference. + +## Azure Queues + +SharePoint-provided Azure Queues have no extra cost to the customer. Provision the queue with `ProvisionMigrationQueue` method, without the need to manually set up in Azure admin console. + +Migration API provisions Azure Queues in the same datacenter of the SharePoint instance. + +Alternatively, use user-provided Azure Queues if desired. Check the requirement in the Migration API Reference document. + +### Azure Queue Encryption + +`CreateMigrationJobEncrypted` method encrypts the messages written to the Azure Queue. + +To decrypt the messages, make sure you preserve `JobId` and the `IV` values returned by `CreateMigrationJobEncrypted` method. + +#### Encrypted message sample + +```json +{"Label": "Encrypted"}, +{"JobId": "[JobId value]"}, +{"IV": "[IV value, encoded in BASE64]"}, +{"Content": "[encrypted message, encoded in BASE64]"} +``` + +### ProvisionMigrationQueue method + +Provisions a new instance of Azure Queue for migration use. + +#### ProvisionMigrationQueue Syntax + +```csharp +public SPProvisionedMigrationQueueInfo ProvisionMigrationQueue() +``` + +#### Return value + +A `SPProvisionedMigrationQueueInfo` object containing the information of the newly created Azure Queue. + +##### JobQueueUri value + +A `Uri` value containing the URI and SAS access token of the newly created Azure Queue. + +Pass this value to `CreateMigrationJob` method's `azureQueueReportUri` parameter. + +## Use endpoints in Azure Government + +Use Azure Government endpoints for Microsoft 365 Government. + +### Required endpoints in Azure Government + +- `https://*.blob.core.usgovcloudapi.net` +- `https://*.queue.core.usgovcloudapi.net` diff --git a/docs/apis/migration-content-package.md b/docs/apis/migration-content-package.md new file mode 100644 index 000000000..6de44cbfe --- /dev/null +++ b/docs/apis/migration-content-package.md @@ -0,0 +1,113 @@ +--- +title: "Preparing the content for Migration API" +description: "This article provides in-depth information on how to use create and use content packages with SharePoint Migration API" +ms.date: 04/18/2024 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- + +# Preparing the content for Migration API + +Use this document to prepare the contents to migrate with SharePoint Migration API. + +## Files and folders + +### File and package size limits + +Migration API supports importing files with sizes up to 15 GB (the limit set by SharePoint). + +For the best performance, keep the package size under 250 MB or 250 items. + +For larger files, create a package for the individual file. + +### File versions + +Migration API supports importing multiple versions of a file, including major and minor, up to the limit set by SharePoint. + +Each version of the file counts against the file size limit and item count limit. + +Include each version of the file, even if some of the versions already exist in SharePoint. + +### File overwriting + +Migration API deletes the original file along with all the versions, then replaces it with all versions of the resubmitted file, when a file is resubmitted. + +### No decryption + +Migration API doesn't decrypt contents. It treats any encrypted content as opaque files. While SharePoint lists these files, it doesn't index them. This behavior is the same as when a user uploads encrypted files through the SharePoint UI. + +### File compression + +Migration API doesn't decompress packages by default. Don't compress content and manifest packages together. Make sure you store the content package and the manifest package in different Azure Storage Blob Containers. + +Migration API imports **\*.zip** files as compressed archive files if referenced in the import package as the archive itself. To import the individual files within the **\*.zip** file, see [Archive Small Files](#archive-small-files-for-performance). + +### Archive small files for performance + +Migrate small files in batches for improved performance. Migration API **optionally** uncompresses a compressed **\*.zip** archive to improve the performance, based on manifest in **ArchivedFiles.xml**. + +Include `QuickXorHash` value of the archive when using this feature. Compute it with [QuickXorHash Algorithm](/onedrive/developer/code-snippets/quickxorhash). + +Migration API processes non-archived files in **Manifest.xml** without manifest in **ArchiveFiles.xml** as usual. + +This feature requires all the following prerequisites: + +#### Archive file size limit + +10 MB maximum. + +#### Archive file per package + +Two maximum. + +#### Archive file encryption + +Required. + +#### Individual file size + +Less than 100 kb after encryption. + +#### Don't compress individual files + +**Don't compress** the individual files, only compress the archive. + +## SharePoint Events and Event Handlers + +Migration API allows referencing Event Handlers on List Items. However, Migration API doesn't support defining new Event Handlers at the List level. + +Migration API doesn't generate Events when importing items. Therefore, existing Event Handlers don't fire during import. + +## Azure Containers + +### Azure Blob Storage Security Model + +Migration API uses Azure Blob Storage security model. There's no special treatment for Azure Blob Storage Containers used for Migration API that would differentiate from a standard container. + +### Snapshot + +Each file in the container must have at least one snapshot created. Avoid modifying the file during the import. Any file without a snapshot fails to import with errors. Migration API uses the latest snapshot of the file available at the time of import. + +To create a snapshot of a file after uploading to the Azure Blob Storage, use the following code: + +```csharp +CloudBlockBlob blob = blobContainerObj.GetBlockBlobReference(file); +blob.UploadFromStream(stm); +blob.CreateSnapshot(); +``` + +### Permissions + +To ensure the immutability of source blobs, Migration API accepts an SAS key with only `Read` and `List` access flags set for the content package container. + +Likewise, Migration API accepts a SAS key with only `Read`, `List`, and `Write` access for the Manifest container. Migration API requires the `Write` access for writing backlog files at the end of the import. + +Migration API checks SAS keys for these required access flags. Migration API rejects attempts to create migration jobs with incorrect access flags on SAS keys. diff --git a/docs/apis/migration-events.md b/docs/apis/migration-events.md new file mode 100644 index 000000000..dcd8c2209 --- /dev/null +++ b/docs/apis/migration-events.md @@ -0,0 +1,269 @@ +--- +title: "Migration events in Azure Queue" +description: "This article provides in-depth information on how to use Azure Queue events in migration." +ms.date: 04/18/2024 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- +# Migration events in Azure Queue + +This document lists all types of events Migration API and AMR API written to the Azure Queue. Use these events to get status updates on migration jobs. + +## JobQueued + +```log +JobId:845daca4-5529-4b0e-85ab-a603efee5b12 +Time:09/29/2020 19:56:02.883 +SiteId:48917234-de43-474a-9f1b-8d98ffa08425 +DbId:8fd09323-b23f-430d-8957-213586ce3861 +TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +CorrelationId:c8d97e9f-802f-0000-ceac-44663834d510 +``` + +## JobPostponed + +```log +JobId:845daca4-5529-4b0e-85ab-a603efee5b12 +Time:09/29/2020 19:56:57.598 +NextPickupTime:09/29/2020 20:16:57.519 +SiteId:48917234-de43-474a-9f1b-8d98ffa08425 +DbId:8fd09323-b23f-430d-8957-213586ce3861 +JobsInQueue:TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +CorrelationId:d5d97e9f-702c-0000-ceb9-354fefa5e9f6 +``` + +## JobLogFileCreate + +```log +JobId:071f9aad-36e6-4bef-9f09-40b5c7498ecdTime:09/29/2020 19:56:29053 +FileName:Import-071f9aad-36e6-4bef-9f09-40b5c7498ecd-1.log +CorrelationId:22ca20ec-23de-468b-add3-4e52e90d3a68 +JobStart +JobId:071f9aad-36e6-4bef-9f09-40b5c7498ecdTime:09/29/2020 19:56:29:100 +SiteId:48917234-de43-474a-9f1b-8d98ffa08425 +WebId:36b66979-4a43-4b93-9b92-909c7186ff98 +DBId:8fd09323-b23f-430d-8957-213586ce3861 +FarmId:211e600c-f48d-4319-ba92-61150c8e8e8c +ServerId:cfd27448-822a-420b-bcc8-4f39629b01bc +SubscriptionId:51812136-3cba-482d-9696-532cddceab31 +TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +CorrelationId:c308c0ea-a7f5-4be9-acd4-1ebd39867434 +``` + +## JobProgress + +```log +JobId:845daca4-5529-4b0e-85ab-a603efee5b12 +Time:09/29/2020 19:56:32.265 +FilesCreated:15 +BytesProcessed:45 +ObjectsProcessed:217 +TotalExpectedSPObjects:403 +TotalErrors:0 +TotalWarnings:0 +TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +WaitTimeOnSqlThrottlingMilliseconds:0 +TotalDurationInMs:0 +CpuDurationInMs:0 +SqlDurationInMs:0 +SqlQueryCount:0 +CreatedOrUpdatedFileStatsBySize: +{ + "0-1K": { + "Count": 15, + "TotalSize": 45, + "TotalDownloadTime": 251, + "TotalCreationTime": 6754 + } +} +ObjectsStatsByType: +{ + "SPUser": { + "Count": 1, + "TotalTime": 289, + "AccumulatedVersions": 0, + "ObjectsWithVersions": 0 + }, + "SPFolder": { + "Count": 2, + "TotalTime": 144, + "AccumulatedVersions": 0, + "ObjectsWithVersions": 0 + }, + "SPDocumentLibrary": { + "Count": 1, + "TotalTime": 173, + "AccumulatedVersions": 0, + "ObjectsWithVersions": 0 + }, + "SPFile": { + "Count": 200, + "TotalTime": 6765, + "AccumulatedVersions": 0, + "ObjectsWithVersions": 0 + }, + "SPListItem": { + "Count": 14, + "TotalTime": 2111, + "AccumulatedVersions": 0, + "ObjectsWithVersions": 0 + } +} +TotalExpectedBytes:0 +CorrelationId:ccd97e9f-a0cc-0000-ceb9-37a900bec68d +``` + +## JobEnd (Import) + +```json +{ +"Event": "JobEnd", +"JobId": "aed28dcc-efc3-46c3-89f2-b5df71ccfe85", +"Time": "04/11/2024 14:51:53.531", +"FilesCreated": "5", +"BytesProcessed": "260999", +"ObjectsProcessed": "6", +"TotalErrors": "2", +"TotalWarnings": "0", +"FilesCreatedIrrespectiveOfVersions": "1", +"BytesProcessedOnlyCurrentVersion": "111001" +} +``` + +### **FilesCreatedIrrespectiveOfVersions** property + +An integer. + +The number of files created, exclusive of file versions. If a file has multiple versions, this count increases by 1 only when all the versions are migrated. + +List items aren't counted in this property. + +### **BytesProcessedOnlyCurrentVersion** property + +An integer. The bytes are processed with the last version of the file. If a file has multiple versions, this byte count increases only when all the versions are migrated. + +List items aren't counted in this property. + +## JobEnd (AMR) + +AMR API generates `JobEnd` event with estimation of item counts in `TotalExpectedSPObjects` field: + +```log +Event:JobEnd +JobId:e915f93a-b377-476e-995c-952fd28c0a12 +Time:11/28/2023 13:41:06.109 +FilesCreated:182 +BytesProcessed:441084014 +ObjectsProcessed:425 +TotalExpectedSPObjects:425 +TotalErrors:2 +TotalWarnings:0 +TotalRetryCount:0 +MigrationType:AsyncRead +MigrationDirection:Export +``` + +## JobDeleted + +```log +JobId:071f9aad-36e6-4bef-9f09-40b5c7498ecd +Time:09/29/2020 19:56:29.053 +CorrelationId:22ca20ec-23de-468b-add3-4e52e90d3a68 +``` + +### JobCancelled + +```log +JobId:071f9aad-36e6-4bef-9f09-40b5c7498ecd +Time:09/29/2020 19:58:29053 +TotalRetryCount:0 +CancelledByUser:false +MigrationType:None +MigrationDirection:Import +CorrelationId:22ca20ec-23de-468b-add3-4e52e90d3a68 +``` + +## JobError + +```log +JobId:b427d8d7-2b91-4da0-aee5-4b5a5a5d867e +Time: 02/05/2019 06:56:09.732 +TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +ObjectType:File +Url:Shared Documents/file.pdf +Id:fae7b4b0-2912-11e9-b0f3-7b554a52d6ab +ErrorCode:-2147024816 +ErrorType:Microsoft.SharePoint.SPException +Message:ErrorMessage +CorrelationId:d8e9bc9e-20e2-8000-aa83-48a62fc5ce75 +``` + +## JobFatalError + +```log +JobId:8f728c13-95d0-4d54-96bc-4ee912bd32ce +Time: 02/05/2019 06:57:20.523 +TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +ObjectType: +Url: +Id: +ErrorCode:-2147213196 +ErrorType:Microsoft.SharePoint.SPException +Message:ErrorMessage +CorrelationId:b370d5a0-105d-4000-241f-9b2d70449d7b +``` + +## JobWarning + +```log +JobId:b427d8d7-2b91-4da0-aee5-4b5a5a5d867e +Time: 02/05/2019 06:56:09.732 +TotalRetryCount:0 +MigrationType:None +MigrationDirection:Import +ObjectType:File +Url:Shared Documents/file.pdf +Id:fae7b4b0-2912-11e9-b0f3-7b554a52d6ab +ErrorCode:-2147024816 +ErrorType:Microsoft.SharePointSPException +Message:ErrorMessage +CorrelationId:d8e9bc9e-20e2-8000-aa83-48a62fc5ce75 +FinishManifestFileUpload +JobId:b427d8d7-2b91-4da0-aee5-4b5a5a5d867e +Time:02/05/2019 06:56:09.732 +ManifestFileName:Filename +CorrelationId:d8e9bc9e-20e2-8000-aa83-48a62fc5ce75 +``` + +## FinishManifestFileUpload + +Indicates that AMR API exported metadata. Find exported manifest files in the Azure Blob Storage Container supplied. The event also contains the location and file names of the exported files. + +### Example + +```json +{"Event", "FinishManifestFileUpload"}, +{"JobId", “f8d7d577-676e-47ce-ab69-ae7803979883”}, +{"Time", “2019-09-03T19:11:33.903”}, +{"ManifestFileName", “f8d7d577-676e-47ce-ab69-ae7803979883/ExportSettings.xml”} +``` diff --git a/docs/apis/migration-isv-guidance.md b/docs/apis/migration-isv-guidance.md index 6a4901c8d..142300d3b 100644 --- a/docs/apis/migration-isv-guidance.md +++ b/docs/apis/migration-isv-guidance.md @@ -1,119 +1,121 @@ --- title: "Migration guide for ISVs" -ms.reviewer: +description: "Learn about using the SharePoint Migration API." +ms.date: 06/28/2021 ms.author: jhendr author: JoanneHendrickson manager: pamgreen audience: Dev ms.topic: article -ms.prod: sharepoint-server-itpro -localization_priority: Priority -ms.collection: -- IT_Sharepoint_Server_Top -- SPMigration -- M365-collaboration +ms.subservice: migration-tool +ms.localizationpriority: high +ms.collection: + - SPMigration + - M365-collaboration search.appverid: MET150 -ROBOTS: NOINDEX, NOFOLLOW -ms.custom: -ms.assetid: --- # Migration guidance for ISVs -This document provides guidance for ISVs to deliver a fast and reliable migration experience to customers. It has the latest Microsoft migration practices and addresses common concerns or questions raised by ISV. The page will be updated on regular basis and the priority of the guidance is listed in the order of publication. +This document guides ISVs in delivering a fast and reliable migration experience to customers. It contains the latest Microsoft migration practices and concerns or questions raised by ISVs. ## Use app-based authentication -There are different usage patterns between end user traffic and an application doing background activities such as migration. It is important to identify user traffic versus application traffic. -To provide a stable platform and more reliable service, Microsoft is requesting that ISVs transition from using a user-based authentication to app-based authentication to provide greater reliability to our end users and partners. +There are different usage patterns between end user traffic and an application doing background activities such as migration. It is important to identify user traffic versus application traffic. -Migration is a background task application and should **not** be run in user mode. By transitioning to app-based authentication, you will benefit from the elastic capability of off-peak time to have more resources. +To provide a stable platform and more reliable service, Microsoft is requesting that ISVs transition from using a user-based authentication to app-based authentication to provide greater reliability to our end users and partners. -> [!Note] ->Microsoft will start enforcing the proper usage roles in early 2020. Vendors who continue to run migration in user roles can expect to experience increasing throttling and poor performance. +Migration is a background task application and should **not** be run in user mode. By transitioning to app-based authentication, you will benefit from the elastic capability of off-peak time to have more resources. + +> [!NOTE] +> Microsoft will start enforcing the proper usage roles in Q1 2020. Vendors who continue to run migration in user roles can expect to experience increasing throttling and poor performance. To learn more on how to register an app ID and how to implement app-based authentication see: -- [How to register an app ID](https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Factive-directory%2Fdevelop%2Factive-directory-v2-registration-portal&data=04%7C01%7CWan.Wu%40microsoft.com%7C7c98484b20de4fc80fb308d6da3e3509%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636936358039977299%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C-1&sdata=L%2BObRVyCBKPwvvY7MUUsWX%2B8yEIbzqaTkBjcmNjc1vk%3D&reserved=0) -- [Microsoft Graph Auth guidance](https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fgraph%2Fauth%2F&data=04%7C01%7CWan.Wu%40microsoft.com%7C7c98484b20de4fc80fb308d6da3e3509%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636936358039977299%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C-1&sdata=ZrFqXsLT3BtT8ynnlLQH9w7JZIOw07zu2X3EYbBmfD4%3D&reserved=0): Includes an informative video, basics, how to register your app and getting access scenarios +- [How to register an app ID](/azure/active-directory/develop/active-directory-v2-registration-portal) +- [Microsoft Graph Auth guidance](/graph/auth): Includes an informative video, basics, how to register your app and getting access scenarios - [Don’t get throttled! SharePoint and OneDrive guide to staying below the limits](https://www.youtube.com/watch?v=_pBHfGGdMfE) ### App-based authentication migration guidance #### Permission settings + Azure Active Directory (AAD) provides two type of permission : delegated permission and application permissions. For official AAD guidance please see: -- [Permissions and consent in the Azure Active Directory v1.0 endpoint](https://docs.microsoft.com/azure/active-directory/develop/v1-permissions-and-consent). +- [Permissions and consent in the Azure Active Directory v1.0 endpoint](/azure/active-directory/develop/v1-permissions-and-consent). -For SharePoint and OneDrive migration scenarios, the guidance is to follow the AAD permission specification. +For SharePoint and OneDrive migration scenarios, the guidance is to follow the AAD permission specification. -For migration tool that relies on end user signed in and presence, delegated permission is recommended. +For migration tool that relies on end user signed in and presence, delegated permission is recommended. For service-based migration tool that run without a signed-in user present such as app that runs as background service, application permission is recommended. #### Number of App IDs -Questions have been raised by ISV on whether to have a single App ID covering all migration offering products or having multiple App ID per software offering. There is no specific guidance where the ISVs can identify all of their App IDs. Please contact Microsoft for any corner case scenarios. +Questions have been raised by ISV on whether to have a single App ID covering all migration offering products or having multiple App ID per software offering. There is no specific guidance where the ISVs can identify all of their App IDs. Please contact Microsoft for any corner case scenarios. ->[!Note] +> [!Note] > Please register all your migration app IDs with Microsoft to ensure that you receive adequate throughput for your migration jobs. +## Use the Migration API -## Use the Migration API For migration jobs, the first guidance is to use existing published migration APIs. ### Import API (CreateMigrationJob) -The *CreateMigrationJob* helps the ISVs to import to SharePoint and OneDrive faster and more reliably. +The *CreateMigrationJob* helps the ISVs to import to SharePoint and OneDrive faster and more reliably. -- [Create Migration Job (Import API)](https://docs.microsoft.com/sharepoint/dev/apis/migration-api-overview) +- [SharePoint Import Migration API (CreationMigrationJob)](migration-api-overview.md) -The lastest supported features are: - -- [Migrate web parts using the Migration API](https://docs.microsoft.com/sharepoint/dev/apis/migrate-webparts-with-migrationapi) +The latest supported features are: +- [Migrating web parts using the Migration API](migrate-webparts-with-migrationapi.md) ### Export API (Asynchronous Metadata Read) -A new migration API, Asynchronous Metadata Read API (Export API) is currently being made available to ISVs for testing. If you are interested, please contact Microsoft with your test tenant information. +A new migration API, Asynchronous Metadata Read API (Export API) is available to ISVs. The *AsynchronousMetadataRead* helps ISVs export content from SharePoint and OneDrive with fast and reduced calls. For example, the new API can export all the files and lists related metadata from the root level of document library in a single call. This reduces the number of calls needed, the chance of being throttled, and improves performance. -- [Asynchronous Metadata Read (Export API)](https://docs.microsoft.com/sharepoint/dev/apis/export-amr-api) +To learn more, see [SharePoint Migration Export (Asynchronous Metadata Read) API](export-amr-api.md) -The *AsynchronousMetadataRead* helps the ISVs export content from SharePoint and OneDrive. +## Switch to the Microsoft Graph API -## Switch to the Microsoft Graph API -If a feature is not supported by the migration API, we recommend that you use the Graph API. If the Graph API does not support the needed migration feature, then use CSOM. However, using CSOM increases the likelihood of being throttled. +If a feature is not supported by the migration API, we recommend that you use the Graph API. If the Graph API does not support the needed migration feature, then use CSOM. However, using CSOM increases the likelihood of being throttled. -- [Graph Guidance: Best practices for discovering files and detecting changes at scale](https://docs.microsoft.com/onedrive/developer/rest-api/concepts/scan-guidance?view=odsp-graph-online) +- [Graph Guidance: Best practices for discovering files and detecting changes at scale](/onedrive/developer/rest-api/concepts/scan-guidance) ### CSOM Guidance (fallback only) The following provides guidance on specific CSOM implementation scenarios to help improve migration performance with SharePoint and OneDrive. -#### Enumeration Query Ordering guidance +#### Enumeration Query Ordering guidance + There are two kinds of enumeration queries, assuming the client intends to read every item with no server-side filtering. To query for every item in the list, recursively – in other words, the order does not depend on which folder(s) the items are contained in – the query should sort by ID. - - +`` + To query for every item in a specific folder, the query should sort by the filename, **FileLeafRef**. - +`` +## Permission guidance -## For migrations over 100TB +You need to be aware of three key numbers as you plan your migration to OneDrive or SharePoint especially when you have a hierarchy of deeply nested folders. They are: (1) the number of SharePoint unique permission scopes, (2) the number of role assignments, and (3) the total number of items in a list or library. Read the full guidance: -For customers migrating greater than 100TB of data, please follow the instructions on how to create a support ticket to help the product team to prepare the backend for the customers. +- [Migration guidance for ISVs](migration-isv-guidance.md) + +## For migrations over 100TB + +For customers migrating greater than 100TB of data, please follow the instructions on how to create a support ticket to help the product team to prepare the backend for the customers. + +- [Best practices for improving SharePoint and OneDrive migration performance](/sharepointmigration/sharepoint-online-and-onedrive-migration-speed). -• [Best practices for improving SharePoint and OneDrive migration performance](https://docs.microsoft.com/sharepointmigration/sharepoint-online-and-onedrive-migration-speed). - ## Escalation and throttling - + The primary reason speed is impacted, and throttling occurs, is due to the load that gets generated by calling CSOM and REST APIs. As a result of this load, throttling rules fire that impact the speed, reliability and predictability of the migration. Throttling is used to protect the database and to ensure a good user experience for our customers. - -To read the official throttling guidance, see: -- [Avoid getting throttled or blocked in SharePoint Online](https://myignite.techcommunity.microsoft.com/sessions/65661) +To read the official throttling guidance, see: -We continue to work to identify issues and improve the API. The asynchronous metadata read API is a direct result of ISV feedback. As an ISV/partner, we value your feedback. Please contact Microsoft if you have further questions. +- [Avoid getting throttled or blocked in SharePoint Online](https://aka.ms/spo429) +We continue to work to identify issues and improve the API. The asynchronous metadata read API is a direct result of ISV feedback. As an ISV/partner, we value your feedback. Please contact Microsoft if you have further questions. diff --git a/docs/apis/migration-job-progress-api-reference.md b/docs/apis/migration-job-progress-api-reference.md new file mode 100644 index 000000000..d6f6eff66 --- /dev/null +++ b/docs/apis/migration-job-progress-api-reference.md @@ -0,0 +1,171 @@ +--- +title: "SharePoint Migration Job Progress API" +description: "This article explains how to retrieve migration job status with GetMigrationJobProgress API." +ms.date: 06/15/2025 +ms.author: jihongzuo +author: shiongzuo +manager: dapodean +audience: ISV +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- +# SharePoint GetMigrationJobProgress API + +After submitting a migration job—whether an import job or an Asynchronous Metadata Read (AMR) job—you can use the GetMigrationJobProgress API to track its progress. The API is available via both SDK and REST interfaces. + +It returns a sequence of job status events, including: JobQueued, JobStart, JobProgress, JobError, and JobEnd. + +## Permissions + +Use application-based authentication when submitting a migration job. Ensure the application is granted the Sites.Read.All permission or higher. + +## GetMigrationJobProgress Method (SDK) + +### Syntax + +```csharp +public ClientResult Site.GetMigrationJobProgress( + Guid jobId, + String nextToken +) +``` + +### Method Parameters + +| Name | Type | Required | Description | +| :--------- | :------- | :------- | :----------------------------------------------------- | +| jobId | Guid | Yes | Unique identifier of the migration job | +| nextToken | String | Yes | Token for paging position. Use "0" for initial request | + +For a completed job, requests using nextToken are idempotent—repeating the same request will consistently return the same result. + +### Return Values + +| Name | Type | Description | +| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------ | +| Logs | IList | Returns a collection of job status events when new progress is available, or an empty collection if there are no updates. | +| NextToken | String | Returns an updated string value when new progress is available, or the same value as the nextToken parameter if there are no updates. | + +### Method Usage Example + +```csharp +ClientResult result = context.Site.GetMigrationJobProgress(jobId, nextToken ?? "0"); +context.ExecuteQuery(); +IList logs = result.Value.Logs; +string newNextToken = result.Value.NextToken; +``` + +## GetMigrationJobProgress REST API + +### HTTP Request + +```http +GET https://{site_url}/_api/site/GetMigrationJobProgress(jobId='{jobId}',nextToken=0) +``` + +### URI Parameters + +| Name | Type | Required | Description | +| :--------- | :------- | :------- | :----------------------------------------------------- | +| jobId | Guid | Yes | Unique identifier of the migration job | +| nextToken | String | Yes | Token for paging position. Use "0" for initial request | + +### Request Headers + +| Header | Required | +| :------------------------------------- | :------- | +| Authorization: Bearer {token} | Yes | +| Accept: application/json;odata=verbose | Yes | + +### Response + +A JSON object when the HTTP status code is 200. + +An empty JSON object when the HTTP status code is other than 200. + +### Error Handling + +| Status Code | Meaning | Action | +| :---------- | :------------- | :---------------------------------------------------------------------- | +| 403 | Unauthorized | Ensure the app/user has at least Sites.Read.All permissions. | +| 429 | Too Many Requests | Parse Retry-After header and retry after the specified delay. | +| 500 | Internal Server Error | Parse error responses to identify internal errors. Do Not Retry. | +| 503 | Service Unavailable | Parse Retry-After header and retry after the specified delay. | + +| Internal Error Code | Meaning | +| :------------------ | :---------------------------------------------- | +| -2147213145 | Job not found | +| -2147213146 | Job status expired (valid for less than 5 days) | + +### API Usage Example + +#### Request Sample + +```http +GET https://contoso.sharepoint.com/_api/site/GetMigrationJobProgress(jobId=' 3e280efa-78a3-4ba1-bac6-e447aa538ca5', nextToken=0) +``` + +#### Successful Response Sample + +Status code: 200 +Response body: + +```json +{ + "d": { + "GetMigrationJobProgress": { + "Logs": { + "__metadata": { + "type": "Collection(Edm.String)" + }, + "results": [ + "{\"MigrationType\":\"None\",\"MigrationDirection\":\"Import\",\"SiteId\":\"48f1898f-77d9-4a1b-bddc-1f49bb6dc134\",\"DbId\":\"de6b85cd-726e-4b13-ae04-629798fddbf3\",\"TotalRetryCount\":\"0\",\"JobId\":\"3e280efa-78a3-4ba1-bac6-e447aa538ca5\",\"Time\":\"05/20/2025 09:18:48.132\",\"CorrelationId\":\"91884a0c-5ee8-4e1f-a23f-e4f7ec170182\",\"Event\":\"JobQueued\"}", + "{\"MigrationType\":\"None\",\"MigrationDirection\":\"Import\",\"SiteId\":\"48f1898f-77d9-4a1b-bddc-1f49bb6dc134\",\"WebId\":\"7206fc09-e4af-48b3-8730-ed7321396d7a\",\"DbId\":\"de6b85cd-726e-4b13-ae04-629798fddbf3\",\"FarmId\":\"f77d7b6c-ef43-4609-8fce-0e93142ce8a0\",\"ServerId\":\"44af885c-393b-4236-9417-bae7a9edc44e\",\"SubscriptionId\":\"82abb045-250e-4186-ba83-b9295930f272\",\"TotalRetryCount\":\"0\",\"JobId\":\"3e280efa-78a3-4ba1-bac6-e447aa538ca5\",\"Time\":\"05/20/2025 09:20:51.129\",\"CorrelationId\":\"7d3e7a8e-4445-4ce0-adb1-078e78cbf686\",\"Event\":\"JobStart\"}", + "{\"MigrationType\":\"None\",\"MigrationDirection\":\"Import\",\"TotalRetryCount\":\"0\",\"ObjectType\":\"ListItem\",\"Url\":\"\",\"Id\":\"cb471d5f-593f-4a63-b59e-8eae3e35b08a\",\"SourceListItemIntId\":\"3\",\"TargetListItemIntId\":\"3\",\"ErrorCode\":\"-2147286782\",\"ErrorType\":\"Microsoft.SharePoint.SPException\",\"Message\":\"Attempted to use an object that has ceased to exist. (Exception from HRESULT: 0x80030102 (STG_E_REVERTED)) \",\"JobId\":\"3e280efa-78a3-4ba1-bac6-e447aa538ca5\",\"Time\":\"05/20/2025 09:20:55.490\",\"CorrelationId\":\"7d3e7a8e-4445-4ce0-adb1-078e78cbf686\",\"Event\":\"JobError\"}", + "{\"MigrationType\":\"None\",\"MigrationDirection\":\"Import\",\"TotalRetryCount\":\"0\",\"FilesCreated\":\"0\",\"BytesProcessed\":\"0\",\"ObjectsProcessed\":\"4\",\"TotalExpectedSPObjects\":\"15\",\"TotalErrors\":\"3\",\"TotalWarnings\":\"0\",\"WaitTimeOnSqlThrottlingMilliseconds\":\"0\",\"TotalDurationInMs\":\"0\",\"CpuDurationInMs\":\"0\",\"SqlDurationInMs\":\"0\",\"SqlQueryCount\":\"0\",\"IsShallowCopy\":\"False\",\"CreatedOrUpdatedFileStatsBySize\":\"{}\",\"ObjectsStatsByType\":\"{\\\"SPUser\\\":{\\\"Count\\\":1,\\\"TotalTime\\\":124,\\\"AccumulatedVersions\\\":0,\\\"ObjectsWithVersions\\\":0},\\\"SPFolder\\\":{\\\"Count\\\":1,\\\"TotalTime\\\":153,\\\"AccumulatedVersions\\\":0,\\\"ObjectsWithVersions\\\":0},\\\"SPDocumentLibrary\\\":{\\\"Count\\\":1,\\\"TotalTime\\\":404,\\\"AccumulatedVersions\\\":0,\\\"ObjectsWithVersions\\\":0},\\\"SPFile\\\":{\\\"Count\\\":1,\\\"TotalTime\\\":0,\\\"AccumulatedVersions\\\":0,\\\"ObjectsWithVersions\\\":0},\\\"SPListItem\\\":{\\\"Count\\\":1,\\\"TotalTime\\\":1880,\\\"AccumulatedVersions\\\":0,\\\"ObjectsWithVersions\\\":0}}\",\"TotalExpectedBytes\":\"0\",\"FilesCreatedIrrespectiveOfVersions\":\"0\",\"BytesProcessedOnlyCurrentVersion\":\"0\",\"JobId\":\"3e280efa-78a3-4ba1-bac6-e447aa538ca5\",\"Time\":\"05/20/2025 09:20:57.380\",\"CorrelationId\":\"7d3e7a8e-4445-4ce0-adb1-078e78cbf686\",\"Event\":\"JobEnd\"}" + ] + }, + "NextToken": "1764", + "__metadata": { + "type": "SP.MigrationJobProgress" + } + } + } +} +``` + +#### Error Response Sample + +Status code: 500 +Response body: + +```json +{ + "error": { + "code": "-2147213145, Microsoft.SharePoint.SPException", + "innererror": { + "message": "Job not found", + "stacktrace": "STACK_TRACE" + }, + "message": { + "lang": "en-US", + "value": "Job not found" + } + } +} +``` + +## Best Practice + +Begin with `nextToken=0`, store the returned token, and poll at certain intervals. This method is well-suited for long-running jobs and helps ensure no updates are missed. + +Since migration jobs typically take several minutes or more, polling every minute is advised, while adhering to the [guideline](https://aka.ms/spo429) to avoid throttling. + +## See Also + +- [SharePoint Migration API](migration-api-overview.md) +- [Migration Events](migration-events.md) diff --git a/docs/apis/migration-manifest.md b/docs/apis/migration-manifest.md new file mode 100644 index 000000000..770fd670b --- /dev/null +++ b/docs/apis/migration-manifest.md @@ -0,0 +1,405 @@ +--- +title: "Preparing the manifest for Migration API" +description: "This article provides in-depth information on how to use create and use manifest packages with SharePoint Migration API" +ms.date: 04/18/2024 +ms.author: ranren +author: underreview +manager: dapodean +audience: ITPro +ms.subservice: migration-tool +ms.topic: article +ms.localizationpriority: high +ms.collection: + - SPMigration + - m365-collaboration +--- + +# XML manifest files + +Migration API relies on XML manifest files to process the content import correctly. Create manifest files in a well-defined format. AMR API also exports metadata in this format. + +## XML Validation + +The package structure for Manifest files is based on a constrained version of [SharePoint Content Migration Schemas](/sharepoint/dev/schema/content-migration-schemas). + +## Encoding invalid XML characters + +AMR API encodes invalid XML characters in fields. Decode the attributes listed in `EncodedAttributes`. + +Migration API doesn't support invalid XML character encoding. + +### Example + +In this example, these attributes are encoded: URL, ParentWebURL, Name, and Version. + +```xml + +``` + +## Location + +Placed all manifest files at the root level of the Azure Blob Storage Container for manifest files. + +## ArchivedFiles.xml + +Optional. + +Used to process archived small files in batch. + +### ArchivedFiles.xml Example + +```xml + + + + + + + + + + + + + + + + + + + +``` + +## ExportSettings.xml + +Required. + +An XML file contains the export settings specified with the `SPExportSettings` and other classes. It also specifies the export settings, used in the subsequent import process at the migration target site. It also maintains a catalog of all objects exported to the migration package. + +### Ignore Web Parts + +Migration API checks and processes SharePoint Web Parts in certain types of files. For sources other than SharePoint Server and SharePoint Online, bypass these checks by setting `IgnoreWebParts` to `true`. This practice improves the performance of migration tasks when not migrating Web Parts. + +### Specify content source + +Migration API requires a `SourceType` value, containing the source of the content. It should contain a value from the following list: + +#### Accepted `SourceType` values + +- `AmazonS3` +- `AzureStorage` +- `Box` +- `Dropbox` +- `Egnyte` +- `FileShare` +- `GoogleCloudStorage` +- `GoogleDrive` +- `MicrosoftStream` +- `OneDrive` +- `SharePointOnline` +- `SharePointOnPremServer` +- `Other` + +When declaring to `Other`, include an extra `DetailedSource` value to provide more detail on the content source information. + +### ExportSettings.xml Example + +```xml + + + + + +``` + +## LookupListMap.xml + +Optional. + +An XML manifest file that maintains a simple lookup list, which records all SharePoint List Item references. Place it at the root of the Azure Blob Store Container defined by the `CreateMigrationJob`’s `azureContainerManifestUri` parameter. + +Not required if the import package doesn't contain Defining Fields or Views on a List or Document Library. The omission of this file generates a warning message in the log. Include a file with a childless `root` node to avoid this warning message. + +## Manifest.xml + +Required. + +An XML manifest file that contains the complete list of both the contents and the structure of the content package. Migration API uses this manifest file to reconstitute the source and its components. + +Place all instances of the **Manifest.xml** file for a package at the root of the Azure Blob Store Container. + +This manifest file is also the primary descriptor for metadata within the package, and provides the List, Folder, and Item hierarchy, along with metadata for the items including references back to users and groups defined in **UserGroupMap.xml** file. + +Use more than one **Manifest.xml** if needed. The manifests are identified with different file names. Migration API locates all manifests through references in **SystemData.xml** file’s `ManifestFile` entries. + +### Document Library/List ID consistency + +Use consistent Web ID and Document Library ID/List ID at the source and the target location. Inconsistent Web IDs generate errors as Migration API can't find the parent web for the import operation. + +Likewise, Migration API can't import items with incorrect Document Library IDs and List IDs into the target Document Library or List. Don't reuse IDs within the same site collection, to avoid Migration API importing packages to the same target site collection, regardless of the destination web. + +### GUID consistency + +To avoid GUID conflicts and import errors, use the same package for the same target. Importing a new package with the same content will cause problems. The package from a file share assigns GUIDs to files, folders, and list items. Keep the package from the file share as a record of the original GUIDs. Use the same GUIDs for later packages to avoid conflicts and track changes. + +### Preserve content identifiers + +The identifiers in the Import Packages are **explicitly** used during import to identify content. This practice preserves existing identifiers for Document Library contents. + +Reference the target Web and List identifiers **explicitly**. + +Migration API preserves content type identifiers, file/folder item GUIDs, and List Item integer identifiers during import. Import fails when Migration API encounters incorrect identifiers in the package. + +This preservation enables successive import iterations with different packages, allowing items to move locations. + +### Permission Roles + +Manifest.xml contains the following Roles-related objects: + +#### Roles object + +Contains the list of all defined Roles on the Web. + +#### Role object + +Defines a Role with ID, internal permissions rights mask flags, and display information. + +##### RoleId value + +Defines the identifiers of the Role object. + +##### PermMask value + +Contains the rights mask flags. + +#### RoleAssignments object + +Contains the list of all unique permissions (RoleAssignment objects). + +#### RoleAssignment object + +Includes the list of distinct Assignment objects (if any). + +##### Assignment object + +Contains the actual membership of one distinct User or Group and their actual Role, where + +- RoleId values map to the RoleId values of the Role objects. +- PrincipalId values map to ID values of User or Group objects respectively in **UserGroups.xml**. + +#### Permissions Example + +```xml + + … + + + + + + + + + + + + + + … + + + … + +``` + +## Requirements.xml + +Optional. + +SharePoint Server usually generates this XML manifest file. It contains a list of deployment requirements in the form of installation requirements on the migration target, such as + +- feature definitions +- template versions +- Web Part assemblies +- language packs +- and so forth. + +Include no child node under the root for file shares. The omission of this file generates a warning message in the log. + +## RootObjectMap.xml + +Optional. + +Maintains a list of mappings of secondary (dependent) objects. Migration API uses this manifest file to correctly place dependent objects. + +The most common `RootObject` included is a single object of type List. The `ID` of this item should be the List `ID` of the target list, and the `ParentWebID` should match the `ID` of the parent target web containing this list in order for migration to be successful. The `ID`, `WebUrl`, and `Url` values of this object must also match the related structure laid out in the **Manifest.xml** file. + +## SystemData.xml + +Required. + +Contains various low-level system data. It also records the number and paths of **Manifest.xml** files in the manifest package, when there are multiple manifests. + +### Versions + +`SchemaVersion` references to the current `Build` and `DatabaseVersion` of the target farm, currently “15.0.0.0”. + +`SiteVersion` should match the target site collection `UIVersion`, currently `15`. + +### Multiple Manifests + +List all **Manifest.xml** files in the package in **SystemData.xml**, as `ManifestFile` entries. + +### Immutable SystemObjects + +List all `SystemObjects` defining dependent objects that remain immutable by Migration API. + +### SystemData.xml example + +This example **SystemData.xml** file shows the common objects from a file share import. Use different `ID`s for each package, and the `URL`s may be different. + +```xml + + + + + + + + + + + + + + +``` + +## UserGroupMap.xml + +Required. + +Records Users and User Security Groups for managing permissions. Migration API uses the manifest to ascertain the membership of Users and Groups, along with their roles and specific assignments. These assignments include unique permissions set at the level of the object and its offspring, unless a deeper child object overrides them. + +User or Group entries aren't mandatory, but omission prevents author or security information from the population during import. Migration API generates warnings in such cases. + +### User identifiers + +Identify a User only once in a single package. + +Manifest all Users and Groups within the exported Web(s). + +#### User object + +Includes the information about specific Users, including identification of a specific security principle as a domain group or not, sign-in, and the base64 encoded SystemId (SID) of the security principle. + +#### Group object + +Includes the information about specific Groups and the direct membership list of that Group. + +Owner values on Group objects and UserId values on member objects within group objects map to other ID values of other User or Group objects respectively. + +The following example shows how to manifest Users and Groups. + +```xml + + + + + … + + + + + + + + + + … + + +``` + +Make sure the Sign-in and SystemId values of users match the values in SharePoint. + +### Deleted Users + +Include an `IsDeleted` value as `true` for deleted accounts. This practice prevents lookup failures in the import process, which negatively impacts performance. + +### Unresolved User identifiers + +If Migration API is unable to resolve a User with the Sign-in information, and SystemId **is not** provided, Migration API replaces this User with `System Account` in the associated metadata (such as Author or Editor) in the package and generates a warning in the import logs: + +```text +Failed to ensure user 'user@contoso.com' +``` + +If Migration API is unable to resolve a User with the Sign-in while the SystemId **is** provided, Migration API creates a new deleted User with the provided Sign-in and SystemId. Migration API uses this User with associated metadata within the package. Migration API generates a warning in the import logs: + +```text +Failed to retrieve user 'user@contoso.com' attributes from the SiteUsers; falling back to passed in values +``` + +### Avoid non-UPN email addresses in User identifiers + +The `Login` attribute of the User identifier requires a UPN. **Do not use** non-UPN email addresses. Using non-UPN email addresses causes unexpected behavior in SharePoint Online. + +### Examples + +The following examples show the correct and incorrect ways of using the User identifiers. + +In this case, the user has the following identifiers: + +- UPN: +- Email: . + +#### Correct example + +This example manifests the User only once, with a UPN email address. + +```xml + +``` + +#### Incorrect example + +This example **incorrectly** uses a non-UPN email address and **incorrectly** includes more than one identifier for a single user. + +```xml + + +``` + +This example **incorrectly** uses a non-UPN email address. + +```xml + +``` + +## ViewFormsList.xml + +Optional. + +This XML manifest file maintains a list of Web Parts and tracks whether each is a view or form. + +This file is optional if the Import Package doesn't contain Web Parts. The omission of this file generates a warning message in the log. Alternatively, include a manifest file with a childless `root` node to avoid the warning message. diff --git a/docs/apis/migration-perm-guidance.md b/docs/apis/migration-perm-guidance.md new file mode 100644 index 000000000..f46fb025c --- /dev/null +++ b/docs/apis/migration-perm-guidance.md @@ -0,0 +1,86 @@ +--- +title: Migration permission guidance +description: "Migration permission guidance" +ms.date: 03/30/2023 +ms.subservice: migration-tool +ms.author: jhendr +author: JoanneHendrickson +manager: serdars +audience: ITPro +f1.keywords: +- NOCSH +ms.topic: conceptual +ms.localizationpriority: high +ms.collection: +- SPMigration +- M365-collaboration +search.appverid: MET150 +--- +# Migration permission guidance + +You need to be aware of three key numbers as you plan your migration to OneDrive or SharePoint especially when you have a hierarchy of deeply nested folders. They are: (1) the number of SharePoint unique permission scopes, (2) the number of role assignments, and (3) the total number of items in a list or library. + +## Permissions: Inherited and unique + +Inherited permissions are set as the default at the root site collection level and are applied to the other locations and objects within that site collection. Unique permissions are all other permissions that differ (or "break") from what is set at the root. In SharePoint, you can set unique permissions all the way down to the item level. + +Each time you break inheritance by granting access to a new user account or group at any level in a site, even on a single item, you create a new unique security "scope" ID. That scope is counted as a unique permission towards the total limit. A library (or list) can't have greater than 50,000 unique security scopes. + +![Site hierarchy](../images/hierarchy-perms.png) + +When the number of unique security scopes exceeds the value of the list view threshold, added SQL server round trips take place that can affect performance. +When migrating, we recommend that you have less than 5,000 unique scopes per library. + +## Role assignments + +A role assignment is a mapping between a user, a SharePoint object (web, list, file) and a role (for example, Design, Full Control, or Contribute). The role assignment ties together the role definition (permission level) with the specific user or group, and the scope that that permission level will be applied to (such as list, folder, item). + +The maximum number of role assignments allowed per security scope is 5,000. + +## Item limits + +When a library (or list) contains more than 100,000 items (files and folders or list items), you can't break permissions inheritance on the list itself. There's a limit of 100,000 items that can be updated or removed as a part of creating a new SharePoint security scope. + +If you're migrating a structure that has more than 100,000 children (such as files, folders, lists, or other object types), you need to restructure the migration by importing security in multiple phases to avoid exceeding this limit. Any VROOM invite, REST share link, or any other permission-modifying function call will trigger an HTTP 429 throttle if the threshold is reached. Permissions won't be updated. Unlike other throttles, waiting and trying again won't resolve the situation as you've reached a hard limit of 100,000. + +To learn more about the service limits in SharePoint for Microsoft 365, see [SharePoint Limits](/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#items-in-lists-and-libraries). + +## Folders with less than 100,000 items + +If your library (or list) has fewer than 100,000 items, and you have less than 50,000 unique scopes, you can migrate using the Migration API and apply unique scopes to create folders with fewer 100-K items to break inheritance as needed. + +## Folders with more than 100,000 items + +If you have a folder with more than 100,000 items, we recommend one of the following approaches. Determine how many items are in your source or root folder, including lists or other object types. Scan and determine which folder structures have greater than 100,000 items. + +### Method 1: Restructure the source layout + +The first option is to restructure your *source* layout. + +For example, divide a single folder of 250,000 items into four folders at the root so each folder has less than 100,000 items. There's still "room to grow", presuming users will continue to add content and make changes here. + +Make sure that there are no more than 50,000 unique scopes in the structure: ideally less than 5,000. + +In this example, at the source, break up the structure into four folders, A, B, C, and D, each having less than 100,000 items. Then perform the migration. For details, see the following illustration. + +![Hierarchy ABCD](../images/hierarchy-ABCD.png) + +> [!NOTE] +> There are other limits that must be considered during migration. For details, see [SharePoint Limits](/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#items-in-lists-and-libraries). + +### Method 2: Create your destination layout to avoid exceeding limits + +The alternate approach is to keep your source layout, applying unique scopes at the destination before migration. + +**Example:** Your source folder has 250,000 items within it. At your target location, create folders A, B, C, and D and apply the unique scopes and scope ID. This will break inheritance. Then proceed with your content migration. +If you don't want your end users to share items until migration is completed, use the Migration API to migrate the content and scopes, but set the scope to NULL to prevent any use. +After all the content and incremental migrations are completed, apply the proper scope. + +After the incremental migration has completed, and only if you previously set the scope to NULL, you can reapply the unique scope for folders A, B, C, D separately. When you reapply the scope, evaluate your folder size starting at the lowest level of hierarchy. + +## Other sharing/permission-related considerations + +The REST share link or any other permission-modifying function won't take effect if you attempt to update the permission on a file that is checked out by a user. +Finally, if a SharePoint site or OneDrive location is being actively used during migration, the existing permissions applied on that site, user or document will be enforced. + +**Example:** If you attempt to modify the permission on a site that only allows access to existing users already defined on the site, and the user you're trying to add to a file or folder doesn't already have permissions on the site itself, the permission call (for example, VROOM Invite) won't be able to make the modification. diff --git a/docs/apis/onenote-migration-service.md b/docs/apis/onenote-migration-service.md new file mode 100644 index 000000000..5b8f9b616 --- /dev/null +++ b/docs/apis/onenote-migration-service.md @@ -0,0 +1,57 @@ +--- +title: Migrating OneNote folders +description: "Migrating OneNote folders using the SPO OneNote converting service" +ms.date: 06/28/2022 +ms.author: jhendr +author: JoanneHendrickson +manager: pamgreen +audience: Dev +ms.topic: article +ms.subservice: migration-tool +ms.localizationpriority: high +ms.collection: +- SPMigration +- M365-collaboration +search.appverid: MET150 +--- +# Migrating OneNote folders + +When bringing **OneNote** notebooks into SharePoint Online (SPO) from outside the service, you are required to convert the file. OneNote files need to be located within a correctly tagged NoteBook folder before the OneNote content is accessible via the modern APIs. + +There is now a OneNote converting service in SPO that lets you mark the **OneNote** notebooks that are being migrated to be converted. + +## Example + +The following example shows SPMT using the SPO OneNote converting service, which is running in SPO background. + +![OneNote migration process](../images/onenote-migration-flow.png) + +## Algorithm for checking whether to mark the folder as OneNote folder + +For a normal folder, we use the following algorithm to determine whether it should be marked as **OneNote** folder or not. + +If any of the subfolders or descendant subfolders are NOT considered a OneNote folder, then this folder is NOT considered as a OneNote folder. + +If any file under this folder has an extension other than the following, it is NOT considered as a OneNote folder. + +- .one +- .onetoc2 +- .onetemp + +If the folder does not contain one .onetoc2 file, it is NOT considered to be a **OneNote** folder. + +## How to mark the OneNote folder + +The CSOM will mark the `HTML_x0020_File_x0020_Type` field of the folder on SharePoint Online as `OneNote.Notebook`. + +The marking must be done ONLY on the top-level OneNote folder candidate in the file hierarchy. + +Sample code: + +```csharp +List list = context.web.Lists.GetById({listid}); +ListItem item = list.GetItemByUniqueId({itemid}); +Item[“HTML_x0020_File_x0020_Type”] = “OneNote.Notebook”; +Item.SystemUpdate(); +Context.ExecuteQuery(); +``` diff --git a/docs/apis/rest/complete-basic-operations-using-sharepoint-rest-endpoints.md b/docs/apis/rest/complete-basic-operations-using-sharepoint-rest-endpoints.md deleted file mode 100644 index d6f078902..000000000 --- a/docs/apis/rest/complete-basic-operations-using-sharepoint-rest-endpoints.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Complete basic operations using SharePoint REST endpoints -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints/ -localization_priority: Normal ---- - - -# Complete basic operations using SharePoint REST endpoints - -This content has been redirected to [Complete basic operations using SharePoint REST endpoints](../../sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints.md). diff --git a/docs/apis/rest/determine-sharepoint-rest-service-endpoint-uris.md b/docs/apis/rest/determine-sharepoint-rest-service-endpoint-uris.md deleted file mode 100644 index f001263e6..000000000 --- a/docs/apis/rest/determine-sharepoint-rest-service-endpoint-uris.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Determine SharePoint REST service endpoint URIs -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/determine-sharepoint-rest-service-endpoint-uris/ -localization_priority: Normal ---- - - -# Determine SharePoint REST service endpoint URIs - -This content has been redirected to [Determine SharePoint REST service endpoint URIs](../../sp-add-ins/determine-sharepoint-rest-service-endpoint-uris.md). diff --git a/docs/apis/rest/get-to-know-the-sharepoint-rest-service.md b/docs/apis/rest/get-to-know-the-sharepoint-rest-service.md deleted file mode 100644 index 0a7f0a909..000000000 --- a/docs/apis/rest/get-to-know-the-sharepoint-rest-service.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Get to know the SharePoint REST service -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service/ -localization_priority: Normal ---- - - -# Get to know the SharePoint REST service - -This content has been redirected to [Get to know the SharePoint REST service](../../sp-add-ins/get-to-know-the-sharepoint-rest-service.md). diff --git a/docs/apis/rest/make-batch-requests-with-the-rest-apis.md b/docs/apis/rest/make-batch-requests-with-the-rest-apis.md deleted file mode 100644 index 9d0768aa0..000000000 --- a/docs/apis/rest/make-batch-requests-with-the-rest-apis.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Make batch requests with the REST APIs -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/make-batch-requests-with-the-rest-apis/ -localization_priority: Normal ---- - - -# Make batch requests with the REST APIs - -This content has been redirected to [Make batch requests with the REST APIs](../../sp-add-ins/make-batch-requests-with-the-rest-apis.md). diff --git a/docs/apis/rest/navigate-the-sharepoint-data-structure-represented-in-the-rest-service.md b/docs/apis/rest/navigate-the-sharepoint-data-structure-represented-in-the-rest-service.md deleted file mode 100644 index 0666d75e9..000000000 --- a/docs/apis/rest/navigate-the-sharepoint-data-structure-represented-in-the-rest-service.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Navigate the SharePoint data structure represented in the REST service -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/navigate-the-sharepoint-data-structure-represented-in-the-rest-service/ -localization_priority: Normal ---- - - -# Navigate the SharePoint data structure represented in the REST service - -This content has been redirected to [Navigate the SharePoint data structure represented in the REST service](../../sp-add-ins/navigate-the-sharepoint-data-structure-represented-in-the-rest-service.md). diff --git a/docs/apis/rest/set-custom-permissions-on-a-list-by-using-the-rest-interface.md b/docs/apis/rest/set-custom-permissions-on-a-list-by-using-the-rest-interface.md deleted file mode 100644 index 2cab59fc5..000000000 --- a/docs/apis/rest/set-custom-permissions-on-a-list-by-using-the-rest-interface.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Set custom permissions on a list by using the REST interface -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/set-custom-permissions-on-a-list-by-using-the-rest-interface/ -localization_priority: Normal ---- - - -# Set custom permissions on a list by using the REST interface - -This content has been redirected to [Set custom permissions on a list by using the REST interface](../../sp-add-ins/set-custom-permissions-on-a-list-by-using-the-rest-interface.md). diff --git a/docs/apis/rest/synchronize-sharepoint-items-using-the-rest-service.md b/docs/apis/rest/synchronize-sharepoint-items-using-the-rest-service.md deleted file mode 100644 index d72133ab3..000000000 --- a/docs/apis/rest/synchronize-sharepoint-items-using-the-rest-service.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Synchronize SharePoint items using the REST service -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/synchronize-sharepoint-items-using-the-rest-service/ -localization_priority: Normal ---- - - -# Synchronize SharePoint items using the REST service - -This content has been redirected to [Synchronize SharePoint items using the REST service](../../sp-add-ins/synchronize-sharepoint-items-using-the-rest-service.md). diff --git a/docs/apis/rest/upload-a-file-by-using-the-rest-api-and-jquery.md b/docs/apis/rest/upload-a-file-by-using-the-rest-api-and-jquery.md deleted file mode 100644 index 6ce5542f8..000000000 --- a/docs/apis/rest/upload-a-file-by-using-the-rest-api-and-jquery.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Upload a file by using the REST API and jQuery -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/upload-a-file-by-using-the-rest-api-and-jquery/ -localization_priority: Normal ---- - - -# Upload a file by using the REST API and jQuery - -This content has been redirected to [Upload a file by using the REST API and jQuery](../../sp-add-ins/upload-a-file-by-using-the-rest-api-and-jquery.md). diff --git a/docs/apis/rest/use-odata-query-operations-in-sharepoint-rest-requests.md b/docs/apis/rest/use-odata-query-operations-in-sharepoint-rest-requests.md deleted file mode 100644 index a4e83aa0c..000000000 --- a/docs/apis/rest/use-odata-query-operations-in-sharepoint-rest-requests.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Use OData query operations in SharePoint REST requests -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/use-odata-query-operations-in-sharepoint-rest-requests/ -localization_priority: Normal ---- - - -# Use OData query operations in SharePoint REST requests - -This content has been redirected to [Use OData query operations in SharePoint REST requests](../../sp-add-ins/use-odata-query-operations-in-sharepoint-rest-requests.md). diff --git a/docs/apis/rest/working-with-folders-and-files-with-rest.md b/docs/apis/rest/working-with-folders-and-files-with-rest.md deleted file mode 100644 index 5b65026bb..000000000 --- a/docs/apis/rest/working-with-folders-and-files-with-rest.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Working with folders and files with REST -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest/ -localization_priority: Normal ---- - - -# Working with folders and files with REST - -This content has been redirected to [Working with folders and files with REST](../../sp-add-ins/working-with-folders-and-files-with-rest.md). diff --git a/docs/apis/rest/working-with-lists-and-list-items-with-rest.md b/docs/apis/rest/working-with-lists-and-list-items-with-rest.md deleted file mode 100644 index 3f70e1364..000000000 --- a/docs/apis/rest/working-with-lists-and-list-items-with-rest.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Working with lists and list items with REST -ms.date: 02/07/2018 -ms.prod: sharepoint -redirect_url: https://docs.microsoft.com/sharepoint/dev/sp-add-ins/working-with-lists-and-list-items-with-rest/ -localization_priority: Normal ---- - - -# Working with lists and list items with REST - -This content has been redirected to [Working with lists and list items with REST](../../sp-add-ins/working-with-lists-and-list-items-with-rest.md). diff --git a/docs/apis/sharepoint-rest-graph.md b/docs/apis/sharepoint-rest-graph.md index dbc82f6dd..ac203275b 100644 --- a/docs/apis/sharepoint-rest-graph.md +++ b/docs/apis/sharepoint-rest-graph.md @@ -1,25 +1,23 @@ --- title: Operations using SharePoint REST v2 (Microsoft Graph) endpoints description: Perform basic create, read, update, and delete (CRUD) operations with the SharePoint v2 REST interface. -ms.date: 9/10/2019 -ms.prod: sharepoint online -localization_priority: Priority +ms.date: 12/05/2020 +ms.localizationpriority: high --- - # SharePoint REST operations via the Microsoft Graph REST API -If you are looking for the legacy SharePoint REST API documentation, see [Complete basic operations using SharePoint REST endpoints](https://docs.microsoft.com/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints). +If you are looking for the legacy SharePoint REST API documentation, see [Complete basic operations using SharePoint REST endpoints](../sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints.md). -For SharePoint Online, innovation using a REST API against SharePoint is driven via the Microsoft Graph REST API's. In scenarios where a solutions already have access tokens available to access SharePoint content, it's possible to access the REST API nativly within SharePoint instead of calling via the Microsoft Graph API. +For SharePoint Online, innovation using a REST API against SharePoint is driven via the Microsoft Graph REST API's. In scenarios where solutions already have access tokens available to access SharePoint content, it's possible to access the REST API natively within SharePoint instead of calling via the Microsoft Graph API. Below is a table outlining a set of the Microsoft Graph endpoints being backed by SharePoint Online. -|Graph URL| SharePoint URL| -|----|----| -|https://graph.microsoft.com/v1.0/sites| https://{tenant-name}.sharepoint.com/_api/v2.0/sites| -|https://graph.microsoft.com/v1.0/drives| https://{tenant-name}.sharepoint.com/_api/v2.0/drives| -|https://graph.microsoft.com/v1.0/drive| https://{tenant-name}.sharepoint.com/_api/v2.0/drive| -|https://graph.microsoft.com/v1.0/lists| https://{tenant-name}.sharepoint.com/_api/v2.0/lists| +| Graph URL | SharePoint URL | +| ----------------------------------------- | ------------------------------------------------------- | +| `https://graph.microsoft.com/v1.0/sites` | `https://{tenant-name}.sharepoint.com/_api/v2.0/sites` | +| `https://graph.microsoft.com/v1.0/drives` | `https://{tenant-name}.sharepoint.com/_api/v2.0/drives` | +| `https://graph.microsoft.com/v1.0/drive` | `https://{tenant-name}.sharepoint.com/_api/v2.0/drive` | +| `https://graph.microsoft.com/v1.0/lists` | `https://{tenant-name}.sharepoint.com/_api/v2.0/lists` | If your solution already uses other Microsoft Graph REST API's, it is recommended to call API's via the Microsoft Graph REST endpoints for easier code management. @@ -27,9 +25,4 @@ To figure out if a Microsoft Graph REST API call is backed by SharePoint Online ## See also -- [Microsoft Graph REST API v1.0 reference](https://docs.microsoft.com/graph/api/overview?view=graph-rest-1.0) - - - - - +- [Microsoft Graph REST API v1.0 reference](/graph/api/overview) diff --git a/docs/apis/site-creation-rest.md b/docs/apis/site-creation-rest.md index 05666d71b..530ad6137 100644 --- a/docs/apis/site-creation-rest.md +++ b/docs/apis/site-creation-rest.md @@ -1,36 +1,35 @@ --- title: Create Modern SharePoint Sites using REST description: Create and get the status of a new modern SharePoint site by using the REST interface. -ms.date: 4/19/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 12/07/2022 +ms.localizationpriority: high --- # Manage modern SharePoint sites using REST -This topic assumes that you are already familiar with the following topics: +This topic assumes that you are already familiar with the following topics: - [Get to know the SharePoint REST service](../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) - [Complete basic operations using SharePoint REST endpoints](../sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints.md) -This topic does not provide code snippets. The REST examples below assume an HTTP Accept header of 'application/json;odata.metadata=none'. +This topic does not provide code snippets. The REST examples below assume an HTTP Accept header of `application/json;odata.metadata=none`. The following REST commands are available for creating a modern SharePoint Communication site: - **Create**. Create a new SharePoint site. -- **Delete**. Deletes a SharePoint site. +- **Delete**. Delete a SharePoint site. - **Status**. Get the status of a SharePoint site. The base URL for the REST commands is `_api/SPSiteManager`. ## Create a modern site -Using the following REST api you can create both Communication sites and non-group associated Team Sites. +Using the following REST API you can create both Communication sites and Non-group associated Team Sites. -To specify which type of site to create you use the WebTemplate attribute. Use one of the following templates to select which type of site to create: +To specify which type of site to create you use the `WebTemplate` attribute. Use one of the following templates to select which type of site to create: -* Communication Site: `SITEPAGEPUBLISHING#0` -* non-group associated Team Site: `STS#3` +- Communication Site: `SITEPAGEPUBLISHING#0` +- Non-group associated Team Site: `STS#3` ```json url: /_api/SPSiteManager/create @@ -45,27 +44,42 @@ body: "Lcid": 1033, "ShareByEmailEnabled":false, "Classification":"Low Business Impact", + "SensitivityLabel": "", "Description":"Description", "WebTemplate":"SITEPAGEPUBLISHING#0", "SiteDesignId":"6142d2a0-63a5-4ba0-aede-d9fefca2c767", - "Owner":"owner@yourtenant.onmicrosoft.com" + "Owner":"owner@yourtenant.onmicrosoft.com", + "WebTemplateExtensionId":"00000000-0000-0000-0000-000000000000" } } ``` > [!IMPORTANT] -> If you use an app-only context to create the site collection the **owner property is required**. In other cases this is an optional property and if not present will default to the user calling the REST endpoint. +> If you use an app-only context to create the site collection the **Owner property is required**. In other cases this is an optional property and if not present will default to the user calling the REST endpoint. +> [!NOTE] +> The "Classification" parameter only sets the value visible on the site, but doesn't apply the label on the site. Use the new parameter "SensitivityLabel" to actually apply the label on your site collection. -The site design id can be retrieved by using the [Get-SPOSiteDesign](/powershell/module/sharepoint-online/get-spositedesign) (Microsoft SharePoint Online Management Shell) or [Get-PnPSiteDesign](/powershell/module/sharepoint-pnp/get-pnpsitedesign) (PnP PowerShell) cmdlets. If you want to apply an out-of-the-box available site design, use the following values: +The site design id can be retrieved by using the [Get-SPOSiteDesign](/powershell/module/sharepoint-online/get-spositedesign) (Microsoft SharePoint Online Management Shell) or [Get-PnPSiteDesign](/sharepoint/dev/declarative-customization/site-design-pnppowershell) (PnP PowerShell) cmdlets. If you want to apply an out-of-the-box available site design, use the following values: -- Topic: null +- Standard communication: `96c933ac-3698-44c7-9f4a-5fd17d71af9e` or null - Showcase: `6142d2a0-63a5-4ba0-aede-d9fefca2c767` - Blank: `f6cc5403-0d63-442e-96c0-285923709ffc` +> [!IMPORTANT] +> To apply your custom site designs as retrieved with [Get-SPOSiteDesign](/powershell/module/sharepoint-online/get-spositedesign) (Microsoft SharePoint Online Management Shell) or [Get-PnPSiteDesign](/sharepoint/dev/declarative-customization/site-design-pnppowershell) (PnP PowerShell) you will have to change the JSON as follows: +```json +... + "SiteDesignId":"00000000-0000-0000-0000-000000000000", + "Owner":"owner@yourtenant.onmicrosoft.com", + "WebTemplateExtensionId":"" +... +``` +[!INCLUDE [pnp-powershell](../../includes/snippets/open-source/pnp-powershell.md)] + ### Response -If successful, this method returns a `200, OK` response code and simple JSON object in the response body with the following details. +If successful, this method returns a `200, OK` response code and simple JSON object in the response body with the following details: ```json { @@ -107,8 +121,8 @@ body: none ### Response -If successful, this method returns a `200, OK` response code and simple JSON object in the response body with the following details. - +If successful, this method returns a `200, OK` response code and simple JSON object in the response body with the following details: + If the site exists, the response returns the site status and site URL: ```json @@ -123,19 +137,20 @@ If the site exists, the response returns the site status and site URL: If the site does not exist, the response returns a site status of 0 with no URL and no site id. ```json -{ +{ "SiteId":, "SiteStatus":0, "SiteUrl": } ``` -The full set of values for SiteStatus are as follows: +The full set of values for `SiteStatus` are as follows: + `0` - Not Found. The site doesn't exist. + `1` - Provisioning. The site is currently being provisioned. + `2` - Ready. The site has been created. + `3` - Error. An error occurred while provisioning the site. ++ `4` - Site with requested URL already exist. ## See also diff --git a/docs/apis/sp-migration-api-and-sensitivity-labels.md b/docs/apis/sp-migration-api-and-sensitivity-labels.md new file mode 100644 index 000000000..c14fa0f53 --- /dev/null +++ b/docs/apis/sp-migration-api-and-sensitivity-labels.md @@ -0,0 +1,37 @@ +--- +title: "Sensitivity labels and the SharePoint Migration API" +description: Learn how to have sensitivity labels applied to content before migration with the SharePoint Migration API. +ms.date: 06/28/2022 +ms.author: jhendr +author: JoanneHendrickson +manager: serdars +search.appverid: MET150 +ms.localizationpriority: high +ms.subservice: migration-tool +--- +# Sensitivity Labels and the SharePoint Migration API + +Sensitivity labels cannot be applied to files and folders using the SharePoint Migration API. If you want to have sensitivity labels applied to your content being migrated to Microsoft 365, we recommend using the Microsoft Information Protection SDK. There currently isn't a parameter in the API to apply sensitivity labels to files. + +**Step 1:** + +Before you migrate your content with the Migration API, become familiar with how sensitivity labels work in Microsoft 365 and learn about the Microsoft Information Protection SDK: + +- [Enable sensitivity labels for Offices files in SharePoint and OneDrive](/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files) +- [Microsoft Information Protection SDK](/information-protection/develop/overview) + +**Step 2:** + +Download and configure the Microsoft Information Protection SDK. The article listed here shows you how to set up and configure your Microsoft 365 subscription and client workstation, in preparation for using the SDK. + +- [Microsoft Information Projection (MIP) SDK setup and configuration](/information-protection/develop/setup-configure-mip) + +**Step 3:** + +Apply sensitivity labels using the MIP SDK. + +If you're currently using Azure Information Protection, you must migrate your labels to the Microsoft Purview compliance portal. For more information on the process, see [How to migrate Azure Information Protection labels to unified sensitivity labels](/azure/information-protection/configure-policy-migrate-labels). + +**Step 4:** + +Migrate content using the [SharePoint Import Migration API (CreationMigrationJob)](migration-api-overview.md) diff --git a/docs/apis/spod-copy-move-api.md b/docs/apis/spod-copy-move-api.md new file mode 100644 index 000000000..202977581 --- /dev/null +++ b/docs/apis/spod-copy-move-api.md @@ -0,0 +1,145 @@ +--- +title: Microsoft 365 Copy and Move API (CreateCopyJobs) +description: "Microsoft 365 Copy and Move API (CreateCopyJobs)" +ms.date: 10/05/2023 +ms.author: jhendr +author: JoanneHendrickson +manager: serdars +audience: ITPro +f1.keywords: +- NOCSH +ms.topic: article +ms.subservice: migration-tool +ms.localizationpriority: high +ms.collection: +- SPMigration +- M365-collaboration +search.appverid: MET150 +--- +# Microsoft 365 Copy and Move API (CreateCopyJobs) + +> [!IMPORTANT] +> SharePoint & OneDrive Copy and Move API replaces the CreateCopyJob API. The CreateCopyJob API has been deprecated. + +The following API is based on the use of the SharePoint Client Side Object Model (CSOM). We recommend using [NuGet](https://www.nuget.org/) packages when you reference CSOM in your solution. + +You can find the latest version of the SharePoint Online CSOM package from the [NuGet library](https://www.nuget.org/) using the ID *Microsoft.SharePointOnline.CSOM*. + +> [!IMPORTANT] +> Learn more about [limitations](#limitations) of this API before you begin. + +## Method + +### CreateCopyJobs + +This method creates a new copy or move job that lets you copy or move a file or folder from one site in SharePoint, OneDrive, or Teams, to another site. + +#### Syntax + +```csharp +public List CreateCopyJobs(Uri[] exportObjectUris, Uri destinationUri, SPCopyMigrationOptions options) +``` + +#### Parameters + +|Parameter|Description| +|:-----|:-----| +|exportObjectUris|The URL of a file or folders in a list that you want to copy or move| +|destinationUri|URL for the destination location.| + +##### SPCopyMigrationOptions + +```csharp +public bool IsMoveMode { get; set; } +``` + +> [!IMPORTANT] +> By default, this is set to copy. For a move operation, set this parameter to true. + +```csharp +public bool IgnoreVersionHistory { get; set; } +``` + +If not specified, the version history will be ignored and not moved to the destination. + +```csharp +public bool AllowSchemaMismatch { get; set; } +``` + +This allows the item to move even if the target has a mismatched schema definition from the source list. + +```csharp +public bool AllowSmallerVersionLimitOnDestination { get; set; } +``` + +This allows the move to take place if the target file has older version. By default it’s disallowed to prevent data loss. + +```csharp +public SPMigrationNameConflictBehavior NameConflictBehavior { get; set; } +``` + +If a name conflict occurs at the target site, the default reports a failure. + +```csharp +public bool IncludeItemPermissions { get; set; } +``` + +Reserved for internal use only. + +```csharp +public SPMoveAndShareFileInfo MoveAndShareFileInfo { get; set; } +``` + +Reserved for internal use only. + +```csharp +public bool BypassSharedLock { get; set; } +``` + +This indicates whether a file with a share lock can still be moved in a move job. If you want to move a file that is locked, you need to set this. + +```csharp +public string[] ClientEtags { get; set; } +``` + +If set, and the source eTag doesn’t match the eTag specified, the copy and move won’t take place. If left NULL, no check will take place. + +```csharp +public bool MoveButKeepSource { get; set; } +``` + +Once set, this move operation is similar to copy. The file will move to destination, but the source content will not be deleted. If set, this will make a copy with the version history and preserve the original metadata. No source item deletions occurs at the end. + +> [!NOTE] +> This is not like the normal copy, which only copies the most recent major version and doesn't maintain all the metadata. + +```csharp +public bool ExcludeChildren { get; set; } +``` + +For this operation, only the root level folder of the URL is copied. The sub-folders or files within the folder will not be moved or copied. + +### Output + +| Output parameter | Description | +| :---------------------- | :------------------------------------------------------------------------------------- | +| JobID/GUID | Return a unique Job ID associated with this asynchronous read | +| SourceListItemUniqueIds | Return the source | +| JobQueueUri | URL for accessing Azure queue used for returning notification of copy and move process | +| EncryptionKey | AES256CBC encryption key used to decrypt messages from job/manifest queue | + +```csharp +public Uri JobQueueUri { get; set; } +``` + +The reporting features are the same as they are for CreateMigrationJob. Logging tracks the status of the createCopyJobs. By default, blob queue permissions and settings are set to "all access”. It gives the job status as follows: job start, job end, and job error information. + +## Limitations + +Currently, the following limitations are: + +| What | Limitation | +| :---------------- | :---------------------------------- | +| File size | [SharePoint Limits](/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#moving-and-copying-across-sites) | +| Number of items | [SharePoint Limits](/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#moving-and-copying-across-sites) | +| Total size of job | [SharePoint Limits](/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#moving-and-copying-across-sites) | diff --git a/docs/apis/syntex/rest-applymodel-method.md b/docs/apis/syntex/rest-applymodel-method.md new file mode 100644 index 000000000..d366409ba --- /dev/null +++ b/docs/apis/syntex/rest-applymodel-method.md @@ -0,0 +1,140 @@ +--- +title: Batch apply model +description: Use REST API to apply a document understanding model to one or more libraries. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- +# Batch Apply model + +Applies (or syncs) a trained document understanding model to one or more libraries (see [example](rest-applymodel-method.md#examples)). + +## HTTP request + +```HTTP +POST /_api/machinelearning/publications HTTP/1.1 +``` + +## URI parameters + +None + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| +|Content-Type|application/json;odata=verbose;charset=utf-8| +|x-requestdigest|The appropriate digest for current site.| + +## Request body + +| Name | Required | Type | Description | +|--------|-------|--------|------------| +|__metadata|yes|string|Set the object meta on the SPO. Always use the value: {"type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningPublicationsEntityData"}.| +|Publications|yes|MachineLearningPublicationEntityData[]|The collection of MachineLearningPublicationEntityData each of which specifies the model and target document library.| + +### MachineLearningPublicationEntityData + +| Name | Required | Type | Description | +|--------|-------|--------|------------| +|ModelUniqueId|yes|string|The unique ID of the model file.| +|TargetSiteUrl|yes|string|The full URL of the target library site.| +|TargetWebServerRelativeUrl|yes|string|The server relative URL of the web for the target library.| +|TargetLibraryServerRelativeUrl|yes|string|The server relative URL of the target library.| +|ViewOption|no|string|Specifies whether to set new model view as the library default.| + +## Response + +| Name | Type | Description| +|--------|-------|------------| +|201 Created||This is a customized API to support applying a model to multi document libraries. In the case of partial success, 201 created could still be returned and the caller needs to inspect the response body to understand if the model has been successfully applied to a document library.| + +## Response Body + +| Name | Type | Description| +|--------|-------|------------| +|TotalSuccesses|int|The total number of a model being successfully applied to a document library.| +|TotalFailures|int|The total number of a model failing to be applied to a document library.| +|Details|MachineLearningPublicationResult[]|The collection of MachineLearningPublicationResult each of which specifies the detailed result of applying the model to the document library.| + +### MachineLearningPublicationResult + +| Name | Type | Description| +|--------|-------|------------| +|StatusCode|int|The HTTP status code.| +|ErrorMessage|string|The error message which tells what's wrong when apply the model to the document library.| +|Publication|MachineLearningPublicationEntityData|It specifies the model info and the target document library.| + +### MachineLearningPublicationEntityData + +| Name | Type | Description | +|--------|--------|------------| +|ModelUniqueId|string|The unique ID of the model file.| +|TargetSiteUrl|string|The full URL of the target library site.| +|TargetWebServerRelativeUrl|string|The server relative URL of the web for the target library.| +|TargetLibraryServerRelativeUrl|string|The server relative URL of the target library.| + +## Examples + +### Apply a model to the contracts document library in the repository site + +In this sample, the ID of the Contoso Contract document understanding model is `7645e69d-21fb-4a24-a17a-9bdfa7cb63dc`. + +#### Sample request + +```HTTP +{ + "__metadata": { + "type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningPublicationsEntityData" + }, + "Publications": { + "results": [ + { + "ModelUniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "TargetSiteUrl": "https://contoso.sharepoint.com/sites/repository/", + "TargetWebServerRelativeUrl": "/sites/repository", + "TargetLibraryServerRelativeUrl": "/sites/repository/contracts", + "ViewOption": "NewViewAsDefault" + } + ] + } +} +``` + + +#### Sample response + +In the response, TotalFailures and TotalSuccesses refers to the number of failures and successes of the model being applies to the specified libraries. + +**Status code:** 201 + +```JSON +{ + "Details": [ + { + "ErrorMessage": null, + "Publication": { + "ModelUniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "TargetSiteUrl": "https://contoso.sharepoint.com/sites/repository/", + "TargetWebServerRelativeUrl": "/sites/repository", + "TargetLibraryServerRelativeUrl": "/sites/repository/contracts", + "ViewOption": "NewViewAsDefault" + }, + "StatusCode": 201 + } + ], + "TotalFailures": 0, + "TotalSuccesses": 1 +} +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-batchdelete-method.md b/docs/apis/syntex/rest-batchdelete-method.md new file mode 100644 index 000000000..546a3ca51 --- /dev/null +++ b/docs/apis/syntex/rest-batchdelete-method.md @@ -0,0 +1,132 @@ +--- +title: BatchDelete +description: Use REST API to remove an applied document understanding model from one or more libraries. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# BatchDelete + +Removes an applied document understanding model from one or more libraries. Note that a model must be removed from all libraries before it can be deleted (see [example](rest-batchdelete-method.md#examples)). + +## HTTP request + +```HTTP +POST /_api/machinelearning/publications/batchdelete HTTP/1.1 +``` + +## URI parameters + +None + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| +|Content-Type|application/json;odata=verbose;charset=utf-8| +|x-requestdigest|The appropriate digest for current site.| + +## Request body + +| Name | Required | Type | Description | +|--------|-------|--------|------------| +|Publications|yes|MachineLearningPublicationEntityData[]|The collection of MachineLearningPublicationEntityData each of which specifies the model and target document library.| + +### MachineLearningPublicationEntityData + +| Name | Required | Type | Description | +|--------|-------|--------|------------| +|ModelUniqueId|yes|string|The unique ID of the model file.| +|TargetSiteUrl|yes|string|The full URL of the target library site.| +|TargetWebServerRelativeUrl|yes|string|The server relative URL of the web for the target library.| +|TargetLibraryServerRelativeUrl|yes|string|The server relative URL of the target library.| + +## Response + +| Name | Type | Description| +|--------|-------|------------| +|200 OK||This is a customized API to support removing a model from multi document libraries. In the case of partial success, 200 OK could still be returned and the caller needs to inspect the response body to understand if the model has been successfully removed from a document library.| + +## Response Body + +| Name | Type | Description| +|--------|-------|------------| +|TotalSuccesses|int|The total number of a model being successfully removed from a document library.| +|TotalFailures|int|The total number of a model failing to be removed from a document library.| +|Details|MachineLearningPublicationResult[]|The collection of MachineLearningPublicationResult each of which specifies the detailed result of removing the model from a document library.| + +### MachineLearningPublicationResult + +| Name | Type | Description| +|--------|-------|------------| +|StatusCode|int|The HTTP status code.| +|ErrorMessage|string|The error message which tells what's wrong when apply the model to the document library.| +|Publication|MachineLearningPublicationEntityData|It specifies the model info and the target document library.| + +### MachineLearningPublicationEntityData + +| Name | Type | Description | +|--------|--------|------------| +|ModelUniqueId|string|The unique ID of the model file.| +|TargetSiteUrl|string|The full URL of the target library site.| +|TargetWebServerRelativeUrl|string|The server relative URL of the web for the target library.| +|TargetLibraryServerRelativeUrl|string|The server relative URL of the target library.| + +## Examples + +### Remove a model from the contracts document library in the repository site + +In this sample, the ID of the Contoso Contract document understanding model is `7645e69d-21fb-4a24-a17a-9bdfa7cb63dc`. + +#### Sample request + +```HTTP +{ + "publications": [ + { + "ModelUniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "TargetSiteUrl": "https://constco.sharepoint-df.com/sites/docsite", + "TargetWebServerRelativeUrl": "/sites/docsite ", + "TargetLibraryServerRelativeUrl": "/sites/dcocsite/joedcos" + } + ] +} +``` + +#### Sample response + +In the response, TotalFailures and TotalSuccesses refer to the number of failures and successes of the model being removed from the specified libraries. + +**Status code:** 200 + +```JSON +{ + "Details": [ + { + "ErrorMessage": null, + "Publication": { + "ModelUniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "TargetSiteUrl": "https://contoso.sharepoint.com/sites/repository/", + "TargetWebServerRelativeUrl": "/sites/repository", + "TargetLibraryServerRelativeUrl": "/sites/repository/contracts", + "ViewOption": "NewViewAsDefault" + }, + "StatusCode": 200 + } + ], + "TotalFailures": 0, + "TotalSuccesses": 1 +} +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-createclassificationrequest.md b/docs/apis/syntex/rest-createclassificationrequest.md new file mode 100644 index 000000000..c4321f606 --- /dev/null +++ b/docs/apis/syntex/rest-createclassificationrequest.md @@ -0,0 +1,93 @@ +--- +title: Create file classification request +description: Use REST API to create a request to classify one or more files using a trained document understanding model. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# Create file classification request + +Creates a request to classify one or more files using the applied document understanding model. (For more information, see [example](rest-createclassificationrequest.md#examples).) + +The REST service of SharePoint Online (and SharePoint 2016 and later on-premises) supports the combining of multiple requests. Requests are combined into a single call to the service by using the OData $batch query option. This method can be used to enqueue classification work items for hundreds of documents at one time. + +## HTTP request + +```http +POST /_api/machinelearning/workItems HTTP/1.1 +``` + +## URI Parameters + +None + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| +|Content-Type|application/json;odata=verbose;charset=utf-8| +|x-requestdigest|The appropriate digest for current site| + +## Request body + +|Name |Type |Description | +|--------|-------|------------| +|_metadata|string |Set the object meta on the SPO. Always use the value: {"type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningWorkItemEntityData"}. | +|TargetSiteId|guid|The ID of the site where the file to classify is located. This can be omitted when TargetSiteUrl has a value. | +|TargetSiteUrl|string|The full URL of the site where the file to classify is located. This can be omitted when TargeSiteId has a value.| +|TargetWebId|guid|The ID of the web where the file to classify is located. This can be omitted when TargetWebServerRelativeUrl has a value. | +|TargetWebServerRelativeUrl|string|The server relative URL of the web where the file to classify is located. This can be omitted when TargetWebId has a value. | +|TargetUniqueId|guid|The ID of the folder to classify. This can be omitted when TargetServerRelativeUrl has a value. | +|TargetServerRelativeUrl|string|The server relative URL of the file to classify is located. This can be omitted when TargetUniqueId has a value.| + +## Responses + +| Name | Type | Description| +|--------|-------|------------| +|201 Created| |The response is customized. In there is failure, it could still return 201 Created. The caller should further check the response body to determine the exact result.| + +## Examples + +### Enqueue a request to classify a file of ID "e6cff8b7-c90c-4564-b5b8-033449090932" + +#### Sample request + +```JSON +{ + "__metadata": { + "type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningWorkItemEntityData" + }, + "TargetSiteId": "f686e63b-aba7-48e5-97c7-68c4c1df292f", + "TargetWebId": "66d6b64d-6f88-4dd9-b3db-47e6f00c53e8", + "TargetUniqueId": "e6cff8b7-c90c-4564-b5b8-033449090932" +} +``` + +#### Sample response + +**Status code:** 201 +```JSON +{ + "ErrorMessage": null, + "StatusCode": 201 +} +``` + +```JSON +{ + "ErrorMessage": null, + "StatusCode": 201 +} +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-createfolderclassificationrequest.md b/docs/apis/syntex/rest-createfolderclassificationrequest.md new file mode 100644 index 000000000..4e6a04e17 --- /dev/null +++ b/docs/apis/syntex/rest-createfolderclassificationrequest.md @@ -0,0 +1,97 @@ +--- +title: Create folder classification request +description: Use REST API to create a request to classify an entire folder using a trained document understanding model. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# Create folder classification request + +Creates a request to classify a whole folder during off-peak hours by using the applied document understanding model. (For more information, see [example](rest-createfolderclassificationrequest.md#examples).) +This API can be used to classify a whole document library by creating a work item for its root folder. + +## HTTP request + +```http +POST /_api/machinelearning/workItems HTTP/1.1 +``` + +## URI Parameters + +None + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| +|Content-Type|application/json;odata=verbose;charset=utf-8| +|x-requestdigest|The appropriate digest for current site| + +## Request body + +|Name |Type |Description | +|--------|-------|------------| +|_metadata|string |Set the object meta on the SPO. Always use the value: {"type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningWorkItemEntityData"}. | +|TargetSiteId|guid|The ID of the site where the folder to classify is located. This can be omitted when TargetSiteUrl has a value. | +|TargetSiteUrl|string|The full URL of the site where the folder to classify is located. This can be omitted when TargeSiteId has a value.| +|TargetWebId|guid|The ID of the web where the folder to classify is located. This can be omitted when TargetWebServerRelativeUrl has a value. | +|TargetWebServerRelativeUrl|string|The server relative URL of the web where the folder to classify is located. This can be omitted when TargetWebId has a value. | +|TargetUniqueId|guid|The ID of the folder to classify. This can be omitted when TargetServerRelativeUrl has a value. | +|TargetServerRelativeUrl|string|The server relative URL of the folder to classify is located. This can be omitted when TargetUniqueId has a value.| +|IsFolder|boolean|The flag that indicates if what will be classified is a folder. Always set this to true for creating a folder classification work item. | + + +## Responses + +| Name | Type | Description| +|--------|-------|------------| +|201 Created| |The response is customized. If there is failure, it could still return 201 Created. The caller should further check the response body to determine the exact result.| + +## Response body + +| Name | Type | Description| +|--------|-------|------------| +|StatusCode |int |The HTTP status code. If it’s not 200 or 201, the API should have failed.| +|ErrorMessage |string |The error message that tells what's wrong when apply the model to the document library.| + +## Examples + +### Enqueue a request to classify a whole folder of ID "e6cff8b7-c90c-4564-b5b8-033449090932" + + +#### Sample request + +```JSON +{ + "__metadata": { + "type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningWorkItemEntityData" + }, + "TargetSiteId": "f686e63b-aba7-48e5-97c7-68c4c1df292f", + "TargetWebId": "66d6b64d-6f88-4dd9-b3db-47e6f00c53e8", + "TargetUniqueId": "e6cff8b7-c90c-4564-b5b8-033449090932", + "IsFolder": true +} +``` + +#### Sample response + +**Status code:** 201 + +```JSON +{ + "ErrorMessage": null, + "StatusCode": 201 +} +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-createmodel-method.md b/docs/apis/syntex/rest-createmodel-method.md new file mode 100644 index 000000000..7bdc5f0c8 --- /dev/null +++ b/docs/apis/syntex/rest-createmodel-method.md @@ -0,0 +1,72 @@ +--- +title: Create model +description: Use REST API to create a model and its associated content type. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# Create model + +Creates a model and its associated content type. Note that this only creates the model. It will still need to be trained in the content center (see [example](rest-createmodel-method.md#examples)). + +## HTTP request + +```http +POST /_api/machinelearning/models HTTP/1.1 +``` +## URI Parameters + +None + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| +|Content-Type|application/json;odata=verbose;charset=utf-8| +|x-requestdigest|The appropriate digest for current site| + +## Request body + +|Name |Type |Description | +|--------|-------|------------| +|_metadata| |Set the object meta on the SPO. Always use the value: {"type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningModelEntityData"}. | +|ContentTypeGroup|string|The associated content type group associated with the model. Defaulted to "Intelligent Document Content Types".| +|ContentTypeName|string|The associated content type name. The created model file will have the same name.| + +## Responses + +| Name | Type | Description| +|--------|-------|------------| +|201 Created| |Success| + +## Examples + +### Create a new document understanding model called "Contoso Contract" + +#### Sample request + +```json +{ + "__metadata": { + "type": "Microsoft.Office.Server.ContentCenter.SPMachineLearningModelEntityData" + }, + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeName": "Contoso Contract" +} +``` + +#### Sample response + +**Status code:** 201 + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-getbytitle-method.md b/docs/apis/syntex/rest-getbytitle-method.md new file mode 100644 index 000000000..eb185e33c --- /dev/null +++ b/docs/apis/syntex/rest-getbytitle-method.md @@ -0,0 +1,111 @@ +--- +title: GetByTitle +description: Use REST API to get or update information about a Microsoft Syntex document understanding model using the model title. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: article +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# GetByTitle + +Gets or updates information about a Microsoft Syntex document understanding model using the model title (see [example](rest-getbytitle-method.md#examples)). + +## HTTP request + +```HTTP +GET /_api/machinelearning/models/getbytitle('{modelFileName}') HTTP/1.1 +``` + +This same method can be used for deleting a model, too. + +```HTTP +DELETE /_api/machinelearning/models/getbytitle('{modelFileName}') HTTP/1.1 +``` + +## URI parameters + +|Name |In |Required|Type|Description| +|-----|---|--------|----|-----------| +|modelFileName|query|True|string|Name of the Syntex model file.| + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| + +## Request body + +For GET, no request body is needed. + +## Responses + +| Name | Type | Description| +|--------|-------|------------| +|200 OK| |Success| + +## Examples + +### Get information about the Contoso Contract model + +In this sample, the name of the Syntex document understanding model is `Contoso Contract`. + +#### Sample request + +```HTTP +GET /_api/machinelearning/models/getbytitle('Contoso Contract') HTTP/1.1 +``` + +#### Sample response + +**Status code:** 200 + +```HTTP +{ + "@odata.context": "https://contoso.sharepoint.com/sites/filerepository/_api/$metadata#models/$entity", + "@odata.type": "#Microsoft.Office.Server.ContentCenter.SPMachineLearningModel", + "@odata.id": "https://contoso.sharepoint.com/sites/filerepository/_api/machinelearning/models/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "@odata.etag": "\"7645e69d-21fb-4a24-a17a-9bdfa7cb63dc,111\"", + "@odata.editLink": " https://contoso.sharepoint.com/sites/filerepository /_api/machinelearning/models/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "ConfidenceScore": "{\"trainingStatus\":{\"kind\":\"original\",\"ClassifierStatus\":{\"TrainingStatus\":\"success\",\"TimeStamp\":1611716640535},\"ExtractorsStatus\":[{\"TimeStamp\":1585175746775,\"ExtractorName\":\"Contract Name\",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1586905975794,\"ExtractorName\":\"Client \",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1586906061099,\"ExtractorName\":\"Contract Date\",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1586907912388,\"ExtractorName\":\"Fee\",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1611716640115,\"ExtractorName\":\"ServiceType\",\"TrainingStatus\":\"success\"}]},\"modelAccuracy\":{\"Classifier\":1,\"Extractors\":{\"Contract Name\":1,\"Client \":1,\"Contract Date\":1,\"Fee\":1,\"ServiceType\":1}},\"perSampleAccuracy\":{\"133\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"249\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"252\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"253\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"254\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"255\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"256\":{\"Extractors\":{\"ServiceType\":1}},\"257\":{\"Extractors\":{\"ServiceType\":1}}},\"perSamplePrediction\":{\"133\":{\"Extractors\":{\"ServiceType\":[]}},\"249\":{\"Extractors\":{\"ServiceType\":[\"Writing\"]}},\"252\":{\"Extractors\":{\"ServiceType\":[\"Catering\"]}},\"253\":{\"Extractors\":{\"ServiceType\":[\"Design\"]}},\"254\":{\"Extractors\":{\"ServiceType\":[\"Marketing\"]}},\"255\":{\"Extractors\":{\"ServiceType\":[\"Financial Planning\"]}},\"256\":{\"Extractors\":{\"ServiceType\":[\"Writing\"]}},\"257\":{\"Extractors\":{\"ServiceType\":[\"Writing\"]}}},\"trainingFailures\":{}}", + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x01010083DF84D4F59BBD4CB06F075AA81F58AA", + "ContentTypeName": "Contoso Contract", + "Created": "2020-03-25T22:04:04Z", + "CreatedBy": "i:0#.f|membership|meganb@contoso.com", + "DriveId": "b!O-aG9qer5UiXx2jEwd8pL0221maIb9lNs9tH5vAMU-h2NuHxlYUiTJyiwKQHZobK", + "Explanations": "{\"Classifier\":[{\"id\":\"8122ac1d-8fcb-4705-8872-2825cbf05bfe\",\"kind\":\"dictionaryFeature\",\"name\":\"agreement\",\"active\":true,\"nGrams\":[\"CONSULTING AGREEMENT\",\"SERVICES AGREEMENT\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"af83bea8-bc53-4e93-a3da-f1e697eb6bef\",\"kind\":\"modelFeature\",\"name\":\"Contract Name\",\"active\":true,\"modelReference\":\"Contract Name\",\"conceptId\":\"841d0dcf-7f1d-4a39-931c-53923d10c346\"},{\"id\":\"e3734994-9e34-40e3-82c7-bb6c7bc5a0c3\",\"kind\":\"modelFeature\",\"name\":\"Client \",\"active\":true,\"modelReference\":\"Client \",\"conceptId\":\"8b8490d0-9a09-4c16-bcff-59ce62e05c28\"},{\"id\":\"7c93e7fe-cbfb-47ee-8cca-46ecdf5f628f\",\"kind\":\"modelFeature\",\"name\":\"Contract Date\",\"active\":true,\"modelReference\":\"Contract Date\",\"conceptId\":\"6ba58918-e2f0-4685-9080-98ec4c3adc7c\"},{\"id\":\"5cc85b62-148a-4b07-9155-d9fb7cebb6d0\",\"kind\":\"modelFeature\",\"name\":\"Fee\",\"active\":true,\"modelReference\":\"Fee\",\"conceptId\":\"9c7f764d-afd2-49cd-aaa2-e9407156bfb3\"},{\"id\":\"0f8a23a6-c744-4cae-82bd-d836332ceb56\",\"kind\":\"modelFeature\",\"name\":\"ServiceType\",\"active\":true,\"modelReference\":\"ServiceType\",\"conceptId\":\"4aa9f2fe-cfab-49f8-86b1-11646c79cdbf\"}],\"Extractors\":{\"Contract Name\":[{\"id\":\"8804fbeb-bcf8-44c0-8ade-3fc65496037f\",\"kind\":\"dictionaryFeature\",\"name\":\"before\",\"active\":true,\"nGrams\":[\"- AND -\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}],\"Client \":[{\"id\":\"606c56de-9e71-42ef-8ec6-f0bbf351d673\",\"kind\":\"dictionaryFeature\",\"name\":\"start\",\"active\":true,\"nGrams\":[\"BETWEEN:\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"334e6df5-e076-40db-a47b-f11ceec7af9a\",\"kind\":\"dictionaryFeature\",\"name\":\"after\",\"active\":true,\"nGrams\":[\"of\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"bccefd2e-88a4-406c-aa9d-81d508bbafb3\",\"kind\":\"proximityFeature\",\"name\":\"prox\",\"active\":true,\"patterns\":[[{\"id\":\"606c56de-9e71-42ef-8ec6-f0bbf351d673\",\"kind\":\"proximityFeatureReference\"},{\"kind\":\"proximityTokenRange\",\"minCount\":1,\"maxCount\":6},{\"id\":\"334e6df5-e076-40db-a47b-f11ceec7af9a\",\"kind\":\"proximityFeatureReference\"}]]}],\"Contract Date\":[{\"id\":\"fabe1ed3-07af-4dc6-852d-fe9521c64801\",\"kind\":\"dictionaryFeature\",\"name\":\"dated\",\"active\":true,\"nGrams\":[\"dated\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"983da7b8-51d7-4a85-9644-007b488fce0b\",\"kind\":\"dictionaryFeature\",\"name\":\"betw\",\"active\":true,\"nGrams\":[\"between\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}],\"Fee\":[{\"id\":\"f4cf89dc-64d1-49a1-9be4-41debda251b6\",\"kind\":\"dictionaryFeature\",\"name\":\"flat fee of \",\"active\":true,\"nGrams\":[\"flat fee of $\",\"flat fee of $$\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}],\"ServiceType\":[{\"id\":\"c04408f5-ce14-4eb0-81d0-f72ea9fa7e83\",\"kind\":\"dictionaryFeature\",\"name\":\"Before label\",\"active\":true,\"nGrams\":[\"will provide \"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"ea94fa7f-e41b-4e09-a484-355912bfbdff\",\"kind\":\"dictionaryFeature\",\"name\":\"After label\",\"active\":true,\"nGrams\":[\"services for \"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}]}}", + "ID": 16, + "LastTrained": "2021-01-27T03:04:00Z", + "ListID": "f1e13676-8595-4c22-9ca2-c0a4076686ca", + "ModelSettings": null, + "ModelType": 2, + "Modified": "2021-01-27T03:05:04Z", + "ModifiedBy": "i:0#.f|membership|kevinche@contoso.com", + "ObjectId": "01ZBWEM5E54ZCXN6ZBERFKC6U336T4WY64", + "PublicationType": 0, + "Schemas": "{\"Extractors\":{\"Contract Name\":{\"concepts\":{\"841d0dcf-7f1d-4a39-931c-53923d10c346\":{\"name\":\"Contract Name\"}},\"relationships\":[]},\"Client \":{\"concepts\":{\"8b8490d0-9a09-4c16-bcff-59ce62e05c28\":{\"name\":\"Client \"}},\"relationships\":[]},\"Contract Date\":{\"concepts\":{\"6ba58918-e2f0-4685-9080-98ec4c3adc7c\":{\"name\":\"Contract Date\"}},\"relationships\":[]},\"Fee\":{\"concepts\":{\"9c7f764d-afd2-49cd-aaa2-e9407156bfb3\":{\"name\":\"Fee\"}},\"relationships\":[]},\"ServiceType\":{\"concepts\":{\"4aa9f2fe-cfab-49f8-86b1-11646c79cdbf\":{\"name\":\"ServiceType\",\"termSetId\":\"76c12efb-5173-4982-ae9b-5f9e37187171\"}},\"relationships\":[]}}}", + "SourceUrl": null, + "UniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc" +} +``` + +### Get and delete the Contoso Contract model by name + +In this sample, the name of the Contoso Contract document understanding model is `Contoso Contract`. + +##### Sample request + +```HTTP +DELETE /_api/machinelearning/models/getbytitle('Contoso Contract') HTTP/1.1 +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-getbyuniqueid-method.md b/docs/apis/syntex/rest-getbyuniqueid-method.md new file mode 100644 index 000000000..a22cb154e --- /dev/null +++ b/docs/apis/syntex/rest-getbyuniqueid-method.md @@ -0,0 +1,110 @@ +--- +title: GetByUniqueId +description: Use REST API to get or update information about a Microsoft Syntex document understanding model. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# GetByUniqueId + +Gets or updates information about a Microsoft Syntex document understanding model (see [example](rest-getbyuniqueid-method.md#examples)). + +## HTTP request + +```HTTP +GET /_api/machinelearning/models/getbyuniqueid('{modelUniqueId}') HTTP/1.1 +``` + +This same method can be used for deleting a model, too. + +```HTTP +DELETE /_api/machinelearning/models/getbyuniqueid('{modelUniqueId}') HTTP/1.1 +``` +## URI parameters + +|Name |In |Required|Type|Description| +|-----|---|--------|----|-----------| +|modelUniqueId|query|True|string|ID of the Syntex model file.| + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| + +## Request body + +For GET, no request body is needed. + +## Responses + +| Name | Type | Description| +|--------|-------|------------| +|200 OK| |Success| + +## Examples + +### Get the Contoso Contract model by ID + +In this sample, the ID of the Contoso Contract document understanding model is `7645e69d-21fb-4a24-a17a-9bdfa7cb63dc`. + +#### Sample request + +```HTTP +GET /_api/machinelearning/models/getbyuniqueid('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc') HTTP/1.1 +``` + +#### Sample response + +**Status code:** 200 + +```HTTP +{ + "@odata.context": "https://contoso.sharepoint.com/sites/filerepository/_api/$metadata#models/$entity", + "@odata.type": "#Microsoft.Office.Server.ContentCenter.SPMachineLearningModel", + "@odata.id": "https://contoso.sharepoint.com/sites/filerepository/_api/machinelearning/models/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "@odata.etag": "\"7645e69d-21fb-4a24-a17a-9bdfa7cb63dc,111\"", + "@odata.editLink": " https://contoso.sharepoint.com/sites/filerepository /_api/machinelearning/models/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "ConfidenceScore": "{\"trainingStatus\":{\"kind\":\"original\",\"ClassifierStatus\":{\"TrainingStatus\":\"success\",\"TimeStamp\":1611716640535},\"ExtractorsStatus\":[{\"TimeStamp\":1585175746775,\"ExtractorName\":\"Contract Name\",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1586905975794,\"ExtractorName\":\"Client \",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1586906061099,\"ExtractorName\":\"Contract Date\",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1586907912388,\"ExtractorName\":\"Fee\",\"TrainingStatus\":\"success\"},{\"TimeStamp\":1611716640115,\"ExtractorName\":\"ServiceType\",\"TrainingStatus\":\"success\"}]},\"modelAccuracy\":{\"Classifier\":1,\"Extractors\":{\"Contract Name\":1,\"Client \":1,\"Contract Date\":1,\"Fee\":1,\"ServiceType\":1}},\"perSampleAccuracy\":{\"133\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"249\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"252\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"253\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"254\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"255\":{\"Classifier\":1,\"Extractors\":{\"ServiceType\":1}},\"256\":{\"Extractors\":{\"ServiceType\":1}},\"257\":{\"Extractors\":{\"ServiceType\":1}}},\"perSamplePrediction\":{\"133\":{\"Extractors\":{\"ServiceType\":[]}},\"249\":{\"Extractors\":{\"ServiceType\":[\"Writing\"]}},\"252\":{\"Extractors\":{\"ServiceType\":[\"Catering\"]}},\"253\":{\"Extractors\":{\"ServiceType\":[\"Design\"]}},\"254\":{\"Extractors\":{\"ServiceType\":[\"Marketing\"]}},\"255\":{\"Extractors\":{\"ServiceType\":[\"Financial Planning\"]}},\"256\":{\"Extractors\":{\"ServiceType\":[\"Writing\"]}},\"257\":{\"Extractors\":{\"ServiceType\":[\"Writing\"]}}},\"trainingFailures\":{}}", + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x01010083DF84D4F59BBD4CB06F075AA81F58AA", + "ContentTypeName": "Contoso Contract", + "Created": "2020-03-25T22:04:04Z", + "CreatedBy": "i:0#.f|membership|meganb@contoso.com", + "DriveId": "b!O-aG9qer5UiXx2jEwd8pL0221maIb9lNs9tH5vAMU-h2NuHxlYUiTJyiwKQHZobK", + "Explanations": "{\"Classifier\":[{\"id\":\"8122ac1d-8fcb-4705-8872-2825cbf05bfe\",\"kind\":\"dictionaryFeature\",\"name\":\"agreement\",\"active\":true,\"nGrams\":[\"CONSULTING AGREEMENT\",\"SERVICES AGREEMENT\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"af83bea8-bc53-4e93-a3da-f1e697eb6bef\",\"kind\":\"modelFeature\",\"name\":\"Contract Name\",\"active\":true,\"modelReference\":\"Contract Name\",\"conceptId\":\"841d0dcf-7f1d-4a39-931c-53923d10c346\"},{\"id\":\"e3734994-9e34-40e3-82c7-bb6c7bc5a0c3\",\"kind\":\"modelFeature\",\"name\":\"Client \",\"active\":true,\"modelReference\":\"Client \",\"conceptId\":\"8b8490d0-9a09-4c16-bcff-59ce62e05c28\"},{\"id\":\"7c93e7fe-cbfb-47ee-8cca-46ecdf5f628f\",\"kind\":\"modelFeature\",\"name\":\"Contract Date\",\"active\":true,\"modelReference\":\"Contract Date\",\"conceptId\":\"6ba58918-e2f0-4685-9080-98ec4c3adc7c\"},{\"id\":\"5cc85b62-148a-4b07-9155-d9fb7cebb6d0\",\"kind\":\"modelFeature\",\"name\":\"Fee\",\"active\":true,\"modelReference\":\"Fee\",\"conceptId\":\"9c7f764d-afd2-49cd-aaa2-e9407156bfb3\"},{\"id\":\"0f8a23a6-c744-4cae-82bd-d836332ceb56\",\"kind\":\"modelFeature\",\"name\":\"ServiceType\",\"active\":true,\"modelReference\":\"ServiceType\",\"conceptId\":\"4aa9f2fe-cfab-49f8-86b1-11646c79cdbf\"}],\"Extractors\":{\"Contract Name\":[{\"id\":\"8804fbeb-bcf8-44c0-8ade-3fc65496037f\",\"kind\":\"dictionaryFeature\",\"name\":\"before\",\"active\":true,\"nGrams\":[\"- AND -\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}],\"Client \":[{\"id\":\"606c56de-9e71-42ef-8ec6-f0bbf351d673\",\"kind\":\"dictionaryFeature\",\"name\":\"start\",\"active\":true,\"nGrams\":[\"BETWEEN:\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"334e6df5-e076-40db-a47b-f11ceec7af9a\",\"kind\":\"dictionaryFeature\",\"name\":\"after\",\"active\":true,\"nGrams\":[\"of\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"bccefd2e-88a4-406c-aa9d-81d508bbafb3\",\"kind\":\"proximityFeature\",\"name\":\"prox\",\"active\":true,\"patterns\":[[{\"id\":\"606c56de-9e71-42ef-8ec6-f0bbf351d673\",\"kind\":\"proximityFeatureReference\"},{\"kind\":\"proximityTokenRange\",\"minCount\":1,\"maxCount\":6},{\"id\":\"334e6df5-e076-40db-a47b-f11ceec7af9a\",\"kind\":\"proximityFeatureReference\"}]]}],\"Contract Date\":[{\"id\":\"fabe1ed3-07af-4dc6-852d-fe9521c64801\",\"kind\":\"dictionaryFeature\",\"name\":\"dated\",\"active\":true,\"nGrams\":[\"dated\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"983da7b8-51d7-4a85-9644-007b488fce0b\",\"kind\":\"dictionaryFeature\",\"name\":\"betw\",\"active\":true,\"nGrams\":[\"between\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}],\"Fee\":[{\"id\":\"f4cf89dc-64d1-49a1-9be4-41debda251b6\",\"kind\":\"dictionaryFeature\",\"name\":\"flat fee of \",\"active\":true,\"nGrams\":[\"flat fee of $\",\"flat fee of $$\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}],\"ServiceType\":[{\"id\":\"c04408f5-ce14-4eb0-81d0-f72ea9fa7e83\",\"kind\":\"dictionaryFeature\",\"name\":\"Before label\",\"active\":true,\"nGrams\":[\"will provide \"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"ea94fa7f-e41b-4e09-a484-355912bfbdff\",\"kind\":\"dictionaryFeature\",\"name\":\"After label\",\"active\":true,\"nGrams\":[\"services for \"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}]}}", + "ID": 16, + "LastTrained": "2021-01-27T03:04:00Z", + "ListID": "f1e13676-8595-4c22-9ca2-c0a4076686ca", + "ModelSettings": null, + "ModelType": 2, + "Modified": "2021-01-27T03:05:04Z", + "ModifiedBy": "i:0#.f|membership|kevinche@contoso.com", + "ObjectId": "01ZBWEM5E54ZCXN6ZBERFKC6U336T4WY64", + "PublicationType": 0, + "Schemas": "{\"Extractors\":{\"Contract Name\":{\"concepts\":{\"841d0dcf-7f1d-4a39-931c-53923d10c346\":{\"name\":\"Contract Name\"}},\"relationships\":[]},\"Client \":{\"concepts\":{\"8b8490d0-9a09-4c16-bcff-59ce62e05c28\":{\"name\":\"Client \"}},\"relationships\":[]},\"Contract Date\":{\"concepts\":{\"6ba58918-e2f0-4685-9080-98ec4c3adc7c\":{\"name\":\"Contract Date\"}},\"relationships\":[]},\"Fee\":{\"concepts\":{\"9c7f764d-afd2-49cd-aaa2-e9407156bfb3\":{\"name\":\"Fee\"}},\"relationships\":[]},\"ServiceType\":{\"concepts\":{\"4aa9f2fe-cfab-49f8-86b1-11646c79cdbf\":{\"name\":\"ServiceType\",\"termSetId\":\"76c12efb-5173-4982-ae9b-5f9e37187171\"}},\"relationships\":[]}}}", + "SourceUrl": null, + "UniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc" +} +``` + +### Get and delete the Contoso Contract model by ID + +In this sample, the ID of the Contoso Contract document understanding model is `7645e69d-21fb-4a24-a17a-9bdfa7cb63dc`. + +#### Sample request + +```HTTP +DELETE /_api/machinelearning/models/getbyuniqueid('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc') HTTP/1.1 +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-getmodelandlibraryinfo.md b/docs/apis/syntex/rest-getmodelandlibraryinfo.md new file mode 100644 index 000000000..2ae731fe7 --- /dev/null +++ b/docs/apis/syntex/rest-getmodelandlibraryinfo.md @@ -0,0 +1,122 @@ +--- +title: Get model and library info +description: Use REST API to get information about a model and the library where it has been applied. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# Get model and library information + +Gets information about a model and the library where it has been applied (see [example](rest-getmodelandlibraryinfo.md#examples)). + +## HTTP request + +```HTTP +GET /_api/machinelearning/publications/getbymodeluniqueid('{modelUniqueId}') HTTP/1.1 +``` + +## URI parameters + +| Name | In | Required | Type | Description | +|--------|-------|--------|------------|-----------| +|ModelUniqueId|query|True|GUID|The unique id of the model file.| + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| + + +## Response + +| Name | Type | Description| +|--------|-------|------------| +|200 OK| |Success| + +## Examples + +### Get information about the contracts model and primed document library in the repository site + +In this sample, the ID of the Contoso Contract document understanding model is `7645e69d-21fb-4a24-a17a-9bdfa7cb63dc`. + +#### Sample request + +```HTTP +GET /sites/TestCC/_api/machinelearning/publications/getbymodeluniqueid('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc') HTTP/1.1 +``` + +#### Sample response + +**Status code:** 200 + +```JSON +{ + "@odata.context": "https://contoso.sharepoint.com/sites/TestCC/_api/$metadata#publications", + "value": [ + { + "@odata.type": "#Microsoft.Office.Server.ContentCenter.SPMachineLearningPublication", + "@odata.id": "https://contoso.sharepoint.com/sites/repository /_api/machinelearning/publications/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "@odata.etag": "\"7645e69d-21fb-4a24-a17a-9bdfa7cb63dc,94\"", + "@odata.editLink": " https://contoso.sharepoint.com/sites/TestCC /_api/machinelearning/publications/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "Created": "2021-04-27T03:05:25Z", + "CreatedBy": "i:0#.f|membership|meganb@contoso.com", + "DriveId": "b!O-aG9qer5UiXx2jEwd8pL0221maIb9lNs9tH5vAMU-gPy9BrxT7GTrtXtdtv1Uzb", + "ID": 26, + "ModelId": 16, + "ModelName": "contosocontract.classifier", + "ModelType": 0, + "ModelUniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "ModelVersion": "8.0", + "Modified": "2021-03-17T17:56:42Z", + "ModifiedBy": "i:0#.f|membership|joedoe@contoso.com", + "ObjectId": "01ZBWEM5FZRILGLXTEB5CZ2NNNSCTWBJMQ", + "PublicationType": 1, + "TargetLibraryRemoved": false, + "TargetLibraryServerRelativeUrl": "/sites/repository/contracts", + "TargetLibraryUrl": " https://contoso.sharepoint.com/sites/repository/contracts", + "TargetSiteUrl": "https://contoso.sharepoint.com/sites/repository", + "TargetWebServerRelativeUrl": "/sites/repository", + "UniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "ViewOption": "NewViewAsDefault" + }, + { + "@odata.type": "#Microsoft.Office.Server.ContentCenter.SPMachineLearningPublication", + "@odata.id": "https://contoso.sharepoint.com /sites/legal/_api/machinelearning/publications/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "@odata.etag": "\"7645e69d-21fb-4a24-a17a-9bdfa7cb63dc,101\"", + "@odata.editLink": "https://contoso.sharepoint.com /sites/legal/_api/machinelearning/publications/getbyuniqueId('7645e69d-21fb-4a24-a17a-9bdfa7cb63dc')", + "Created": "2021-01-27T03:17:44Z", + "CreatedBy": "i:0#.f|membership|esherman@contoso.com ", + "DriveId": "b!O-aG9qer5UiXx2jEwd8pL0221maIb9lNs9tH5vAMU-gPy9BrxT7GTrtXtdtv1Uzb", + "ID": 27, + "ModelId": 16, + "ModelName": "dispositions.classifier", + "ModelType": 0, + "ModelUniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "ModelVersion": "8.0", + "Modified": "2021-03-17T23:17:46Z", + "ModifiedBy": "i:0#.f|membership|esherman@contoso.com ", + "ObjectId": "01ZBWEM5B3ERSZK4PAARGLFZ7JP6GMXG2R", + "PublicationType": 1, + "TargetLibraryRemoved": false, + "TargetLibraryServerRelativeUrl": "/sites/legal/dispositions", + "TargetLibraryUrl": "https://contoso.sharepoint.com/sites/legal/dispositions", + "TargetSiteUrl": " https://contoso.sharepoint.com/sites/legal", + "TargetWebServerRelativeUrl": "/sites/legal", + "UniqueId": "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc", + "ViewOption": "NewViewAsDefault" + } + ] +} +``` + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/rest-updatemodelsettings-method.md b/docs/apis/syntex/rest-updatemodelsettings-method.md new file mode 100644 index 000000000..904565c66 --- /dev/null +++ b/docs/apis/syntex/rest-updatemodelsettings-method.md @@ -0,0 +1,74 @@ +--- +title: UpdateModelSettings +description: Use REST API to update available models settings for a Microsoft Syntex document understanding model. +ms.date: 09/23/2022 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: high +--- + +# UpdateModelSettings + +Updates available models settings (associated retention label and model description) for a Microsoft Syntex document understanding model (see [example](rest-updatemodelsettings-method.md#examples)). + +## HTTP request + +```HTTP +POST /_api/machinelearning/models/getbytitle('{modelFileName}')/updatemodelsettings HTTP/1.1 +``` + +## URI parameters + +|Name |In |Required|Type|Description| +|-----|---|--------|----|-----------| +|modelFileName|query|True|string|Name of the Syntex model file.| + +## Request headers + +| Header | Value | +|--------|-------| +|Accept|application/json;odata=verbose| +|Content-Type|application/json;odata=verbose;charset=utf-8| +|x-requestdigest|The appropriate digest for the current site.| + +## Request body + +|Name |Type |Description | +|--------|-------|-------| +|ModelSettings|string|JSON of model settings.| +|Description|string|The model description.| +|RetentionLabel| |Info for the associated label (label ID and name).| + +## Responses + +| Name | Type | Description| +|--------|-------|------------| +|200 OK| |Success| + +## Examples + +### Update model settings for Contoso Contract + +In this example, the model description and "Standard Hold" retention label are updated. The ID of the retention label is `27c5fcba-abfd-4c34-823d-0b4a48f7ffe6`. + +#### Sample request + +```HTTP +{ + "ModelSettings": "{\"Description\":\"This model is used to set files classified as Contoso Contracts with a standard hold retention.\", \"RetentionLabel\":{\"Id\":\"27c5fcba-abfd-4c34-823d-0b4a48f7ffe6\",\"Name\":\"Standard Hold\"}}" +} + +``` + +#### Sample response + +**Status code:** 200 + +## See also + +[Syntex document understanding model REST API](syntex-model-rest-api.md) diff --git a/docs/apis/syntex/syntex-model-rest-api.md b/docs/apis/syntex/syntex-model-rest-api.md new file mode 100644 index 000000000..277c633dd --- /dev/null +++ b/docs/apis/syntex/syntex-model-rest-api.md @@ -0,0 +1,57 @@ +--- +title: Unstructured document understanding model REST API +description: Overview of the document understanding model REST API. +ms.date: 07/21/2025 +ms.author: chucked +author: chuckedmonson +manager: pamgreen +ms.reviewer: ssquires +audience: admin +ms.topic: reference +ms.collection: m365initiative-syntex +ms.localizationpriority: medium +--- + +# Unstructured document processing model REST API + +You can use the SharePoint REST interface to create an unstructured document processing model, apply or remove the model to one or more libraries, and obtain or update information about the model. + +The SharePoint Online (and SharePoint 2016 and later on-premises) REST service supports combining multiple requests into a single call to the service by using the OData $batch query option. + +For details and links to code samples, see [Make batch requests with the REST APIs](/sharepoint/dev/sp-add-ins/make-batch-requests-with-the-rest-apis). + +## Prerequisites + +Before you get started, make sure that you're familiar with the following: + +- [Get to know the SharePoint REST service](/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service) +- [Complete basic operations using SharePoint REST endpoints](/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints) + +## REST commands + +The following REST commands are available for working with unstructured document processing models: + +- [Create model](rest-createmodel-method.md) – Creates a model and its associated content type. +- [GetByUniqueId](rest-getbyuniqueid-method.md) – Gets or updates information about an unstructured document processing model. +- [GetByTitle](rest-getbytitle-method.md) – Gets or updates information about an unstructured document processing model using the model title. +- [Apply model](rest-applymodel-method.md) – Applies (or syncs) a trained unstructured document processing model to one or more libraries. +- [Get model and library information](rest-getmodelandlibraryinfo.md) – Gets information about a model and the library where it has been applied. +- [UpdateModelSettings](rest-updatemodelsettings-method.md) – Updates available models settings (associated retention label and model description) for an unstructured document processing model. +- [BatchDelete](rest-batchdelete-method.md) – Removes an applied unstructured document processing model from one or more libraries. +- [Create file classification request](rest-createclassificationrequest.md) – Creates a request to classify a specified file or files using the applied model. +- [Create folder classification request](rest-createclassificationrequest.md) – Creates a request to classify an entire folder using the applied model. + +## Scenarios + +Note the following scenario examples that aren't intuitive from the method name. For more information, see each article. + +The create model method only creates the model object and its associated content type. You'll need to first train the model in the content center before it can be applied to a library. + +The apply model method is used to configure the model on the target library to classify documents and optionally extract additional information. This API also supports batch applying the model to multiple libraries. + +The remove model method just removes the model from one or more libraries where it was previously applied. If you want to delete the model, it must first be removed from all the libraries where it was applied. + + +## See also + +[Unstructured document processing overview](/microsoft-365/contentunderstanding/document-understanding-overview) diff --git a/docs/apis/webhooks/get-started-webhooks.md b/docs/apis/webhooks/get-started-webhooks.md index 01d0096bc..c3b73e38a 100644 --- a/docs/apis/webhooks/get-started-webhooks.md +++ b/docs/apis/webhooks/get-started-webhooks.md @@ -1,17 +1,14 @@ --- title: Get started with SharePoint webhooks description: Build an application that adds and handles SharePoint webhook requests. -ms.date: 03/14/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 09/23/2022 +ms.localizationpriority: high --- - - # Get started with SharePoint webhooks This article describes how to build an application that adds and handles SharePoint webhook requests. You will learn how to use [Postman client](https://www.getpostman.com/) to construct and execute SharePoint webhook requests quickly while interacting with a simple ASP.NET Web API as the webhook receiver. -You will use plain HTTP requests, which is useful for helping you understand how webhooks work. +You will use plain HTTP requests, which is useful for helping you understand how webhooks work. To complete the step-by-step instructions in this article, download and install the following tools: @@ -19,31 +16,29 @@ To complete the step-by-step instructions in this article, download and install * [Postman](https://www.getpostman.com/) * [Visual Studio Community Edition](https://go.microsoft.com/fwlink/?LinkId=691978&clcid=0x409) * [ngrok](https://ngrok.com/) (to install ngrok, see [Download and Installation](https://ngrok.com/download)) -* An Office 365 developer subscription with SharePoint Online. If you are new to Office 365, you can also [sign up for an Office 365 developer subscription through the Office 365 Developer Program](https://developer.microsoft.com/office/dev-program). See the [Office 365 Developer Program documentation](https://docs.microsoft.com/office/developer-program/office-365-developer-program) for step-by-step instructions about how to join the Office 365 Developer Program and sign up and configure your subscription. +* An Office 365 developer subscription with SharePoint Online. If you are new to Office 365, you can also [sign up for an Office 365 developer subscription through the Office 365 Developer Program](https://developer.microsoft.com/office/dev-program). See the [Office 365 Developer Program documentation](/office/developer-program/office-365-developer-program) for step-by-step instructions about how to join the Office 365 Developer Program and sign up and configure your subscription. ## Step 1: Register an Azure AD application for Postman client -In order for the Postman client to communicate with SharePoint, you need to register a Microsoft Azure Active Directory (Azure AD) app in your Azure AD tenant associated with your Office 365 tenant. +In order for the Postman client to communicate with SharePoint, you need to register a Microsoft Azure Active Directory (Azure AD) app in your Azure AD tenant associated with your Office 365 tenant. 1. Ensure that you register the application as a **Web Application**. +1. To access SharePoint Online, it's important to grant the Azure AD app permissions to the **Office 365 SharePoint Online** application and select the **read and write items and lists in all site collections** permission. -2. To access SharePoint Online, it's important to grant the Azure AD app permissions to the **Office 365 SharePoint Online** application and select the **read and write items and lists in all site collections** permission. - - > [!NOTE] - > For more information about adding an Azure AD application and granting permissions to applications, see [Adding an application](https://docs.microsoft.com/azure/active-directory/develop/active-directory-integrating-applications#adding-an-application). + > [!NOTE] + > For more information about adding an Azure AD application and granting permissions to applications, see [Adding an application](/azure/active-directory/develop/active-directory-integrating-applications#adding-an-application). -3. Enter the following endpoint as the Reply (Redirect) URL for the app. This is the endpoint to which Azure AD will send the authentication response, including the access token, if authentication was successful. +1. Enter the following endpoint as the Reply (Redirect) URL for the app. This is the endpoint to which Azure AD will send the authentication response, including the access token, if authentication was successful. - ```html - https://www.getpostman.com/oauth2/callback - ``` + ```html + https://www.getpostman.com/oauth2/callback + ``` -4. Generate a **Key**, which will be the client secret. +1. Generate a **Key**, which will be the client secret. +1. The following properties are required in later steps, so copy them to a safe place: -5. The following properties are required in later steps, so copy them to a safe place: - - * Client Id - * Client Secret + * Client Id + * Client Secret ## Step 2: Build a webhook receiver @@ -52,22 +47,14 @@ For this project, use the Visual Studio Web API project to build the webhook rec ### Create a new ASP.NET Web API project 1. Open Visual Studio. - -2. Select **File** > **New** > **Project**. - -3. In the **Templates** pane, select **Installed Templates**, and expand the **Visual C#** node. - -4. Under **Visual C#**, select **Web**. - -5. In the list of project templates, select **ASP.NET Web Application**. - -6. Name the project **SPWebhooksReceiver**, and select **OK**. - -7. In the **New ASP.NET Project** dialog, select the **Web API** template from the **ASP.NET 4.5.** group. - -8. Change the authentication to **No Authentication** by selecting the **Change Authentication** button. - -9. Select **OK** to create the Web API project. +1. Select **File** > **New** > **Project**. +1. In the **Templates** pane, select **Installed Templates**, and expand the **Visual C#** node. +1. Under **Visual C#**, select **Web**. +1. In the list of project templates, select **ASP.NET Web Application**. +1. Name the project **SPWebhooksReceiver**, and select **OK**. +1. In the **New ASP.NET Project** dialog, select the **Web API** template from the **ASP.NET 4.5.** group. +1. Change the authentication to **No Authentication** by selecting the **Change Authentication** button. +1. Select **OK** to create the Web API project. > [!NOTE] > You can clear the **Host in the cloud** check box because this project will not be deployed to the cloud. @@ -81,70 +68,54 @@ Visual Studio creates your project. Use ASP.NET Web API Tracing to log the requests coming from SharePoint. The following steps install the tracing package: 1. Go to **Solution Explorer** in Visual Studio. - -2. Open the context menu (right-click) for the project, and select **Manage NuGet Packages**. - -3. In the search box, enter **Microsoft.AspNet.WebApi.Tracing**. - -4. In the search results, select the **Microsoft.AspNet.WebApi.Tracing** package, and then select **Install** to install the package. +1. Open the context menu (right-click) for the project, and select **Manage NuGet Packages**. +1. In the search box, enter **Microsoft.AspNet.WebApi.Tracing**. +1. In the search results, select the **Microsoft.AspNet.WebApi.Tracing** package, and then select **Install** to install the package. #### Build SPWebhookNotification model Each notification generated by the service is serialized into a **webhookNotification** instance. You need to build a simple model that represents this notification instance. 1. Go to **Solution Explorer** in Visual Studio. - -2. Open the context menu (right-click) for the **Models** folder, and select **Add** > **Class**. - -3. Enter **SPWebhookNotification** as the class name and select **Add** to add the class to your project. - -4. Add the following code to the body of the **SPWebhookNotification** class: - - ```cs - public string SubscriptionId { get; set; } - - public string ClientState { get; set; } - - public string ExpirationDateTime { get; set; } - - public string Resource { get; set; } - - public string TenantId { get; set; } - - public string SiteUrl { get; set; } - - public string WebId { get; set; } - ``` +1. Open the context menu (right-click) for the **Models** folder, and select **Add** > **Class**. +1. Enter **SPWebhookNotification** as the class name and select **Add** to add the class to your project. +1. Add the following code to the body of the **SPWebhookNotification** class: + + ```csharp + public string SubscriptionId { get; set; } + public string ClientState { get; set; } + public string ExpirationDateTime { get; set; } + public string Resource { get; set; } + public string TenantId { get; set; } + public string SiteUrl { get; set; } + public string WebId { get; set; } + ``` #### Build SPWebhookContent model Because multiple notifications can be submitted to your webhook receiver in a single request, they are combined together in an object with a single array value. Build a simple model that represents the array. 1. Go to **Solution Explorer** in Visual Studio. +1. Open the context menu (right-click) for the **Models** folder, and select **Add** > **Class**. +1. Enter **SPWebhookContent** as the class name, and select **Add** to add the class to your project. +1. Add the following code to the body of the **SPWebhookContent** class: -2. Open the context menu (right-click) for the **Models** folder, and select **Add** > **Class**. - -3. Enter **SPWebhookContent** as the class name, and select **Add** to add the class to your project. - -4. Add the following code to the body of the **SPWebhookContent** class: - - ```cs - public List Value { get; set; } - ``` + ```csharp + public List Value { get; set; } + ``` #### Add SharePoint webhook client state -Webhooks provide the ability to use an optional string value that is passed back in the notification message for your subscription. This can be used to verify that the request is indeed coming from the source you trust, which in this case is SharePoint. +Webhooks provide the ability to use an optional string value that is passed back in the notification message for your subscription. This can be used to verify that the request is indeed coming from the source you trust, which in this case is SharePoint. Add a client state value with which the application can verify the incoming requests. 1. Go to **Solution Explorer** in Visual Studio. +1. Open the **web.config** file, and add the following key as the client state to the `` section: -2. Open the **web.config** file, and add the following key as the client state to the `` section: - - ```xml - - ``` + ```xml + + ``` #### Enable tracing @@ -157,162 +128,152 @@ In the **web.config** file, enable tracing by adding the following key inside th A trace writer is required, so you must add a trace writer to the controller configuration (in this case use the one from **System.Diagnostics**). 1. Go to **Solution Explorer** in Visual Studio. +1. Open **WebApiConfig.cs** in the **App_Start** folder. +1. Add the following line inside the **Register** method: -2. Open **WebApiConfig.cs** in the **App_Start** folder. - -3. Add the following line inside the **Register** method: - - ```cs - config.EnableSystemDiagnosticsTracing(); - ``` + ```csharp + config.EnableSystemDiagnosticsTracing(); + ``` #### Build SharePoint webhook controller Now build the webhook receiver controller that handles the incoming requests from SharePoint and take action accordingly. 1. Go to **Solution Explorer** in Visual Studio. - -2. Open the context menu (right-click) for the **Controllers** folder, and select **Add** > **Controller**. - -3. In the **Add Scaffold** dialog, select **Web API 2 Controller - Empty**. - -4. Select **Add**. - -5. Name the controller **SPWebhookController**, and select **Add** to add the API controller to your project. - -6. Replace the `using` statements with the following code: - - ```cs - using Newtonsoft.Json; - using SPWebhooksReceiver.Models; - using System.Collections.Generic; - using System.Configuration; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Threading.Tasks; - using System.Web; - using System.Web.Http; - using System.Web.Http.Tracing; - ``` - -7. Replace the code in the **SPWebhookController** class with the following code: - - ```cs - [HttpPost] - public HttpResponseMessage HandleRequest() - { - HttpResponseMessage httpResponse = new HttpResponseMessage(HttpStatusCode.BadRequest); - var traceWriter = Configuration.Services.GetTraceWriter(); - string validationToken = string.Empty; - IEnumerable clientStateHeader = new List(); - string webhookClientState = ConfigurationManager.AppSettings["webhookclientstate"].ToString(); - - if (Request.Headers.TryGetValues("ClientState", out clientStateHeader)) - { - string clientStateHeaderValue = clientStateHeader.FirstOrDefault() ?? string.Empty; - - if (!string.IsNullOrEmpty(clientStateHeaderValue) && clientStateHeaderValue.Equals(webhookClientState)) - { - traceWriter.Trace(Request, "SPWebhooks", - TraceLevel.Info, - string.Format("Received client state: {0}", clientStateHeaderValue)); - - var queryStringParams = HttpUtility.ParseQueryString(Request.RequestUri.Query); - - if (queryStringParams.AllKeys.Contains("validationtoken")) - { - httpResponse = new HttpResponseMessage(HttpStatusCode.OK); - validationToken = queryStringParams.GetValues("validationtoken")[0].ToString(); - httpResponse.Content = new StringContent(validationToken); - - traceWriter.Trace(Request, "SPWebhooks", - TraceLevel.Info, - string.Format("Received validation token: {0}", validationToken)); - return httpResponse; - } - else - { - var requestContent = Request.Content.ReadAsStringAsync().Result; - - if (!string.IsNullOrEmpty(requestContent)) - { - SPWebhookNotification notification = null; - - try - { - var objNotification = JsonConvert.DeserializeObject(requestContent); - notification = objNotification.Value[0]; - } - catch (JsonException ex) - { - traceWriter.Trace(Request, "SPWebhooks", - TraceLevel.Error, - string.Format("JSON deserialization error: {0}", ex.InnerException)); - return httpResponse; - } - - if (notification != null) - { - Task.Factory.StartNew(() => - { - //handle the notification here - //you can send this to an Azure queue to be processed later - //for this sample, we just log to the trace - - traceWriter.Trace(Request, "SPWebhook Notification", - TraceLevel.Info, string.Format("Resource: {0}", notification.Resource)); - traceWriter.Trace(Request, "SPWebhook Notification", - TraceLevel.Info, string.Format("SubscriptionId: {0}", notification.SubscriptionId)); - traceWriter.Trace(Request, "SPWebhook Notification", - TraceLevel.Info, string.Format("TenantId: {0}", notification.TenantId)); - traceWriter.Trace(Request, "SPWebhook Notification", - TraceLevel.Info, string.Format("SiteUrl: {0}", notification.SiteUrl)); - traceWriter.Trace(Request, "SPWebhook Notification", - TraceLevel.Info, string.Format("WebId: {0}", notification.WebId)); - traceWriter.Trace(Request, "SPWebhook Notification", - TraceLevel.Info, string.Format("ExpirationDateTime: {0}", notification.ExpirationDateTime)); - - }); - - httpResponse = new HttpResponseMessage(HttpStatusCode.OK); - } - } - } - } - else - { - httpResponse = new HttpResponseMessage(HttpStatusCode.Forbidden); - } - } - - return httpResponse; - } - ``` - -8. Save the file. +1. Open the context menu (right-click) for the **Controllers** folder, and select **Add** > **Controller**. +1. In the **Add Scaffold** dialog, select **Web API 2 Controller - Empty**. +1. Select **Add**. +1. Name the controller **SPWebhookController**, and select **Add** to add the API controller to your project. +1. Replace the `using` statements with the following code: + + ```csharp + using Newtonsoft.Json; + using SPWebhooksReceiver.Models; + using System.Collections.Generic; + using System.Configuration; + using System.Linq; + using System.Net; + using System.Net.Http; + using System.Threading.Tasks; + using System.Web; + using System.Web.Http; + using System.Web.Http.Tracing; + ``` + +1. Replace the code in the **SPWebhookController** class with the following code: + + ```csharp + [HttpPost] + public HttpResponseMessage HandleRequest() + { + HttpResponseMessage httpResponse = new HttpResponseMessage(HttpStatusCode.BadRequest); + var traceWriter = Configuration.Services.GetTraceWriter(); + string validationToken = string.Empty; + IEnumerable clientStateHeader = new List(); + string webhookClientState = ConfigurationManager.AppSettings["webhookclientstate"].ToString(); + + if (Request.Headers.TryGetValues("ClientState", out clientStateHeader)) + { + string clientStateHeaderValue = clientStateHeader.FirstOrDefault() ?? string.Empty; + + if (!string.IsNullOrEmpty(clientStateHeaderValue) && clientStateHeaderValue.Equals(webhookClientState)) + { + traceWriter.Trace(Request, "SPWebhooks", + TraceLevel.Info, + string.Format("Received client state: {0}", clientStateHeaderValue)); + + var queryStringParams = HttpUtility.ParseQueryString(Request.RequestUri.Query); + + if (queryStringParams.AllKeys.Contains("validationtoken")) + { + httpResponse = new HttpResponseMessage(HttpStatusCode.OK); + validationToken = queryStringParams.GetValues("validationtoken")[0].ToString(); + httpResponse.Content = new StringContent(validationToken); + + traceWriter.Trace(Request, "SPWebhooks", + TraceLevel.Info, + string.Format("Received validation token: {0}", validationToken)); + return httpResponse; + } + else + { + var requestContent = Request.Content.ReadAsStringAsync().Result; + + if (!string.IsNullOrEmpty(requestContent)) + { + SPWebhookNotification notification = null; + + try + { + var objNotification = JsonConvert.DeserializeObject(requestContent); + notification = objNotification.Value[0]; + } + catch (JsonException ex) + { + traceWriter.Trace(Request, "SPWebhooks", + TraceLevel.Error, + string.Format("JSON deserialization error: {0}", ex.InnerException)); + return httpResponse; + } + + if (notification != null) + { + Task.Factory.StartNew(() => + { + //handle the notification here + //you can send this to an Azure queue to be processed later + //for this sample, we just log to the trace + + traceWriter.Trace(Request, "SPWebhook Notification", + TraceLevel.Info, string.Format("Resource: {0}", notification.Resource)); + traceWriter.Trace(Request, "SPWebhook Notification", + TraceLevel.Info, string.Format("SubscriptionId: {0}", notification.SubscriptionId)); + traceWriter.Trace(Request, "SPWebhook Notification", + TraceLevel.Info, string.Format("TenantId: {0}", notification.TenantId)); + traceWriter.Trace(Request, "SPWebhook Notification", + TraceLevel.Info, string.Format("SiteUrl: {0}", notification.SiteUrl)); + traceWriter.Trace(Request, "SPWebhook Notification", + TraceLevel.Info, string.Format("WebId: {0}", notification.WebId)); + traceWriter.Trace(Request, "SPWebhook Notification", + TraceLevel.Info, string.Format("ExpirationDateTime: {0}", notification.ExpirationDateTime)); + + }); + + httpResponse = new HttpResponseMessage(HttpStatusCode.OK); + } + } + } + } + else + { + httpResponse = new HttpResponseMessage(HttpStatusCode.Forbidden); + } + } + + return httpResponse; + } + ``` + +1. Save the file. ## Step 3: Debug the webhook receiver 1. Select **F5** to debug the webhook receiver. - -2. When you have the browser open, copy the port number from the address bar. For example: `http://localhost:<_port-number_>` +1. When you have the browser open, copy the port number from the address bar. For example: `http://localhost:<_port-number_>` ## Step 4: Run ngrok proxy 1. Open a console terminal. +1. Go to the extracted ngrok folder. +1. Enter the following with the port number URL from the previous step to start ngrok: -2. Go to the extracted ngrok folder. - -3. Enter the following with the port number URL from the previous step to start ngrok: + ``` + ./ngrok http port-number --host-header=localhost:port-number + ``` - ``` - ./ngrok http port-number --host-header=localhost:port-number - ``` + You should see ngrok running. - You should see ngrok running. - -4. Copy the **Forwarding** HTTPS address. You will use this address as the service proxy for SharePoint to send requests. +1. Copy the **Forwarding** HTTPS address. You will use this address as the service proxy for SharePoint to send requests. ## Step 5: Add webhook subscription using Postman @@ -321,15 +282,12 @@ Now build the webhook receiver controller that handles the incoming requests fro Postman makes it really simple to work with APIs. The first step is to configure Postman to authenticate with Azure AD so you can send API requests to SharePoint. You will use the Azure AD app that you registered in Step 1. 1. Open Postman. You are presented with a **Sidebar** and **Request Editor**. +1. Select the **Authorization** tab in the **Request Editor**. +1. Select **OAuth 2.0** in the **Type** list. +1. Select the **Get New Access Token** button. +1. In the dialog window, enter the following: -2. Select the **Authorization** tab in the **Request Editor**. - -3. Select **OAuth 2.0** in the **Type** list. - -4. Select the **Get New Access Token** button. - -5. In the dialog window, enter the following: - * **Auth URL**: + * **Auth URL**: * `https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2F<_your-sharepoint-tenant-url-without-https_>` * Replace `your-sharepoint-tenant-url-without-https` with your tenant url without the **https** prefix. * **Access Token URL**: `https://login.microsoftonline.com/common/oauth2/token` @@ -338,15 +296,12 @@ Postman makes it really simple to work with APIs. The first step is to configure * **Token name**: sp_webhooks_token * **Grant type**: Authorization Code -6. Select the **Request Token** to sign in, consent, and get the token for the session. - -7. When the token is successfully retrieved, you should see **access\_token** variable added to the **Authorization** tab. - -8. Select the option to **Add token to header**. - -9. Double-click the **access\_token** variable to add the token to the header for the request. +1. Select the **Request Token** to sign in, consent, and get the token for the session. +1. When the token is successfully retrieved, you should see **access\_token** variable added to the **Authorization** tab. +1. Select the option to **Add token to header**. +1. Double-click the **access\_token** variable to add the token to the header for the request. - ![Postman get new access token](../../images/postman-get-new-access-token.png) + ![Postman get new access token](../../images/postman-get-new-access-token.png) ### Get Documents list Id @@ -354,174 +309,158 @@ You need to manage webhooks for the default document library, which is provision 1. Enter the following request URL: - ``` - https://site-collection/_api/web/lists/getbytitle('Documents')?$select=Title,Id - ``` + ```http + https://site-collection/_api/web/lists/getbytitle('Documents')?$select=Title,Id + ``` -2. Replace _site-collection_ with your site collection. - - Postman executes your request and if successful, you should see the result. +1. Replace _site-collection_ with your site collection. -3. Copy the **Id** from the results. Later you will use the **Id** to make webhook requests. + Postman executes your request and if successful, you should see the result. + +1. Copy the **Id** from the results. Later you will use the **Id** to make webhook requests. ### Add webhook subscription Now that you have the required information, construct the query and the request to add a webhook subscription. Use the request editor for the following steps: 1. Change the request to **POST** from **GET**. - -2. Enter the following as the request URL: - - ``` - https://site-collection/_api/web/lists('list-id')/subscriptions - ``` - -3. Replace _site-collection_ with your site collection. - -4. Go to the **Headers** tab. - -5. Make sure you still have the **Authorization** header. If not, you need to request a new access token. - -6. Add the following header **key** > **value** pairs: - * Accept > application/json;odata=nometadata - * Content-Type > application/json - -7. Go to the **Body** tab and select **raw** format. - -8. Paste the following JSON as the body: - - ```json - { - "resource": "https://site-collection/_api/web/lists('list-id')", - "notificationUrl": "https://ngrok-forwarding-address/api/spwebhook/handlerequest", - "expirationDateTime": "2016-10-27T16:17:57+00:00", - "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449" - } - ``` - -
- - ![postman add webhook body](../../images/postman-add-webhook-body.png) - -9. Make sure the **expirationDateTime** is at most 6 months from today. - -10. Make sure you are debugging the webhook receiver as in Step 4. - -11. Select **Send** to execute the request. - - If the request is successful, you should see the response from SharePoint that provides the subscription details. The following example shows a response for a newly created subscription: - - ```json - { - "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449", - "expirationDateTime": "2016-10-27T16:17:57Z", - "id": "32b95d9-4d20-4a17-bfa3-2957cb38ead8", - "notificationUrl": "https://85557d4b.ngrok.io/api/spwebhook/handlerequest", - "resource": "c34420f9-2ad7-4e54-94c9-b67798d2299b" - } - ``` - -12. Copy the subscription **id**. You will need it for the next set of requests. - -13. Go to the webhook receiver project in Visual Studio and examine the **Output** window. You should see the trace logs that look similar to the following trace, along with other messages: - - ``` - iisexpress.exe Information: 0 : Message='Received client state: A0A354EC-97D4-4D83-9DDB-144077ADB449' - iisexpress.exe Information: 0 : Message='Received validation token: daf2803c-43cf-44c7-8dff-7066eaa40f13' - ``` - - The trace indicates that the webhook received initially received a validation request. If you look at the code, you'll see that it returns the validation token immediately so that SharePoint can validate the request: - - ```cs - if (queryStringParams.AllKeys.Contains("validationtoken")) - { - httpResponse = new HttpResponseMessage(HttpStatusCode.OK); - validationToken = queryStringParams.GetValues("validationtoken")[0].ToString(); - httpResponse.Content = new StringContent(validationToken); - - traceWriter.Trace(Request, "SPWebhooks", - TraceLevel.Info, - string.Format("Received validation token: {0}", validationToken)); - return httpResponse; - } - ``` +1. Enter the following as the request URL: + + ```http + https://site-collection/_api/web/lists('list-id')/subscriptions + ``` + +1. Replace _site-collection_ with your site collection. +1. Go to the **Headers** tab. +1. Make sure you still have the **Authorization** header. If not, you need to request a new access token. +1. Add the following header **key** > **value** pairs: + + * **Accept**: `application/json;odata=nometadata` + * **Content-Type**: `application/json` + +1. Go to the **Body** tab and select **raw** format. +1. Paste the following JSON as the body: + + ```json + { + "resource": "https://site-collection/_api/web/lists('list-id')", + "notificationUrl": "https://ngrok-forwarding-address/api/spwebhook/handlerequest", + "expirationDateTime": "2016-10-27T16:17:57+00:00", + "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449" + } + ``` + + ![postman add webhook body](../../images/postman-add-webhook-body.png) + +1. Make sure the **expirationDateTime** is at most 6 months from today. +1. Make sure you are debugging the webhook receiver as in Step 4. +1. Select **Send** to execute the request. + + If the request is successful, you should see the response from SharePoint that provides the subscription details. The following example shows a response for a newly created subscription: + + ```json + { + "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449", + "expirationDateTime": "2016-10-27T16:17:57Z", + "id": "32b95d9-4d20-4a17-bfa3-2957cb38ead8", + "notificationUrl": "https://85557d4b.ngrok.io/api/spwebhook/handlerequest", + "resource": "c34420f9-2ad7-4e54-94c9-b67798d2299b" + } + ``` + +1. Copy the subscription **id**. You will need it for the next set of requests. +1. Go to the webhook receiver project in Visual Studio and examine the **Output** window. You should see the trace logs that look similar to the following trace, along with other messages: + + ```console + iisexpress.exe Information: 0 : Message='Received client state: A0A354EC-97D4-4D83-9DDB-144077ADB449' + iisexpress.exe Information: 0 : Message='Received validation token: daf2803c-43cf-44c7-8dff-7066eaa40f13' + ``` + + The trace indicates that the webhook received initially received a validation request. If you look at the code, you'll see that it returns the validation token immediately so that SharePoint can validate the request: + + ```csharp + if (queryStringParams.AllKeys.Contains("validationtoken")) + { + httpResponse = new HttpResponseMessage(HttpStatusCode.OK); + validationToken = queryStringParams.GetValues("validationtoken")[0].ToString(); + httpResponse.Content = new StringContent(validationToken); + + traceWriter.Trace(Request, "SPWebhooks", + TraceLevel.Info, + string.Format("Received validation token: {0}", validationToken)); + return httpResponse; + } + ``` ## Step 6: Get subscription details Now you'll run queries in Postman to get the subscription details. 1. Open the Postman client. +1. Change the request to **GET** from **POST**. +1. Enter the following as the request: -2. Change the request to **GET** from **POST**. - -3. Enter the following as the request: - - ``` - https://site-collection/_api/web/lists('list-id')/subscriptions - ``` - -4. Replace _site-collection_ with your site collection. + ```http + https://site-collection/_api/web/lists('list-id')/subscriptions + ``` -5. Select **Send** to execute the request. +1. Replace _site-collection_ with your site collection. +1. Select **Send** to execute the request. - If successful, you should see SharePoint return the subscriptions for this list resource. Because we just added one, you should at least see one subscription returned. The following example shows a response with one subscription: + If successful, you should see SharePoint return the subscriptions for this list resource. Because we just added one, you should at least see one subscription returned. The following example shows a response with one subscription: - ```json - { - "value": [ - { - "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449", - "expirationDateTime": "2016-10-27T16:17:57Z", - "id": "32b95add-4d20-4a17-bfa3-2957cb38ead8", - "notificationUrl": "https://85557d4b.ngrok.io/api/spwebhook/handlerequest", - "resource": "c34420f9-2a67-4e54-94c9-b67798229f9b" - } - ] - } - ``` + ```json + { + "value": [ + { + "clientState": "A0A354EC-97D4-4D83-9DDB-144077ADB449", + "expirationDateTime": "2016-10-27T16:17:57Z", + "id": "32b95add-4d20-4a17-bfa3-2957cb38ead8", + "notificationUrl": "https://85557d4b.ngrok.io/api/spwebhook/handlerequest", + "resource": "c34420f9-2a67-4e54-94c9-b67798229f9b" + } + ] + } + ``` -6. Run the following query to get details of the specific subscription: +1. Run the following query to get details of the specific subscription: - ``` - https://site-collection/_api/web/lists('list-id')/subscriptions('subscription-id') - ``` + ```http + https://site-collection/_api/web/lists('list-id')/subscriptions('subscription-id') + ``` -7. Replace `subscription-id` with your subscription id. +1. Replace `subscription-id` with your subscription id. ## Step 7: Test webhook notification Now add a file to the Documents library and test if you get a notification from SharePoint in the webhook receiver. 1. Go to Visual Studio. +1. In the **SPWebhookController**, place a breakpoint on the following line of code: -2. In the **SPWebhookController**, place a breakpoint on the following line of code: - - ```cs - var requestContent = Request.Content.ReadAsStringAsync().Result; - ``` - -3. Go to the **Documents** library. It is named **Shared Documents** library in your default site collection. - -4. Add a new file. - -5. Go to Visual Studio and wait for the breakpoint to be hit. + ```csharp + var requestContent = Request.Content.ReadAsStringAsync().Result; + ``` - The wait time may vary from a few seconds to up to five minutes. When the breakpoint is hit, the webhook receiver has just received a notification from SharePoint. +1. Go to the **Documents** library. It is named **Shared Documents** library in your default site collection. +1. Add a new file. +1. Go to Visual Studio and wait for the breakpoint to be hit. -6. Select **F5** to continue. + The wait time may vary from a few seconds to up to five minutes. When the breakpoint is hit, the webhook receiver has just received a notification from SharePoint. -7. To see the notification data, look in the **Output** window for the following entries, since you added the notification data into the trace log: +1. Select **F5** to continue. +1. To see the notification data, look in the **Output** window for the following entries, since you added the notification data into the trace log: - ``` - iisexpress.exe Information: 0 : Message='Resource: c34420f9-2a67-4e54-94c9-b6770892299b' - iisexpress.exe Information: 0 : Message='SubscriptionId: 32b95ad9-4d20-4a17-bfa3-2957cb38ead8' - iisexpress.exe Information: 0 : Message='TenantId: 7a17cb7d-6898-423f-8839-45f363076f06' - iisexpress.exe Information: 0 : Message='SiteUrl: /' - iisexpress.exe Information: 0 : Message='WebId: 62b80e0b-f889-4974-a519-cc138413be40' - iisexpress.exe Information: 0 : Message='ExpirationDateTime: 2016-10-27T16:17:57.0000000Z' - ``` + ```console + iisexpress.exe Information: 0 : Message='Resource: c34420f9-2a67-4e54-94c9-b6770892299b' + iisexpress.exe Information: 0 : Message='SubscriptionId: 32b95ad9-4d20-4a17-bfa3-2957cb38ead8' + iisexpress.exe Information: 0 : Message='TenantId: 7a17cb7d-6898-423f-8839-45f363076f06' + iisexpress.exe Information: 0 : Message='SiteUrl: /' + iisexpress.exe Information: 0 : Message='WebId: 62b80e0b-f889-4974-a519-cc138413be40' + iisexpress.exe Information: 0 : Message='ExpirationDateTime: 2016-10-27T16:17:57.0000000Z' + ``` -This project only writes the information to the trace log. However, in your receiver, you send this information into a table or a queue that can process the received data to get information from SharePoint. +This project only writes the information to the trace log. However, in your receiver, you send this information into a table or a queue that can process the received data to get information from SharePoint. With this data, you can construct the URL and use the [GetChanges](https://msdn.microsoft.com/library/office/dn531433.aspx#bk_ListGetChanges) API to get the latest changes. diff --git a/docs/apis/webhooks/lists/create-subscription.md b/docs/apis/webhooks/lists/create-subscription.md index 065537129..bab6f9320 100644 --- a/docs/apis/webhooks/lists/create-subscription.md +++ b/docs/apis/webhooks/lists/create-subscription.md @@ -1,15 +1,12 @@ --- title: Create a new subscription description: Creates a new webhook subscription on a SharePoint list. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 10/20/2020 +ms.localizationpriority: high --- +# Create a new subscription - -# Create a new subscription - -Creates a new webhook subscription on a SharePoint list. +Creates a new webhook subscription on a SharePoint list. ## Permissions @@ -19,7 +16,7 @@ The application must have at least edit permissions to the SharePoint list where You must grant the Azure AD app the permissions specified in the following table: -Application | Permission +Application | Permission ------------|------------ Office 365 SharePoint Online|Read and write items and lists in all site collections. @@ -27,13 +24,13 @@ Office 365 SharePoint Online|Read and write items and lists in all site collecti You must grant the SharePoint Add-in the following permission(s) or higher: -Scope | Permission rights +Scope | Permission rights ------|------------ List|Manage ## HTTP request -``` +```http POST /_api/web/lists('list-id')/subscriptions ``` @@ -41,7 +38,7 @@ POST /_api/web/lists('list-id')/subscriptions Include the following properties in the request body. -Name | Type | Description +Name | Type | Description -----|------|------------ resource|string|The URL of the list to receive notifications from. notificationUrl|string|The service URL to send notifications to. @@ -75,7 +72,7 @@ Content-Type: application/json { "id": "a8e6d5e6-9f7f-497a-b97f-8ffe8f559dc7", - "expirationDateTime": "2016-04-27T16:17:57Z", + "expirationDateTime": "2016-04-27T16:17:57Z", "notificationUrl": "https://91e383a5.ngrok.io/api/webhook/handlerequest", "resource": "5c77031a-9621-4dfc-bb5d-57803a94e91d" } @@ -83,9 +80,16 @@ Content-Type: application/json ## URL validation -Before a new subscription is created, SharePoint sends a request with a validation token in the body of the request to the service URL provided. Your service must respond to this request by returning the validation token. +> [!IMPORTANT] +> Before a new subscription is created, SharePoint sends a request with a validation token in the querystring of the request to the notification URL provided. Your service must respond to this request by returning the validation token. If your service fails to validate the request in this way, the subscription is not created.** -If your service fails to validate the request in this way, the subscription is not created. +### Example + +```csharp +{ + return new OkObjectResult(req.Query["validationtoken"].ToString()); +} +``` ## See also diff --git a/docs/apis/webhooks/lists/delete-subscription.md b/docs/apis/webhooks/lists/delete-subscription.md index 5d60d8a5b..397d90237 100644 --- a/docs/apis/webhooks/lists/delete-subscription.md +++ b/docs/apis/webhooks/lists/delete-subscription.md @@ -1,12 +1,9 @@ --- title: Delete a subscription description: Deletes a webhook subscription from a SharePoint list. After deleting the subscription, notifications are no longer delivered. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Normal +ms.date: 09/23/2022 +ms.localizationpriority: medium --- - - # Delete a subscription Deletes a webhook subscription from a SharePoint list. After deleting the subscription, notifications are no longer delivered. @@ -19,7 +16,7 @@ The application must have at least edit permissions to the SharePoint list where You must grant the Azure AD app the permissions specified in the following table. A subscription can only be deleted by the Azure AD application that created it. -Application | Permission +Application | Permission ------------|------------ Office 365 SharePoint Online|Read and write items and lists in all site collections. @@ -27,7 +24,7 @@ Office 365 SharePoint Online|Read and write items and lists in all site collecti You must grant the SharePoint Add-in the following permission(s) or higher. A subscription can only be deleted by the SharePoint Add-in that created it. -Scope | Permission rights +Scope | Permission rights ------|------------ List|Manage diff --git a/docs/apis/webhooks/lists/get-subscription.md b/docs/apis/webhooks/lists/get-subscription.md index bb0f36b52..661e9076e 100644 --- a/docs/apis/webhooks/lists/get-subscription.md +++ b/docs/apis/webhooks/lists/get-subscription.md @@ -1,12 +1,9 @@ --- title: Get subscriptions description: Gets one or more webhook subscriptions on a SharePoint list. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Normal +ms.date: 09/23/2022 +ms.localizationpriority: medium --- - - # Get subscriptions Gets one or more webhook subscriptions on a SharePoint list. @@ -19,17 +16,17 @@ The application must have at least edit permissions to the SharePoint list where #### If your application is a Microsoft Azure Active Directory (Azure AD) application -You must grant the Azure AD application the permissions specified in the following table. A subscription can only be retrieved by the Azure AD application that created it. +You must grant the Azure AD application the permissions specified in the following table. A subscription can only be retrieved by the Azure AD application that created it. -Application | Permission +Application | Permission ------------|------------ Office 365 SharePoint Online|Read and write items and lists in all site collections. #### If your application is a SharePoint Add-in -You must grant the SharePoint Add-in the following permission(s) or higher. A subscription can only be retrieved by the SharePoint Add-in that created it. +You must grant the SharePoint Add-in the following permission(s) or higher. A subscription can only be retrieved by the SharePoint Add-in that created it. -Scope | Permission rights +Scope | Permission rights ------|------------ List|Manage @@ -39,17 +36,17 @@ The application must have manage list permissions to the SharePoint list where t #### If your application is an Azure AD application -You must grant the Azure AD app the permissions specified in the following table. +You must grant the Azure AD app the permissions specified in the following table. -Application | Permission +Application | Permission ------------|------------ Office 365 SharePoint Online|Have full control of all site collections. #### If your application is a SharePoint Add-in -You must grant the SharePoint Add-in the following permission(s) or higher. +You must grant the SharePoint Add-in the following permission(s) or higher. -Scope | Permission rights +Scope | Permission rights ------|------------ List|Full control @@ -111,7 +108,7 @@ Do not supply a request body for this method. #### Response -This returns a collection of all subscriptions on a SharePoint resource. +This returns a collection of all subscriptions on a SharePoint resource. ```http HTTP/1.1 200 OK diff --git a/docs/apis/webhooks/lists/overview-sharepoint-list-webhooks.md b/docs/apis/webhooks/lists/overview-sharepoint-list-webhooks.md index 0aeab4115..f8d775112 100644 --- a/docs/apis/webhooks/lists/overview-sharepoint-list-webhooks.md +++ b/docs/apis/webhooks/lists/overview-sharepoint-list-webhooks.md @@ -1,19 +1,16 @@ --- title: SharePoint list webhooks description: List webhooks cover the events corresponding to list item changes for a given SharePoint list or a document library. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 09/23/2022 +ms.localizationpriority: high --- - - # SharePoint list webhooks The SharePoint list webhooks cover the events corresponding to list item changes for a given SharePoint list or a document library. SharePoint webhooks provide a simple notification pipeline so your application can be aware of changes to a SharePoint list without polling the service. ## Tasks -| Task | HTTP method | +| Task | HTTP method | |-----------------------------------------------------|--------------------------------------------------------| | [Create a new subscription](./create-subscription.md) | `POST /_api/web/lists('list-guid')/subscriptions` | | [Get subscriptions](./get-subscription.md) | `GET /_api/web/lists('list-guid')/subscriptions` | diff --git a/docs/apis/webhooks/lists/update-subscription.md b/docs/apis/webhooks/lists/update-subscription.md index 2b1673568..6ba4aa7a7 100644 --- a/docs/apis/webhooks/lists/update-subscription.md +++ b/docs/apis/webhooks/lists/update-subscription.md @@ -1,33 +1,30 @@ --- title: Update a subscription description: Updates a webhook subscription on a SharePoint list. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Normal +ms.date: 09/23/2022 +ms.localizationpriority: medium --- - - # Update a subscription Updates a webhook subscription on a SharePoint list. ## Permissions -The application must have at least edit permissions to the SharePoint list where the subscription will be updated. +The application must have at least edit permissions to the SharePoint list where the subscription will be updated. ### If your application is a Microsoft Azure Active Directory (Azure AD) application You must grant the Azure AD application the permissions specified in the following table. A subscription can only be updated by the Azure AD application that created it. -Application | Permission +Application | Permission ------------|------------ -Office 365 SharePoint Online|Read and write items and lists in all site collections. +Office 365 SharePoint Online|Read and write items and lists in all site collections. ### If your application is a SharePoint Add-in You must grant the SharePoint Add-in the following permission(s) or higher. A subscription can only be updated by the SharePoint Add-in that created it. -Scope | Permission rights +Scope | Permission rights ------|------------ List|Manage @@ -53,11 +50,11 @@ Content-Type: application/json Include the following properties in the request body. -Name | Type | Description +Name | Type | Description -----|------|------------ notificationUrl|string|The service URL to send notifications to. expirationDateTime|date|The date the notification will expire and be deleted. -client-clientState|string|Optional. Opaque string passed back to the client on all notifications.
You can use this for validating notifications or tagging different subscriptions. +clientState|string|Optional. Opaque string passed back to the client on all notifications.
You can use this for validating notifications or tagging different subscriptions. ## Response diff --git a/docs/apis/webhooks/overview-sharepoint-webhooks.md b/docs/apis/webhooks/overview-sharepoint-webhooks.md index ef2ba04a2..190a3a4ea 100644 --- a/docs/apis/webhooks/overview-sharepoint-webhooks.md +++ b/docs/apis/webhooks/overview-sharepoint-webhooks.md @@ -1,27 +1,24 @@ --- title: Overview of SharePoint webhooks description: Build applications that subscribe to receive notifications on specific events that occur in SharePoint. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 09/23/2022 +ms.localizationpriority: high --- - - # Overview of SharePoint webhooks SharePoint webhooks enable developers to build applications that subscribe to receive notifications on specific events that occur in SharePoint. When an event is triggered, SharePoint sends an HTTP POST payload to the subscriber. Webhooks are easier to develop and consume than Windows Communication Foundation (WCF) services used by SharePoint Add-in remote event receivers because webhooks are regular HTTP services (web API). -Currently webhooks are only enabled for SharePoint list items. SharePoint list item webhooks cover the events corresponding to list item changes for a given SharePoint list or a document library. SharePoint webhooks provide a simple notification pipeline so that your application can be aware of changes to a SharePoint list without polling the service. For more information, see [SharePoint list webhooks](./lists/overview-sharepoint-list-webhooks.md). +Currently webhooks are only enabled for SharePoint list items. SharePoint list item webhooks cover the events corresponding to list item changes for a given SharePoint list or a document library. SharePoint webhooks provide a simple notification pipeline so that your application can be aware of changes to a SharePoint list without polling the service. For more information, see [SharePoint list webhooks](./lists/overview-sharepoint-list-webhooks.md). ## Creating webhooks -To create a new SharePoint webhook, you add a new subscription to the specific SharePoint resource, such as a SharePoint list. +To create a new SharePoint webhook, you add a new subscription to the specific SharePoint resource, such as a SharePoint list. The following information is required for creating a new subscription: - **Resource**. The resource endpoint URL you are creating the subscription for. For example, a SharePoint List API URL. - **Server notification URL**. Your service endpoint URL. SharePoint sends an HTTP POST to this endpoint when events occur in the specified resource. -- **Expiration date**. The expiration date for your subscription. The expiration date should not be more than 180 days. By default, subscriptions are set to expire 180 days from when they are created. +- **Expiration date**. The expiration date for your subscription. The expiration date should not be more than 180 days. By default, subscriptions are set to expire 180 days from when they are created. You can also include the following information if needed: @@ -145,9 +142,9 @@ If an error occurs while sending the notification to your application, SharePoin ## Expiration -Webhook subscriptions are set to expire after 180 days by default if an **expirationDateTime** value is not specified. +Webhook subscriptions are set to expire after 180 days by default if an **expirationDateTime** value is not specified. -You need to set an expiration date when creating the subscription. The expiration date should be less than 180 days. Your application is expected to handle the expiration date according to your application's needs by updating the subscription periodically. +You need to set an expiration date when creating the subscription. The expiration date should be less than 180 days. Your application is expected to handle the expiration date according to your application's needs by updating the subscription periodically. ## Retry mechanism diff --git a/docs/apis/webhooks/sharepoint-webhooks-using-azd-template.md b/docs/apis/webhooks/sharepoint-webhooks-using-azd-template.md new file mode 100644 index 000000000..1de5d665e --- /dev/null +++ b/docs/apis/webhooks/sharepoint-webhooks-using-azd-template.md @@ -0,0 +1,178 @@ +--- +title: Create Azure Functions for SharePoint webhooks using an azd template +description: Use Azure Developer cli (azd) to deploy an Azure function app that connects to your SharePoint Online + tenant, to register and manage webhooks, and process the notifications from SharePoint. +ms.date: 07/07/2025 +ms.localizationpriority: low +--- +# Azure Functions for SharePoint webhooks using azd + +[Azure Developer CLI (azd)](https://aka.ms/azd) is an open-source tool that accelerates provisioning and deploying app resources in Azure. + +This article uses the [Azure function app for SharePoint webhooks public template](https://github.com/Azure-Samples/azd-functions-sharepoint-webhooks) to deploy an Azure function app that connects to your SharePoint Online tenant, to register and manage [webhooks](overview-sharepoint-webhooks.md), and process the notifications from SharePoint. + +## Prerequisites + +- [Node.js 22](https://www.nodejs.org/) +- [Azure Functions Core Tools](/azure/azure-functions/functions-run-local) +- [Azure Developer CLI (azd)](/azure/developer/azure-developer-cli/install-azd) +- An Azure subscription that trusts the same Microsoft Entra ID directory as the SharePoint tenant + +## Permissions required to provision the resources in Azure + +The account running **azd** must have at least the following roles to successfully provision the resources: + +- Azure role **[Contributor](/azure/role-based-access-control/built-in-roles/privileged#contributor)**: To create all the resources needed +- Azure role **[Role Based Access Control Administrator](/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator)**: To assign roles (to access the storage account and Application Insights) to the managed identity of the function app + +## Deploy the function app in Azure + +1. Run **azd init** from an empty local (root) folder: + + ```console + azd init --template azd-functions-sharepoint-webhooks + ``` + + Enter an environment name, such as **spofuncs-quickstart** when prompted. In **azd**, the environment is used to maintain a unique deployment context for your app. + +1. Open the file **infra/main.parameters.json**, and set the variables `TenantPrefix` and `siteRelativePath` to match your SharePoint tenant. + + Review the article on [Manage environment variables](/azure/developer/azure-developer-cli/manage-environment-variables) to manage the azd's environment variables. + +1. Finally, run the command **azd up** to build the app, provision the resources in Azure and deploy the app package. + +## Grant the function app access to SharePoint Online + +The authentication to SharePoint is done using `DefaultAzureCredential`, so the credential used depends on whether the function app runs locally, or in Azure. + +If you never heard about `DefaultAzureCredential`, you should familiarize yourself with its concept by referring to the section **Use DefaultAzureCredential for flexibility** in [Credential chains in the Azure Identity client library for JavaScript](/azure/developer/javascript/sdk/authentication/credential-chains). + +### Using its managed identity + +`DefaultAzureCredential` will use a managed identity to authenticate to SharePoint. This may be the existing, system-assigned managed identity of the function app service or a user-assigned managed identity. + +This tutorial assumes the system-assigned managed identity is used. + +#### Grant the SharePoint API permission Sites.Selected to the managed identity + +Navigate to your function app in the [Azure portal](https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.Web%2Fsites/kind/functionapp) > select **Identity** and note the **Object (principal) ID** of the system-assigned managed identity. + +> [!NOTE] +> In this tutorial, it is **d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8**. + +Then, use one of the scripts below to grant this identity the app-only permission **Sites.Selected** on the SharePoint API: + +> [!IMPORTANT] +> The scripts below require at least the delegated permission [`AppRoleAssignment.ReadWrite.All`](/graph/permissions-reference#approleassignmentreadwriteall) (requires admin consent) + +
+ Using the Microsoft Graph PowerShell SDK + +```powershell +# This script requires the modules Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns, which can be installed with the cmdlet Install-Module below: +# Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Applications, Microsoft.Graph.Identity.SignIns -Scope CurrentUser -Repository PSGallery -Force +Connect-MgGraph -Scope "Application.Read.All", "AppRoleAssignment.ReadWrite.All" +$managedIdentityObjectId = "d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity +$scopeName = "Sites.Selected" +$resourceAppPrincipalObj = Get-MgServicePrincipal -Filter "displayName eq 'Office 365 SharePoint Online'" # SPO +$targetAppPrincipalAppRole = $resourceAppPrincipalObj.AppRoles | ? Value -eq $scopeName + +$appRoleAssignment = @{ + "principalId" = $managedIdentityObjectId + "resourceId" = $resourceAppPrincipalObj.Id + "appRoleId" = $targetAppPrincipalAppRole.Id +} +New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityObjectId -BodyParameter $appRoleAssignment | Format-List +``` +
+ +
+ Using az cli in Bash + +```bash +managedIdentityObjectId="d3e8dc41-94f2-4b0f-82ff-ed03c363f0f8" # 'Object (principal) ID' of the managed identity +resourceServicePrincipalId=$(az ad sp list --query '[].[id]' --filter "displayName eq 'Office 365 SharePoint Online'" -o tsv) +resourceServicePrincipalAppRoleId="$(az ad sp show --id $resourceServicePrincipalId --query "appRoles[?starts_with(value, 'Sites.Selected')].[id]" -o tsv)" + +az rest --method POST --uri "https://graph.microsoft.com/v1.0/servicePrincipals/${managedIdentityObjectId}/appRoleAssignments" --headers 'Content-Type=application/json' --body "{ 'principalId': '${managedIdentityObjectId}', 'resourceId': '${resourceServicePrincipalId}', 'appRoleId': '${resourceServicePrincipalAppRoleId}' }" +``` +
+ +#### Grant the managed identity effective access to a SharePoint site + +Navigate to the [Enterprise applications](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/) > Set the **Application type** filter to **Managed Identities** > select your managed identity and note its **Application ID**. + +> [!NOTE] +> In this tutorial, it is **3150363e-afbe-421f-9785-9d5404c5ae34**. + +Then, use one of the scripts below to grant it the app-only permission **manage** (minimum required to register a webhook) on a specific SharePoint site: + +> [!IMPORTANT] +> The app registration used to run those scripts must have at least the following permissions: +> +> - Delegated permission **Application.ReadWrite.All** in the Graph API (requires admin consent) +> - Delegated permission **AllSites.FullControl** in the SharePoint API (requires admin consent) + +
+ Using PnP PowerShell + +[PnP PowerShell](https://pnp.github.io/powershell/cmdlets/Grant-PnPAzureADAppSitePermission.html) + +```powershell +Connect-PnPOnline -Url "https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME" -Interactive -ClientId "YOUR_PNP_APP_CLIENT_ID" +Grant-PnPAzureADAppSitePermission -AppId "3150363e-afbe-421f-9785-9d5404c5ae34" -DisplayName "YOUR_FUNC_APP_NAME" -Permissions Manage +``` +
+ +
+ Using m365 cli in Bash + +[m365 cli](https://pnp.github.io/cli-microsoft365/cmd/spo/site/site-apppermission-add/) + +```bash +targetapp="3150363e-afbe-421f-9785-9d5404c5ae34" +siteUrl="https://YOUR_SHAREPOINT_TENANT_PREFIX.sharepoint.com/sites/YOUR_SHAREPOINT_SITE_NAME" +m365 spo site apppermission add --appId $targetapp --permission manage --siteUrl $siteUrl +``` +
+ +## Call the function app + +For security reasons, when running in Azure, the function app requires an app key to pass in the query string parameter **code**. The app keys are found in the function app service's **App Keys** keys page. + +Most HTTP functions take optional parameters `TenantPrefix` and `siteRelativePath`. If they are not specified, the values in the app's environment variables are used. + +Below is a sample script in PowerShell to call the function app: + +```powershell +# Edit those variables to match your environment +$funchost = "YOUR_FUNC_APP_NAME" +$code = "YOUR_HOST_KEY" +$listTitle = "YOUR_SHAREPOINT_LIST" +$notificationUrl = "https://${funchost}.azurewebsites.net/api/webhooks/service?code=${code}" + +# List all the webhooks registered on a list +Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/list?code=${code}&listTitle=${listTitle}" + +# Register a webhook in a list +Invoke-RestMethod -Method POST -Uri "https://${funchost}.azurewebsites.net/api/webhooks/register?code=${code}&listTitle=${listTitle}¬ificationUrl=${notificationUrl}" + +# Show this webhook registered on a list +Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/show?code=${code}&listTitle=${listTitle}¬ificationUrl=${notificationUrl}" + +# Remove the webhook from a list +# Step 1: Call the function /webhooks/show to get the webhook id +$webhookId = $(Invoke-RestMethod -Method GET -Uri "https://${funchost}.azurewebsites.net/api/webhooks/show?code=${code}&listTitle=${listTitle}¬ificationUrl=${notificationUrl}").Id +# Step 2: Call the function /webhooks/remove and pass the webhook id +Invoke-RestMethod -Method POST -Uri "https://${funchost}.azurewebsites.net/api/webhooks/remove?code=${code}&listTitle=${listTitle}&webhookId=${webhookId}" +``` + +## Cleanup the resources in Azure + +You can delete all the resources this project created in Azure, by running the command **azd down**. + +Alternatively, you can delete the resource group, that has the azd environment's name by default. + +## See also + +- [Overview of SharePoint webhooks](overview-sharepoint-webhooks.md) diff --git a/docs/apis/webhooks/sharepoint-webhooks-using-azure-functions.md b/docs/apis/webhooks/sharepoint-webhooks-using-azure-functions.md index 6309e5fd7..967d0e43d 100644 --- a/docs/apis/webhooks/sharepoint-webhooks-using-azure-functions.md +++ b/docs/apis/webhooks/sharepoint-webhooks-using-azure-functions.md @@ -1,206 +1,242 @@ --- title: Using Azure Functions with SharePoint webhooks description: Set up and use Azure Functions for your webhooks to take care of the hosting and scaling of your function. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 09/23/2022 +ms.localizationpriority: high --- - - # Using Azure Functions with SharePoint webhooks -[Azure Functions](https://docs.microsoft.com/azure/azure-functions/functions-overview) offers an easy way to host your SharePoint webhooks: you can simply add your webhook C# or JavaScript code via the browser, and Azure takes care of the hosting and scaling of your function. This guide shows how to set up and use Azure Functions for your webhooks. +[Azure Functions](/azure/azure-functions/functions-overview) offers an easy way to host your SharePoint webhooks: you can add your webhook C# or JavaScript code via the browser, and Azure takes care of the hosting and scaling of your function. + +This guide shows how to set up and use Azure Functions for your webhooks using the Azure portal. Alternatively, you can refer to article [Create Azure Functions for SharePoint webhooks using an azd template](sharepoint-webhooks-using-azd-template.md), to automate the whole process using an **azd** template. ## Create an Azure Function App -The first step you need to do is create an Azure Function App, which is a special kind of Azure Web App focused on hosting Azure Functions. +The first step you need to do is to create an Azure Function App, which is a special Azure Web App focused on hosting Azure Functions. + +1. Navigate to [https://portal.azure.com](https://portal.azure.com), search for **function app**. Select **Function App** from the search results. + + ![Creating an Azure Function App](../../images/webhook-azure-function00.png) -1. Navigate to [https://portal.azure.com](https://portal.azure.com), select **New**, and then search for **Function App**. +1. Click the **Add** option. - ![Creating an Azure Function App](../../images/webhook-azure-function0.png) + ![Add Azure Function App](../../images/webhook-azure-function01.png) -2. Select **Function App**, and then complete the information needed to create the Function App: +1. Complete the information needed to create the Function App, then click **Review + create**. - ![Complete Azure Function App details](../../images/webhook-azure-function1.png) + ![Fill in Azure Function App details](../../images/webhook-azure-function08.png) + +1. Click **Create** + + ![Azure Function App Confirmation Page](../../images/webhook-azure-function09.png) + +1. When the deployment is completed click **Go to resource**. + + ![Azure Function App Completed Page](../../images/webhook-azure-function10.png) ## Create an Azure Function -1. Now that the app to host the functions is ready, you can continue with creating your first Azure Function by selecting the **New Function** link. +Now that the app to host the functions is ready, you can continue with creating your first Azure Function by clicking the **New function** link. + +![Azure Function App Landing Page](../../images/webhook-azure-function02.png) - ![Adding an Azure Function](../../images/webhook-azure-function2.png) +This offers you to start your function from a template; for SharePoint webhooks, we need an HTTP triggered function, and because we're writing C# code in our sample, this means we're using the **HttpTrigger-CSharp** function template. - This offers you to start your function from a template; in the case of SharePoint webhooks, we need an HTTP triggered function, and because we are writing C# code in our sample, this means we're using the **HttpTrigger-CSharp** function template. Given that SharePoint webhook services need to be anonymously callable, it's important to switch the **Authorization level** to **Anonymous**. +1. Select the **In-portal** development environment option then click **Continue**. - ![Choosing an Azure Function template](../../images/webhook-azure-function3.png) + ![Select Development Environment Page](../../images/webhook-azure-function03.png) - > [!NOTE] - > - Using the **GenericWebHook** template does not yet work for SharePoint webhooks, but the SharePoint product team is aware of this problem and will address it. - > - If you get "Failed to validate the notification URL" errors when using your Azure function-based webhook, you might be able to resolve this by setting the Authorization level to **Function** and defining your function for anonymous access. - > - Java language functions cannot currently validate the webhook callback due to lack of asynchronous support. This should be added by Azure Functions v2 general avalibility as seen [here](https://github.com/Azure/azure-functions-java-worker/issues/83) +1. Select **Webhook + API** trigger type then click **Create**. -
+ ![Select Trigger Type Page](../../images/webhook-azure-function11.png) The result is a "default" Azure Function written in C#. - ![The default Azure Function](../../images/webhook-azure-function4.png) + ![Development Environment Page Showing Default C# Code](../../images/webhook-azure-function04.png) -2. In our case, we want this Azure Function to behave as a SharePoint webhook service, so we need to implement the following in C#: - - Return the validationtoken if specified as a URL parameter to the call. This is needed as described at [Create a new subscription](./lists/create-subscription.md), and SharePoint expects the reply to happen within 5 seconds. - - Process the JSON webhook notification. In the following sample, we've opted to store the JSON in a storage queue so that an Azure Web Job can pick it up and process it asynchronously. Depending on your needs, you could also process the notification directly in your webhook service, but keep in mind that all webhook service calls need to complete in 5 seconds; hence, using an asynchronous model is recommended. +In our case, we want this Azure Function to behave as a SharePoint webhook service, so we need to implement the following in C#: -3. You can achieve this by replacing the default code with the following code (please enter your storage account connection string and update the queue name if you're using a different one): +- Return the **validationtoken** if specified as a URL parameter to the call. This is needed as described at [Create a new subscription](./lists/create-subscription.md), and SharePoint expects the reply to happen within 5 seconds. +- Process the JSON webhook notification. In the following sample, we've opted to store the JSON in a storage queue so that an Azure Web Job can pick it up and process it asynchronously. +- Depending on your needs, you could also process the notification directly in your webhook service, but keep in mind that all webhook service calls need to complete in 5 seconds; so using an asynchronous model is recommended. -```cs +You can achieve this by replacing the default code with the following code: + +```csharp #r "Newtonsoft.Json" -#r "Microsoft.WindowsAzure.Storage" -using System; using System.Net; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Primitives; using Newtonsoft.Json; -using Microsoft.WindowsAzure; -using Microsoft.WindowsAzure.Storage; -using Microsoft.WindowsAzure.Storage.Queue; -public static async Task Run(HttpRequestMessage req, TraceWriter log) +public static async Task Run(HttpRequest req, + ICollector outputQueueItem, ILogger log) { - log.Info($"Webhook was triggered!"); - - // Grab the validationToken URL parameter - string validationToken = req.GetQueryNameValuePairs() - .FirstOrDefault(q => string.Compare(q.Key, "validationtoken", true) == 0) - .Value; - - // If a validation token is present, we need to respond within 5 seconds by - // returning the given validation token. This only happens when a new - // web hook is being added - if (validationToken != null) - { - log.Info($"Validation token {validationToken} received"); - var response = req.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(validationToken); - return response; - } - - log.Info($"SharePoint triggered our webhook...great :-)"); - var content = await req.Content.ReadAsStringAsync(); - log.Info($"Received following payload: {content}"); - - var notifications = JsonConvert.DeserializeObject>(content).Value; - log.Info($"Found {notifications.Count} notifications"); - - if (notifications.Count > 0) + log.LogInformation($"Webhook was triggered!"); + + // Grab the validationToken URL parameter + string validationToken = req.Query["validationtoken"]; + + // If a validation token is present, we need to respond within 5 seconds by + // returning the given validation token. This only happens when a new + // webhook is being added + if (validationToken != null) + { + log.LogInformation($"Validation token {validationToken} received"); + return (ActionResult)new OkObjectResult(validationToken); + } + + log.LogInformation($"SharePoint triggered our webhook...great :-)"); + var content = await new StreamReader(req.Body).ReadToEndAsync(); + log.LogInformation($"Received following payload: {content}"); + + var notifications = JsonConvert.DeserializeObject>(content).Value; + log.LogInformation($"Found {notifications.Count} notifications"); + + if (notifications.Count > 0) + { + log.LogInformation($"Processing notifications..."); + foreach(var notification in notifications) { - log.Info($"Processing notifications..."); - foreach(var notification in notifications) - { - CloudStorageAccount storageAccount = CloudStorageAccount.Parse(""); - // Get queue... create if does not exist. - CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); - CloudQueue queue = queueClient.GetQueueReference("sharepointlistwebhookeventazuread"); - queue.CreateIfNotExists(); - - // add message to the queue - string message = JsonConvert.SerializeObject(notification); - log.Info($"Before adding a message to the queue. Message content: {message}"); - queue.AddMessage(new CloudQueueMessage(message)); - log.Info($"Message added :-)"); - } + // add message to the queue + string message = JsonConvert.SerializeObject(notification); + log.LogInformation($"Before adding a message to the queue. Message content: {message}"); + outputQueueItem.Add(message); + log.LogInformation($"Message added :-)"); } + } - // if we get here we assume the request was well received - return new HttpResponseMessage(HttpStatusCode.OK); + // if we get here we assume the request was well received + return (ActionResult)new OkObjectResult($"Added to queue"); } - // supporting classes public class ResponseModel { - [JsonProperty(PropertyName = "value")] - public List Value { get; set; } + [JsonProperty(PropertyName = "value")] + public List Value { get; set; } } public class NotificationModel { - [JsonProperty(PropertyName = "subscriptionId")] - public string SubscriptionId { get; set; } + [JsonProperty(PropertyName = "subscriptionId")] + public string SubscriptionId { get; set; } - [JsonProperty(PropertyName = "clientState")] - public string ClientState { get; set; } + [JsonProperty(PropertyName = "clientState")] + public string ClientState { get; set; } - [JsonProperty(PropertyName = "expirationDateTime")] - public DateTime ExpirationDateTime { get; set; } + [JsonProperty(PropertyName = "expirationDateTime")] + public DateTime ExpirationDateTime { get; set; } - [JsonProperty(PropertyName = "resource")] - public string Resource { get; set; } + [JsonProperty(PropertyName = "resource")] + public string Resource { get; set; } - [JsonProperty(PropertyName = "tenantId")] - public string TenantId { get; set; } + [JsonProperty(PropertyName = "tenantId")] + public string TenantId { get; set; } - [JsonProperty(PropertyName = "siteUrl")] - public string SiteUrl { get; set; } + [JsonProperty(PropertyName = "siteUrl")] + public string SiteUrl { get; set; } - [JsonProperty(PropertyName = "webId")] - public string WebId { get; set; } + [JsonProperty(PropertyName = "webId")] + public string WebId { get; set; } } public class SubscriptionModel { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string Id { get; set; } + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public string Id { get; set; } - [JsonProperty(PropertyName = "clientState", NullValueHandling = NullValueHandling.Ignore)] - public string ClientState { get; set; } + [JsonProperty(PropertyName = "clientState", NullValueHandling = NullValueHandling.Ignore)] + public string ClientState { get; set; } - [JsonProperty(PropertyName = "expirationDateTime")] - public DateTime ExpirationDateTime { get; set; } + [JsonProperty(PropertyName = "expirationDateTime")] + public DateTime ExpirationDateTime { get; set; } - [JsonProperty(PropertyName = "notificationUrl")] - public string NotificationUrl {get;set;} + [JsonProperty(PropertyName = "notificationUrl")] + public string NotificationUrl {get;set;} - [JsonProperty(PropertyName = "resource", NullValueHandling = NullValueHandling.Ignore)] - public string Resource { get; set; } + [JsonProperty(PropertyName = "resource", NullValueHandling = NullValueHandling.Ignore)] + public string Resource { get; set; } } ``` ## Configure your Azure Function -Because we've chosen the correct template to start from, our configuration is almost complete. The only thing you still need to do is to switch the **Allowed HTTP methods** to **Selected methods**, and then only allow the **POST** HTTP method. Also cross-check that **Mode** is equal to **Standard**, and **Authorization level** is set to **Anonymous**. +Because we've chosen the correct template to start from, our configuration is almost complete. The only thing you still need to do is to configure the Azure Queue Storage as an Output binding so that we can add messages to the queue as they come in. + +1. Select **Integrate** and then **New Output** to add the output binding. + + ![Azure Function Integration Settings](../../images/webhook-azure-function12.png) + +1. Select **Azure Queue Storage** as the binding type and then click **Select**. -![Azure Function settings](../../images/webhook-azure-function5.png) + ![Azure Function Binding Selection](../../images/webhook-azure-function13.png) + +1. Click **Save**. + + ![Azure Function Azure Queue Storage Settings](../../images/webhook-azure-function05.png) + +## Test your Azure Function (Validation Token Test) -## Test your Azure Function You're now all set for your first Azure Function test. -1. Navigate to the **Develop** screen. +1. Navigate back to the code screen by clicking on the name of the function **HttpTrigger1** in the navigation panel. Then click the **Test** tab to open the test panel on the right. + + ![Navigate To Azure Function Test Panel](../../images/webhook-azure-function14.png) + +1. Add a URL parameter **validationtoken** with a random string as value. + +Using this setup, we're mimicking the behavior of SharePoint by calling your webhook service when validating a new webhook addition. + +Click **Run** to test... + +![Set Up Azure Function validationToken Test](../../images/webhook-azure-function15.png) + +If everything goes well, you'll see in the logs section that your service was called and that it returned the passed value with an HTTP 200 response. + +![validationToken Test Results](../../images/webhook-azure-function16.png) -2. Select the **Test** icon to open the test pane on the right, and add a URL parameter "validationtoken" with a random string as value. +## Test your Azure Function (SharePoint List Event Test) -3. Using this setup, we're mimicking the behavior of SharePoint by calling your web hook service when validating a new webhook addition. Select **Run** to test...if everything goes well, you'll see in the logs section that your service was called and that it returned the passed value with an HTTP 200 response. +Now for the second test. This will test your function as if it was called by a SharePoint list event. -![Azure Function testing](../../images/webhook-azure-function6.png) +1. In the Test panel, clear the **validationtoken** URL parameter and replace the Request body with the following JSON object. Then click **Run**. + +```Json +{ + "value": [{ + "subscriptionId":"1111111111-3ef7-4917-ada1-xxxxxxxxxxxxx", + "clientState":null, + "expirationDateTime":"2020-06-14T16:22:51.2160000Z","resource":"xxxxxx-c0ba-4063-a078-xxxxxxxxx","tenantId":"4e2a1952-1ed1-4da3-85a6-xxxxxxxxxx", + "siteUrl":"/sites/webhooktest", + "webId":"xxxxx-3a7c-417b-964e-39f421c55d59" + }] +} +``` + +If everything is OK, you should see all the log messages including the one that indicates that the message was added to the queue. + +![Webhook Notification Test Results](../../images/webhook-azure-function17.png) ## Grab the webhook URL to use in your implementation We'll need to let SharePoint know what webhook URL we're using. To do so, let's start by copying the Azure Function URL. -![Azure Function authorization codes](../../images/webhook-azure-function8.png) - -
+1. Click **Get function URL**. -To avoid unathorized usage of your Azure Function, the caller needs to specify a code when calling your function. This code can be retrieved via the **Manage** screen. + ![Log message console](../../images/webhook-azure-function07.png) -![Azure Function webhook URL](../../images/webhook-azure-function7.png) +1. Click **Copy** to copy the Azure Function App URL to your clipboard. -
+ ![Get Function URL Link](../../images/webhook-azure-function18.png) So in our case the webhook URL to use is the following: -```https://pnp-functions.azurewebsites.net/api/spwebhookfunction?code=wyx9iAxp3o7fdGFZTbnp9Kfc5o2UhlzwgSOT/XGGM6QZcdYYa/o9aw== +```https +https://fa-acto-spwebhook-dev-westus.azurewebsites.net/api/HttpTrigger1?code=LTFbMHrbVVQkhbL2xUplGRmY5XnAI9q/E4s5jvfeIh00KsF9Y7QsJw== ``` ## See also - [Overview of SharePoint webhooks](overview-sharepoint-webhooks.md) - - - diff --git a/docs/apis/webhooks/webhooks-reference-implementation.md b/docs/apis/webhooks/webhooks-reference-implementation.md index c69946a02..f6285aaf7 100644 --- a/docs/apis/webhooks/webhooks-reference-implementation.md +++ b/docs/apis/webhooks/webhooks-reference-implementation.md @@ -1,46 +1,38 @@ --- title: SharePoint webhooks sample reference implementation -description: This SharePoint Patterns and Practices (PnP) reference implementation shows how you can use SharePoint webhooks in your application. -ms.date: 02/08/2018 -ms.prod: sharepoint -localization_priority: Priority +description: This SharePoint Patterns and Practices (PnP) reference implementation shows how you can use SharePoint webhooks in your application. +ms.date: 06/05/2024 +ms.localizationpriority: high --- - - # SharePoint webhooks sample reference implementation The SharePoint Patterns and Practices (PnP) reference implementation shows how you can use SharePoint webhooks in your application. The webhooks are implemented in an enterprise ready manner using various Microsoft Azure components such as Azure Web Jobs, Azure SQL Server, and Azure Storage Queues for asynchronous web job notification handling. -The reference implementation only works with [SharePoint list webhooks](./lists/overview-sharepoint-list-webhooks.md). +The reference implementation only works with [SharePoint list webhooks](./lists/overview-sharepoint-list-webhooks.md). -You can also follow these steps by watching the video on the SharePoint PnP YouTube Channel: - -
+You can also follow these steps by watching the video on the Microsoft 365 Platform Community (PnP) YouTube Channel: > [!Video https://www.youtube.com/embed/P4a1_EWokwM] -
- **Applies to** Office 365 Multi Tenant (MT). -Microsoft Azure is used to host the various components needed to implement Azure webhooks. +Microsoft Azure is used to host the various components needed to implement SharePoint webhooks. + +Source code and other materials for the reference implementation are available in two flavors: -Source code and other materials for the reference implementation are available in two flavors: - A SharePoint provider-hosted application version -- An Office 365 Azure AD application, which can be found in the [SharePoint developer samples GitHub repository](https://aka.ms/sp-webhooks-sample-reference). +- An Office 365 Azure AD application, which can be found in the [SharePoint developer samples GitHub repository](https://aka.ms/sp-webhooks-sample-reference). ## Deploy the reference implementation -The application shows you how to manage webhooks, specifically for a SharePoint list. It also contains a reference implementation of a webhook service endpoint that you can reuse in your webhook projects. +The application shows you how to manage webhooks, specifically for a SharePoint list. It also contains a reference implementation of a webhook service endpoint that you can reuse in your webhook projects. ![SharePoint webhook reference implementation application](../../images/webhook-sample-application.png) ### Deployment guides -- The [SharePoint web hooks reference implementation deployment guide](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/Deployment%20guide.md) lists the deployment steps used to deploy the SharePoint provider-hosted reference implementation. - -- To deploy the Office 365 Azure AD application, use the steps described at [SharePoint web hooks Azure AD reference implementation deployment guide](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List.AzureAD/Deployment%20guide.md), which shows you how to use a Web API function as webhook service. - +- The [SharePoint webhooks reference implementation deployment guide](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/Deployment%20guide.md) lists the deployment steps used to deploy the SharePoint provider-hosted reference implementation. +- To deploy the Office 365 Azure AD application, use the steps described at [SharePoint webhooks Azure AD reference implementation deployment guide](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List.AzureAD/Deployment%20guide.md), which shows you how to use a Web API function as webhook service. - If you're more interested in using Azure Functions, see the [Azure Functions guide](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List.AzureAD/azure%20functions%20guide.md) for more details on how to use Azure Functions in this reference implementation. ### Introduction to webhooks @@ -51,9 +43,9 @@ Webhooks notify your application about changes in SharePoint that the applicatio The reference implementation works with a SharePoint list. To add a webhook to a SharePoint list, your application first creates a webhook subscription by sending a [`POST /_api/web/lists('list-id')/subscriptions`](./lists/create-subscription.md) request. The request includes the following items: -* A payload that identifies the list that you're adding the webhook for. -* The location of your webhook service URL to send the notifications. -* The expiration date of the webhook. +- A payload that identifies the list that you're adding the webhook for. +- The location of your webhook service URL to send the notifications. +- The expiration date of the webhook. After you've requested SharePoint to add your webhook, SharePoint validates that your webhook service endpoint exists. It sends a validation string to your service endpoint. SharePoint expects that your service endpoint returns the validation string within 5 seconds. If this process fails, the webhook creation is canceled. If you've deployed your service, this works and SharePoint returns an HTTP 201 message on the POST request that the application initially sent. The payload in the response contains the ID of the new webhook subscription. @@ -61,7 +53,7 @@ After you've requested SharePoint to add your webhook, SharePoint validates that Take a look at the reference implementation, and you'll see that all webhook CRUD operations are consolidated in the [WebHookManager](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/SharePoint.WebHooks.Common/WebHookManager.cs) class of the **SharePoint.WebHooks.Common** project. Adding a webhook is done by using the **AddListWebHookAsync** method: -```cs +```csharp /// /// This method adds a webhook to a SharePoint list. Note that you need your webhook endpoint being passed into this method to be up and running and reachable from the internet /// @@ -77,11 +69,9 @@ public async Task AddListWebHookAsync(string siteUrl, string } ``` -
- When making a call to SharePoint, you need to provide authentication information, and in this case you're using a **Bearer** authentication header with an **access token**. To obtain the access token, intercept the token via an **ExecutingWebRequest** event handler: -```cs +```csharp ClientContext cc = null; // Create SharePoint ClientContext object... @@ -92,7 +82,7 @@ cc.ExecutingWebRequest += Cc_ExecutingWebRequest; // Capture the OAuth access token since we want to reuse that one in our REST requests private void Cc_ExecutingWebRequest(object sender, WebRequestEventArgs e) { - this.accessToken = e.WebRequestExecutor.RequestHeaders.Get("Authorization").Replace("Bearer ", ""); + this.accessToken = e.WebRequestExecutor.RequestHeaders.Get("Authorization").Replace("Bearer ", ""); } ``` @@ -119,14 +109,13 @@ In the previous step, your service endpoint was called, but SharePoint only prov ![Async GetChanges](../../images/webhook-sample-async-getchanges.png) -You can learn more about the `GetChanges()` implementation in the **ProcessNotification** method in the [ChangeManager](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/SharePoint.WebHooks.Common/ChangeManager.cs) class of the **SharePoint.WebHooks.Common** project. +You can learn more about the `GetChanges()` implementation in the **ProcessNotification** method in the [ChangeManager](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/SharePoint.WebHooks.Common/ChangeManager.cs) class of the **SharePoint.WebHooks.Common** project. To avoid getting the same change repeatedly, it's important that you inform SharePoint from which point you want the changes. This is done by passing a **changeToken**, which also implies that your service endpoint needs to persist the last used **changeToken** so that it can be used the next time the service endpoint is called. The following are some key things to note about changes: - SharePoint does not call your service in real-time: when a change happens on a list that has a webhook, SharePoint queues a webhook callout. Once each minute, this queue is read and the appropriate service endpoints are called. This batching of requests is important. For example, if a bulk upload of 1000 records occurred at once, batching prevents SharePoint from calling your endpoint 1000 times. So your endpoint is only called once, but when you call the `GetChanges()` method, you get 1000 change events that you need to process. - - To guarantee an immediate response, regardless of the number of changes there, it's important that the workload of your service endpoint runs asynchronously. In the reference implementation, we leveraged the power of Azure: the service serializes the incoming payload and stores it in an Azure Storage queue while there's an Azure web job that runs continuously and checks for messages in the queue. When there are messages in the queue, the web job processes them and also executes your logic asynchronously. ## Complete end-to-end flow @@ -136,14 +125,14 @@ The following diagram describes the complete end-to-end webhook flow. ![Webhooks reference implementation end-to-end flow](../../images/webhook-sample-end-to-end-flow.png) 1. Your application creates a webhook subscription. When it does, it gets the current **changeToken** from the list it created the webhook for. -2. Your application persists the **changeToken** in a persistent storage, such as SQL Azure in this case. -3. A change in SharePoint occurs, and SharePoint calls your service endpoint. -4. Your service endpoint serializes the notification request and stores it in a storage queue. -5. Your web job sees the message in the queue and starts your message processing logic. -6. Your message processing logic retrieves the last used change token from the persistent storage. -7. Your message processing logic uses the `GetChanges()`API to determine what changed. -8. The returned changes are processed and now your application performs what it needs to do based on the changes. -9. Finally, the application persists the last retrieved **changeToken** so that next time it does not receive changes that were already processed. +1. Your application persists the **changeToken** in a persistent storage, such as SQL Azure in this case. +1. A change in SharePoint occurs, and SharePoint calls your service endpoint. +1. Your service endpoint serializes the notification request and stores it in a storage queue. +1. Your web job sees the message in the queue and starts your message processing logic. +1. Your message processing logic retrieves the last used change token from the persistent storage. +1. Your message processing logic uses the `GetChanges()`API to determine what changed. +1. The returned changes are processed and now your application performs what it needs to do based on the changes. +1. Finally, the application persists the last retrieved **changeToken** so that next time it does not receive changes that were already processed. ## Work with webhook renewal @@ -155,14 +144,14 @@ When your service receives a notification, it also gets information about the su ### Reliable but more complex model -Create a web job that on a weekly basis reads all the subscription IDs from the persistent storage. One-by-one extend the found subscriptions each time. +Create a web job that on a weekly basis reads all the subscription IDs from the persistent storage. One-by-one extend the found subscriptions each time. > [!NOTE] > This web job is not part of this reference implementation. -The actual renewal of a SharePoint list webhook can be done by using a [`PATCH /_api/web/lists('list-id')/subscriptions(‘subscriptionID’)`](./lists/update-subscription.md) REST call. +The actual renewal of a SharePoint list webhook can be done by using a [`PATCH /_api/web/lists('list-id')/subscriptions(‘subscriptionID’)`](./lists/update-subscription.md) REST call. -In the reference implementation, updating of webhooks is implemented in the [WebHookManager](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/SharePoint.WebHooks.Common/WebHookManager.cs) class of the **SharePoint.WebHooks.Common** project. +In the reference implementation, updating of webhooks is implemented in the [WebHookManager](https://github.com/SharePoint/sp-dev-samples/blob/master/Samples/WebHooks.List/SharePoint.WebHooks.Common/WebHookManager.cs) class of the **SharePoint.WebHooks.Common** project. Updating a webhook is done by using the **UpdateListWebHookAsync** method: @@ -179,7 +168,7 @@ Updating a webhook is done by using the **UpdateListWebHookAsync** method: /// true if successful, exception in case something went wrong public async Task UpdateListWebHookAsync(string siteUrl, string listId, string subscriptionId, string webHookEndPoint, DateTime expirationDateTime, string accessToken) { - // webhook update code... + // webhook update code... } ``` @@ -187,10 +176,8 @@ public async Task UpdateListWebHookAsync(string siteUrl, string listId, st Because SharePoint is calling out to your webhook service endpoint, your endpoint needs to be reachable by SharePoint. This makes development and debugging slightly more complex. The following are some strategies that you can use to make your life easier: -* During initial development, you provide your own serialized payload to your service processing logic. This makes it possible to completely test your processing logic without deploying the service endpoint (and even without configuring a webhook). - -* If you have access to Azure resources, you can deploy your endpoint to Azure by using a debug build and configuring the Azure App Service for debugging. This allows you to set a remote breakpoint and do remote debugging using Visual Studio. - +- During initial development, you provide your own serialized payload to your service processing logic. This makes it possible to completely test your processing logic without deploying the service endpoint (and even without configuring a webhook). +- If you have access to Azure resources, you can deploy your endpoint to Azure by using a debug build and configuring the Azure App Service for debugging. This allows you to set a remote breakpoint and do remote debugging using Visual Studio. - If you do not want to deploy your service during development time, you need to use a secure tunnel for your service. The idea is that you tell SharePoint that the notification service is located on a shared public endpoint. In the client, you install a component that connects to that shared public service, and whenever a call is made to the public endpoint, the client component is notified and it pushes the payload to your service running on localhost. [ngrok](https://ngrok.com/) is an implementation of such a secure tunnel tool that you can use to debug your webhook service locally. ## See also diff --git a/docs/business-apps/flow/get-started/connect-to-other-services-in-your-flow.md b/docs/business-apps/flow/get-started/connect-to-other-services-in-your-flow.md deleted file mode 100644 index 7eac027db..000000000 --- a/docs/business-apps/flow/get-started/connect-to-other-services-in-your-flow.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Connect your flow to other services -description: Connect your flow to 200+ services available in Microsoft Flow and build an integrated experience to perform actions in the services. -ms.date: 12/12/2018 -ms.prod: sharepoint -localization_priority: Priority ---- - -# Connect your flow to other services - -Connect your flow to 200+ services available in Microsoft Flow and build an integrated experience to perform actions in the services. This article continues building the *Projects* list flow built in the previous article *Create your first flow*. - -## Connect to Microsoft Teams - -In this article, we will connect to Microsoft Teams and post a message to one of the channels. - -> **Note:** While this article focusses on Microsoft Teams, you can connect to various other services as well in your flow. - -### Edit the flow - -1. Switch to the flow designer tab in your browser. - -2. If you do not have the flow designer tab opened, then follow the steps to open the flow: - * Browse to the *Projects* list. - * Click on *Flow* and then *See your flows*. - * If promoted, sign in with your Office 365 account. - * Click on *Send an email for new projects* flow in the *My flows* tab. - * Click on *Edit flow* to edit the flow. - -3. Click on *+ New step* in the flow designer. - -4. Click on *Add an action*. - -5. This will open the actions list where you can search and browse for various actions available in Flow. - -6. In the search box, type *Teams* to search for Teams based actions. - -7. In the results, click on *Microsoft Teams* connector to filter the actions to just Teams. - -8. In the available actions list, click on *Microsoft Teams - Post message*. - > Click on the information icon to read more about the action and what it does. - - ![Add Team connector actions in your flow](../../../images/gs02-microsoft-teams-connector.png) - -9. As soon as the action is added, Flow will try to create the Teams connection. Once the connection is created successfully, you should see the action with the available inputs. - - ![Microsoft Teams post messsage action](../../../images/gs02-microsoft-teams-post-message-action.png) - -10. To see the connection information, click on the `...` button and check the *My connections* section to see the connection information the Teams action is using. - -11. Enter the inputs for the Teams action. - * Team Id: Pick a team from the picker. - * Channel Id: Pick a channel from the picker. - -12. In order to construct a message that includes the project information, we will need to interact with the dynamic conetent panel. In the *Message*, type the following in the same order as below: - * First type the text: *A new project * - * In the dynamic content list, search and pick the following property: *Title* - * Then type the text: * was added to the Projects list by * - * In the dynamic content list, search and pick the following property: *Created By DisplayName.* - - ![Microsoft Teams post messsage action with input values](../../../images/gs02-microsoft-teams-post-message-with-inputs.png) - -13. Click *Save* on the command bar to save your flow. - -## Test your flow - -1. Click *Test* on the command bar. - -2. Click on Using data from previous runs*. Since* we already had previous runs of this flow in the previous article, we can select the same data for this flow run as well. - - ![Test your flow using data from previous runs](../../../images/gs02-test-your-flow-previous-runs.png) - -3. Click on the flow run that says *Succeeded* and then click *Save & Test*. - -4. Flow will now run and you should see the status of each action updated successfully in the designer. - -5. As a result of this flow run, you should have received an email and a message should be posted on the selected Teams channel. - -## Next steps - -In the next topic, we will use the same flow and add ... . \ No newline at end of file diff --git a/docs/business-apps/flow/get-started/create-your first-flow.md b/docs/business-apps/flow/get-started/create-your first-flow.md deleted file mode 100644 index cd6812a77..000000000 --- a/docs/business-apps/flow/get-started/create-your first-flow.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: Send an email when a new item is created or modified in a SharePoint list -description: Send an email when a new item is created or modified in a SharePoint list -ms.date: 12/12/2018 -ms.prod: sharepoint -localization_priority: Priority ---- - -# Send an email when a new item is created or modified in a SharePoint list - -Using Microsoft Flow you can easily automate day-to-day tasks or build repetetive tasks in SharePoint that help you stay productive. - -In this tutorial, you will create a flow that will send an email when a new item is added or modified in a SharePoint list. - -## Required setup - -Before following the steps in this artucle, make sure your SharePoint site is set up with the required lists and libraries. - -## Create a flow - -1. Browse to the *Projects* list in your SharePoint site. - -2. You can create and manage flows for a list or a library by clicking on the *Flow* button on the command bar on the list or library page. - -3. Clicking on the *Flow* button exapnds to show you more options: - - * Create a flow - * See your flows - - > **Note:** You may see other options as well such as 'Request sign-off' and other flows if they are available for the list or library here. - - ![Create a flow from Projects list](../../../images/gs01-create-a-flow-command-bar.png) - -4. Click on *Create a flow*. - -5. In the *Create a flow* panel, you can explore various templates available for your list. - - ![Create a flow panel in lists](../../../images/gs01-create-a-flow-panel.png) - -6. Click on the template that reads: - > Send a customized email when a new SharePoint list item is added. - -7. This will take you to the Flow website where it will display more options: - * Template information - * Name and description of the template. - * Connection information - * Varioius services this flow connect to. - * The credentials those services will use to connect to. -8. Verify the connection information to ensure it uses your credentials. - > A green checkmark icon indicates a connection to the service was succesfully made using your credentials. - - ![Flow template - send email when an item is added in a list](../../../images/gs01-create-a-flow-when-item-is-added-template.png) - -9. Click *Continue* to create the flow. Any connections that requires a connection will also be attempted during this step. - -10. Once the flow is created successfully, you will be redirected to the flow designer where you can edit and modifify the flow if needed. - - ![Flow designer - send email when an item is added in a list](../../../images/gs01-designer-when-item-is-added-template.png) - -11. Click on the name of the flow that reads *Send a customized email when a new SharePoint list item is added* and enter the following name for the flow: - * Send an email for new projects - -12. The SharePoint actions are represented with the SharePoint logo in the flow designer. - -13. In the *When the new item is created* action, click on *Edit* to expand the action. - -14. Notice the input configured to the SharePoint site address and list name from where you created the flow. - -15. In the *Send Email* action, click on *Edit* to expand the action. - -16. Notice all the input is filled in with dynamic values from the *Get my profile* and *When the new item is created* actions. - -17. Hover over the dynamic values to see what properties they refer. For example, hovering over the *Email* shows that the property is read from the *Get my profile*'s *Mail* property. - - ![Flow designer - hover to see dynamic content](../../../images/gs01-designer-hover-dynamic-content.png) - -18. Click *Save* to save the flow. - -Your flow is active as soon as you save the flow. In our case, this flow *Send an email for new projects* is now active and will run whenever new items are added to the *Projects* list in the specified SharePoint site. - -## Test your flow - -In order to test your flow, you can test it by adding a new item in SharePoint list by adding a new item or initiating the test run directly from the flow designer. Follow the steps below to test the flow from the designer. Testing the flow from the designer helps you to quickly see the flow run as the flow is executed. - -1. In the flow designer, click on *Test* on the top command bar. - -2. In the *Test Flow* panel, click on *I'll perform the trigger action* and then click on *Save & Test* button. - - ![Flow designer - hover to see dynamic content](../../../images/gs01-designer-test-flow.png) - -3. You should see a message that instructs to add a new list item to the SharePoint list you selected. - - ![Flow designer - test flow message](../../../images/gs01-designer-test-flow-message.png) - -4. You should have the browser tab with the *Projects* list opened already. If not, open a new browser tab and browse to the *Projects* list. - > Do not close the flow designer. Make sure you keep the flow designer browser tab open. - -5. In the *Projects* list, click on the *New* button on the command bar, add the item as specified below and click *Save*: - * Title: Project 4 - * Owner: pick a user from people picker - -6. Switch to the flow designer tab. - -7. You should see the flow run history. If all of the actions were executed successfully, you will a green checkmark icon besides every action. - - ![Flow designer - flow run history](../../../images/gs01-designer-test-flow-run.png) - -8. You can also click on the action to see the inputs and outputs used in the flow run. This is also a good place to see the actual values translated from those dynamic content properties used in that action. - -9. As a result of this flow, you should have received an email as well regarding the new project information. - -## Modify your flow - -1. In the flow designer, click *Edit* to edit your flow. - -2. Click on the *Send Email* action. - -3. In the *Body* input, append the following string after the *Name* dynamic property: - * Owner: - -4. While you are still editing the *Body* input, notice the *dynamic content* list that appears beside the action. - -5. In the *dynamic content* list, you can pick values from the actions in your flow. For example: The project owner information is available in the *When the new item is created* trigger. - -6. To add the owner information, search for *owner* in the search box in the *dynamic content* list. - - ![Flow designer - add owner dynamic content](../../../images/gs01-designer-append-owner-dynamic-content.png) - -7. In the results, click on *Owner DisplayName*. As you can see, it also displays other information such as email, job title, picture and more. Since the *Owner* is a person column in SharePoint, SharePoint passes along the person details as individual properties to the flow. - -8. The modified *Body* input should now look like this with the included *Owner* information. - - ![Flow designer - add owner dynamic content](../../../images/gs01-designer-email-body-with-owner.png) - -9. Repeat the steps to test the flow. - -10. You should now get an email with the updated owner information in it. - -## Next steps - -Congratulations on creating your first flow! - -In the next topic, we will use the same flow and add the ability to interact with Microsoft Teams. \ No newline at end of file diff --git a/docs/business-apps/flow/get-started/set-up-sharepoint-site.md b/docs/business-apps/flow/get-started/set-up-sharepoint-site.md deleted file mode 100644 index 28fb504c2..000000000 --- a/docs/business-apps/flow/get-started/set-up-sharepoint-site.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Set up your SharePoint site with lists and libraries -description: Set up your SharePoint site with lists and libraries -ms.date: 12/12/2018 -ms.prod: sharepoint -localization_priority: Priority ---- - -# Set up your SharePoint site with lists and libraries - -In order to successfully complete the getting started tutorials, set up your SharePoint site with the following. - -## Projects list - -Create a new SharePoint list called *Projects*. Follow the steps below to create a new SharePoint list. - -### Create a new list - -1. Browse to a modern SharePoint site in your Office 365 tenant. - -> **Note:** You can choose to use either a modern Team Site or a Communications Site. - -1. In the command bar, click on *New->List* -2. In the *Create list* panel, enter the following and click *Create* to create the list: - - * **Name:** Projects - * **Description:** Projects list. -3. You will be automatically redirected to the *Projects* list. -4. Click on *+ Add column* and then select *Person* column type to add an *Owner* column to the list. -5. In the *Create a column* panel, enter the following and click *Save* to add the column to the Projects list: - - * **Name:** Owner - * **Description:** Project owner. -6. The new *Owner* column will now be available in the Projects list. - -### Add new project items - -Click on *New* button in the list command bar and add the following list items: - -* Item 1 - * **Title:** Project 1 - * **Owner:** pick a user from people picker - -* Item 2 - * **Title:** Project 2 - * **Owner:** pick a user from people picker - -* Item 3 - * **Title:** Project 3 - * **Owner:** pick a user from people picker - -## Next steps - -Now that you have set up your SharePoint site with the lists and libraries, you are ready to build your first flow. \ No newline at end of file diff --git a/docs/business-apps/get-started/set-up-sharepoint-site-lists-libraries.md b/docs/business-apps/get-started/set-up-sharepoint-site-lists-libraries.md new file mode 100644 index 000000000..6bdb52272 --- /dev/null +++ b/docs/business-apps/get-started/set-up-sharepoint-site-lists-libraries.md @@ -0,0 +1,68 @@ +--- +title: Set up your SharePoint site with lists and libraries +description: Set up your SharePoint site with lists and libraries +ms.date: 6/23/2020 +ms.localizationpriority: high +--- + +# Set up your SharePoint site with lists and libraries + +To successfully complete the *Getting Started* tutorials, set up your SharePoint site with the following items. + +## Microsoft 365 tenant + +To use Power Automate and build flows, you need a Microsoft 365 tenant. + +If you already have an Office 365 tenant, see section **Create Projects list** below. + +For step-by-step instructions about how to join the Microsoft 365 Developer Program and sign up and configure your subscription, see the [Office 365 Developer Program documentation](/office/developer-program/office-365-developer-program). + +## Create Projects list + +Create a new SharePoint list called **Projects**. To create a new SharePoint list, follow these steps. + +### Create a new list + +1. In your Microsoft 365 tenant, browse to a modern SharePoint site. + + > [!NOTE] + > You can use either a modern Teams site or a Communications site. + +1. In the command bar, select **New** > **List**. +1. In the **Create list** panel, enter the following: + + * **Name**: Projects + +1. To create the list, select **Create**. + + You are automatically redirected to the **Projects** list. + +1. Select **+ Add column**, and to add an **Owner** column to the list, and then select the **Person** column type. +1. In the **Create a column** panel, enter the following: + + * **Name**: Owner + * **Description**: Project owner + +1. To add the column to the Projects list, select **Save**. The new **Owner** column becomes available in the **Projects** list. + +### Add new project items + +In the List command bar, select **New**, and add the following list items: + +* Item 1 + * **Title**: Project 1 + * **Owner**: Select a user from people picker + +* Item 2 + * **Title**: Project 2 + * **Owner**: Select a user from people picker + +* Item 3 + * **Title**: Project 3 + * **Owner**: pick a user from people picker + +## Next steps + +Now that you have set up your SharePoint site with the lists and libraries, you are ready to build your first flow. + +![Project lists for Getting Started Power Automate tutorials](../../images/flow-tutorials-setup-projects-list.png) diff --git a/docs/business-apps/introduction-to-sharepoint-business-process-integration.md b/docs/business-apps/introduction-to-sharepoint-business-process-integration.md index a2fa7ab21..576208048 100644 --- a/docs/business-apps/introduction-to-sharepoint-business-process-integration.md +++ b/docs/business-apps/introduction-to-sharepoint-business-process-integration.md @@ -1,46 +1,51 @@ --- -title: SharePoint custom forms and automated business workflow -description: SharePoint custom forms and automated business workflow. -ms.date: 02/02/2018 -ms.prod: sharepoint -localization_priority: Priority +title: Business apps and business process automation +description: Business apps and business process automation. +ms.date: 06/28/2022 +ms.service: sharepoint-online +ms.localizationpriority: high --- -# SharePoint custom forms and automated business workflow +# Business apps and business process automation -Creativity and teamwork are essential to transforming business process. Most processes center on content – files and data. SharePoint gives you tools to gather and manage data in lists and libraries. +Creativity and teamwork are essential to transforming business processes. Most processes center on content – files and data. SharePoint offers tools to gather and manage data in lists and libraries. -Office 365 provides connections to a range of third-party systems with Microsoft Flow and PowerApps. Flow lets you easily automate business processes and PowerApps lets you create great forms and mobile apps based on SharePoint files and data. Both PowerApps and Flow feature intuitive visual designers, so anyone can craft forms and screens in an easy-to-use interface. +Microsoft 365 provides connections to a range of third-party systems with Power Automate and Power Apps. Power Automate lets you automate business processes, and Power Apps lets you create great forms and mobile apps based on SharePoint files and data. Both Power Automate and Power Apps feature intuitive visual designers, so anyone can craft forms and screens using a convenient interface. -## Microsoft Flow +## Power Automate -Using Microsoft Flow, you can create workflows through an easy-to-use visual designer that will guide you through each step and help authenticate your accounts. +Using Power Automate, you can create workflows through an easy-to-use visual designer that will guide you through each step and help authenticate your accounts. -Select from dozens of pre-made templates also available in Flow to start automating your app’s usage. Here are just a few applications of these templates: +Select from dozens of pre-made templates to start automating your app’s usage. Here are just a few applications of these templates: -* Create a new record in Dynamics CRM when a new list item is added to a SharePoint list. +* Create a new record in Microsoft Dynamics CRM when a new list item is added to a SharePoint list. * Copy new members from MailChimp lists to SharePoint lists. * Move files to different folders after they’re approved in SharePoint. * Create a new item in SharePoint when a new order is added in Salesforce. -* Route finished documents to a team for approval +* Route finished documents to a team for approval. -Whether you start with a template or begin from scratch, using Flow to create automation features is intuitive and easy to understand. +Whether you start with a template or begin from scratch, using Power Automate to create automation features is intuitive. -Cross-tool functionality seamlessly moves your data from one operation to another. Since SharePoint is a core piece of the Office 365 suite,your data easily integrates with tools like Excel or Power BI reporting. And since it uses an Excelinspired expression language, these tools talk with each other, using formula language you already recognize and understand to integrate your data from one function to the next. +## Power Apps -## Microsoft PowerApps +Using Microsoft Power Apps, you can create apps with a point-and-click approach to app design. Options include using automatically-generated, pre-made templates, or customizing the tool to fit your more specific needs. After your app is complete, you can instantly publish it to Windows, the web, iOS, and Android. -Using Microsoft PowerApps, you can create apps with a point-and-click approach to app design. You can use the option to use automatically generated pre-made templates or customize the tool to fit your more specific needs. Then, once your app is complete, you can instantly publish it to Windows, the web, iOS, and Android. +Classic mobile and web apps typically required separate coding for each platform, which can be costly and time-consuming to do—especially with developers in high demand. Instead, Power Apps simplifies the process so anyone can do it. Its easy-to-use, browser-based visual designer helps you rapidly build custom business apps without having to write any code. -Classic mobile and web apps typically required separate coding for each platform, which can be costly and time-consuming to do—especially since programmers are currently in high demand. Instead, PowerApps simplifies the process so anyone can do it. Its easy-to-use, browser-based visual designer helps you rapidly build custom business apps without having to write any code. +By connecting Power Apps to your existing systems and data, you can quickly build reports, forms, and workflows, and then publish your app instantly to all users in your organization. -By connecting PowerApps to your existing systems and data, you can quickly build reports, forms, and workflows, then publish your app instantly to all users in your organization. +Power Apps also lets you easily customize the form for a SharePoint list. For example, with custom forms, you can: -PowerApps also allows you to easily customize the form for a SharePoint list. With custom forms, you can, for example: +* Show or hide certain fields. +* Reorganize those fields. +* Change the layout of a form. +* Add formatted text and graphics. -* Show or hide certain fields -* Re-organize those fields -* Change the layout of the form -* Add formatted text and graphics +When you publish your changes, the form is embedded within the SharePoint list for use by all of its users. -When you publish your changes, the form is embedded within the SharePoint list for use by all of its users. \ No newline at end of file +Cross-tool functionality seamlessly moves your data from one operation to another. With SharePoint being a core component of the Microsoft 365 suite, your data easily integrates with tools like Excel or Power BI reporting. And because it uses an Excel-inspired expression language, these tools talk with each other, using formula language you already recognize and understand to integrate your data from one function to the next. + +## Next steps + +* [Get started with Power Automate and SharePoint](./power-automate/get-started/create-your-first-flow.md) +* [Get started with Power Apps and SharePoint](/powerapps/maker/canvas-apps/customize-list-form) diff --git a/docs/business-apps/power-apps/get-started/create-your-first-custom-form.md b/docs/business-apps/power-apps/get-started/create-your-first-custom-form.md new file mode 100644 index 000000000..0ec652047 --- /dev/null +++ b/docs/business-apps/power-apps/get-started/create-your-first-custom-form.md @@ -0,0 +1,136 @@ +--- +title: Customize a form for a SharePoint list +description: Customize a form for a SharePoint list +ms.date: 09/27/2022 +ms.localizationpriority: high +--- + +# Customize a form for a SharePoint list + +Using Power Apps, you can easily customize a form for a SharePoint list that works best for your team or organization. + +In this tutorial, you will create a custom form with a user profile photo, a read-only field, and a conditionally-visible field. + +## Required setup + +Before starting, make sure your SharePoint site is set up with the [required lists and libraries](../../get-started/set-up-sharepoint-site-lists-libraries.md). + +## Create a custom form + +1. In your SharePoint site, browse to the **Projects** list. + +1. To create and manage flows for a list or a library, from the command bar, on the list or library page, select **Integrate** > **Power Apps**. More options appear: + + - Create an app + - See all apps + - Customize forms + + ![Create a custom form from Projects list](../../../images/lists-integrate-power-apps-create-app.png) + +1. Select **Customize forms**. The Power Apps studio appears and loads your form onto the canvas. If the **Welcome to Power Apps Studio** dialog box opens, select **Skip**. + + ![Power Apps studio with custom form](../../../images/gs01-power-apps-studio-custom-form.png) + +### Add a user profile photo + +1. On the **Insert** tab, select **Media** > **Image**. An [Image](/powerapps/maker/canvas-apps/controls/control-image) control named **Image1** is added to the canvas and to the [Tree view](/powerapps/maker/model-driven-apps/using-tree-view-on-form) on the left-hand panel. + + ![Add an image in Power Apps studio](../../../images/gs01-power-apps-studio-add-image.png) + +1. To customize the appearance of the image, you can set its properties. + + 1. When you select a control on the canvas, on the right-hand panel, the **Properties** pane associated with the control appears. + + ![Image control with Properties panel](../../../images/gs01-image-control-selected.png) + + 1. Because the image is the profile photo of the owner of the selected item, we recommend you make it the same height as the **Owner_DataCard1** [data card](/powerapps/maker/canvas-apps/working-with-cards). + + 1. With **Image1** selected, in the [formula bar](/powerapps/maker/canvas-apps/working-with-formulas), change the property to **Height**, and enter `Owner_DataCard1.Height` as the formula. **Image1** now has the same height as **Owner_DataCard1**. + + ![Set image height](../../../images/gs01-set-image-height.png) + +1. Set the width of **Image1** to be the same as its height. In the formula bar, change the property to **Width**, and enter `Self.Height` as the formula. + + ![Set image width](../../../images/gs01-set-image-width.png) + +1. Make **Image1** into a circle. In the **Properties** pane, enter a value that is half the height value in the **Border radius** property. + +1. Place **Image1** on the canvas in your desired location. Adjust the widths and heights of other controls or data cards so they do not overlap with **Image1**. + + ![Set image border radius](../../../images/gs01-set-image-border-radius.png) + +1. To change the image of **Image1** from the sample image to the project owner's profile photo, you can use the Office 365 Users connector to retrieve the photo by the owner's email. First, [connect your custom form to the Office 365 Users connector](/powerapps/maker/canvas-apps/connections/connection-office365-users). + +1. To retrieve the project owner's profile photo by email, in the formula bar, change the property to **Image**, and enter `Office365Users.UserPhoto(DataCardValue5.Selected.Email)` as the formula. The user photo from the owner's Office 365 user profile appears in **Image1**. + + ![Set image picture](../../../images/gs01-set-image-picture.png) + + When you change the project owner, **Image1** will update to the user photo of the new owner. + +### Set a field to be view-only + +To make the **Title** field view-only, follow these steps. + + > [!NOTE] + > **Title** is a [predefined card](/powerapps/maker/canvas-apps/controls/control-card), so it is locked by default, and needs to be unlocked. + +1. Select **Title_DataCard1**, toggle the **Properties** pane to the **Advanced** pane, and select **Unlock to manage properties**. + + ![Unlock title data card](../../../images/gs01-unlock-title-data-card.png) + + Alternatively, in the Tree view, right-click **Title_DataCard1**, and select **Unlock**. + +1. Toggle back to the **Properties** pane, and select the **Display mode** field. The formula bar updates to display this property. + + ![Select display mode field](../../../images/gs01-title-property-display-mode.png) + +1. In the formula bar, enter `DisplayMode.View` as the formula. + + ![View-only title](../../../images/gs01-title-data-card-view-only.png) + + Alternatively, in the **Properties** pane, set the value of **Display** mode to **View**. + + **DataCardValue1** is now a view-only field. + +### Set the visibility of a field based on a condition + +To hide the **Attachments** field if the project owner is Nestor Wilke, follow these steps. + +> [!NOTE] +> **Attachments** is a [predefined card](/powerapps/maker/canvas-apps/controls/control-card), so it is locked by default, and needs to be unlocked. + +1. Select **Attachments**, toggle the **Properties** pane to the **Advanced** pane, and select **Unlock to manage properties**. + + ![Unlock attachments data card](../../../images/gs01-unlock-attachments-data-card.png) + + Alternatively, in the Tree view, right-click **Attachments_DataCard1**, and select **Unlock**. + +1. Toggle back to the **Properties** pane, and select the **Visible** field. The formula bar updates to display this property. + + ![Select visible field](../../../images/gs01-attachments-property-visible.png) + +1. In the formula bar, enter the following formula: `If(SharePointIntegration.Selected.Owner.DisplayName = "Nestor Wilke", false, true)` + + ![Enter conditional formula](../../../images/gs01-attachments-conditional-visibility.png) + + If the project owner is Nestor Wilke, then the **Attachments** data card is hidden. Otherwise, it is visible. + + You can write the same conditional logic in multiple ways. For more info, see [Operators and Identifiers in Power Apps](/powerapps/maker/canvas-apps/functions/operators). + +## Publish your custom form + +1. On the **File** tab, select the **Save** tab, and then select **Save**. + + ![Save Power Apps](../../../images/gs01-save-power-apps.png) + + Alternatively, to save your app, press **Ctrl+S** while the canvas is visible. + +1. After you save the app, select **Publish to SharePoint**. + + ![Publish Power Apps](../../../images/gs01-publish-power-apps.png) + + In the dialog box that appears, to confirm, select **Publish to SharePoint**. + + The version of the custom form that appears in SharePoint is the most recently published version. + +1. In SharePoint, verify the intended functionality of your app. diff --git a/docs/business-apps/power-automate/get-started/connect-to-other-services-in-your-flow.md b/docs/business-apps/power-automate/get-started/connect-to-other-services-in-your-flow.md new file mode 100644 index 000000000..40d815c10 --- /dev/null +++ b/docs/business-apps/power-automate/get-started/connect-to-other-services-in-your-flow.md @@ -0,0 +1,76 @@ +--- +title: Connect your flow to other services +description: Connect your flow to 200+ services available in Power Automate, and build an integrated experience to perform actions in the services. +ms.date: 09/23/2022 +ms.service: sharepoint-online +ms.localizationpriority: high +search.app: + - Flow +search.appverid: met150 +--- + +# Connect your flow to other services + +Connect your flow to 200+ services available in Power Automate and build an integrated experience to perform actions in the services. This article continues building the *Projects* list flow built in the previous article, *Create your first flow*. + +## Connect to Microsoft Teams + +In this article, we will connect to Microsoft Teams and post a message to one of the channels. + +> [!NOTE] +>While this article focuses on Microsoft Teams, you can also connect to various other services in your flow. + +### Edit the flow + +1. In your browser, switch to the **flow designer** tab. +1. If you do not have the flow designer tab opened, to open the flow, follow these steps: + * Browse to the **Projects** list. + * Select **Integrate** > **Power Automate** > **See your flows**. + * If prompted, sign in with your Microsoft 365 account. + * In the **My flows** tab, select **Send a customized email when a new SharePoint list item is added** flow. + * To edit the flow, in the **flow details** page, in the top command bar, select **Edit**. +1. In the flow designer, select **+ New step**. +1. In the search box, to search for Teams-based actions, enter **Teams**. +1. In the results, to filter the actions to only *Teams*, select the **Microsoft Teams connector**. + + ![Search for Microsoft Teams connector](../../../images/gs02-choose-action-microsoft-teams-connector.png) + +1. In the available actions list, select **Microsoft Teams - Post message**. + + > [!NOTE] + > To read more about the action and what it does, select the **i** (information icon). + + ![Add Team connector actions in your flow](../../../images/gs02-microsoft-teams-connector.png) + +1. As soon as the action is added, Power Automate begins to create the Teams connection. After the connection is created successfully, the action with the available inputs appears. + + ![Microsoft Teams post messsage action](../../../images/gs02-microsoft-teams-post-message-action.png) + +1. To see the connection information, select **...** (ellipsis icon). To see the connection information the Teams action is using, check the **My connections** section. +1. For the Teams action, enter the inputs: + * Team: From the picker, select a team. + * Channel: From the picker, select a channel. +1. To construct a message that includes the project information, use the dynamic content panel. In the **Message**, enter the following in this same order: + * Enter: **A new project**. + * In the dynamic content list, search and select the following property: **Title**. + * Enter: **was added to the Projects list by**. + * In the dynamic content list, search and select the following property: **Created By DisplayName**. + + ![Microsoft Teams post messsage action with input values](../../../images/gs02-microsoft-teams-post-message-with-inputs.png) + +1. To save your flow, on the command bar, select **Save**. + +## Test your flow + +1. On the command bar, select **Test**. +1. Select **Using data from previous runs**. Because you already had previous runs of this flow in the previous article, you can select the same data for this flow run as well. + + ![Test your flow using data from previous runs](../../../images/gs02-test-your-flow-previous-runs.png) + +1. Select the flow run identified as **Succeeded**, and then select **Save & Test**. +1. Power Automate runs, and the status of each action updated successfully in the designer appears. +1. As a result of this flow run, you receive an email, and a message is posted on the selected Teams channel. + +## Next steps + +Learn new skills and discover Power Automate with step-by-step guidance by exploring learning paths and modules available here: [Power Automate Learning Paths](/training/browse/?term=Power%20Automate&products=power-automate). diff --git a/docs/business-apps/power-automate/get-started/create-your-first-flow.md b/docs/business-apps/power-automate/get-started/create-your-first-flow.md new file mode 100644 index 000000000..77b9f7505 --- /dev/null +++ b/docs/business-apps/power-automate/get-started/create-your-first-flow.md @@ -0,0 +1,137 @@ +--- +title: Send an email when a new item is created or modified in a SharePoint list +description: Send an email when a new item is created or modified in a SharePoint list +ms.date: 06/28/2022 +ms.service: sharepoint-online +ms.localizationpriority: high +search.app: + - Flow +search.appverid: met150 +--- + +# Send an email when a new item is created in a SharePoint list + +Using Power Automate, you can easily automate day-to-day tasks or build repetitive tasks in SharePoint that help you stay productive. + +In this tutorial, you will create a flow that sends an email when a new item is added in a SharePoint list. + +## Required setup + +Before proceeding with these instructions, make sure your SharePoint site is set up with the [required lists and libraries](../../get-started/set-up-sharepoint-site-lists-libraries.md). + +## Create a flow + +1. In your SharePoint site, browse to the **Projects** list. +1. To create and manage flows for a list or a library, from the command bar, on the list or library page, select **Integrate** > **Power Automate**. Selecting **Power Automate** expands to show you more options: + + * Create a flow + * See your flows + * Configure flows + + ![Create a flow from Projects list](../../../images/lists-integrate-power-automate-create-flow.png) + + > [!NOTE] + > If they are available for the list or library here, you may see other options on the **Automate** menu, such as **Set a reminder** and other flows. + +1. Select **Create a flow**. In the **Create a flow** panel, you can explore various templates available for your list. + + ![Create a flow panel in lists](../../../images/gs01-create-a-flow-panel.png) + +1. Select the template that reads: + + > [!NOTE] + > Send a customized email when a new SharePoint list item is added. + + On a new browser tab, the **Power Automate** website appears and displays: + * Template information + * Name and description of the template. + * Connection information + * Various services this flow connect to. + * The credentials those services will use to connect to. + +1. Using the dropdowns, verify the connection information (**SharePoint Site Address** and **SharePoint List Name**) is accurate to ensure it uses your credentials. + + > [!NOTE] + > A green checkmark icon indicates a connection to the service was succesfully made using your credentials. + + ![Flow template - send email when an item is added in a list](../../../images/gs01-create-a-flow-when-item-is-added-template.png) + +1. To create the flow, select **Create Flow**. Any connections that require a connection are also attempted during this step. After you successfully create the flow, the flow details page appears where you can edit and modify the flow, if needed. + + > [!NOTE] + > In this case, this flow that sends an email when new items are added to the list is now active, and runs whenever new items are added to the **Projects** list in the specified SharePoint site. + + ![Flow designer - send email when an item is added in a list - details](../../../images/gs01-when-item-is-added-template-flow-created.png) + +1. Click **Edit** in the top command bar to edit the flow in the flow designer. + + ![Flow designer - send email when an item is added in a list - flow designer](../../../images/gs01-designer-when-item-is-added-template.png) + +1. To expand and view the configured properties, select the When the new item is created trigger. Note the input configured to the SharePoint site address and list name from where you created the flow. +1. In the **Send Email** action, to expand the action, select **Edit**. All the input is filled in with dynamic values from the **Get my profile** and **When the new item is created** actions. +1. Hover over the dynamic values to see what properties they reference. For example, hovering over **Email** shows that the property is read from the **Mail** property in **Get my profile**. + + ![Flow designer - hover to see dynamic content](../../../images/gs01-designer-hover-dynamic-content.png) + +1. To save the flow, select **Save**. + +## Test your flow + +To test your flow, either add a new item in SharePoint list by adding a new item, or initiate the test run directly from the flow designer. To test the flow from the designer, follow these steps. Testing the flow from the designer helps you to quickly see the flow run as the flow is executed. + +1. In the flow designer, on the top command bar, select **Test**. +1. In the **Test Flow** panel, select **I'll perform the trigger action**, and then select **Save & Test**. + + ![Flow designer - Test flow](../../../images/gs01-designer-test-flow.png) + + A message appears instructing you to add a new list item to the SharePoint list you selected. + + ![Flow designer - test flow message](../../../images/gs01-designer-test-flow-message.png) + +1. You should have the browser tab with the **Projects** list opened already. If not, open a new browser tab, and browse to the **Projects** list. + + > [!NOTE] + > Do not close the flow designer. Make sure you keep the flow designer browser tab open. + +1. In the **Projects** list, on the command bar, select **New**, and add the following items, and then select **Save**: + + * Title: Project 4 + * Owner: Select a user from people picker + +1. Switch to the flow designer tab. The flow run history appears. If all of your actions were executed successfully, a green checkmark icon appears aside every action. + + ![Flow designer - flow run history](../../../images/gs01-designer-test-flow-run.png) + +1. Select the action to see the inputs and outputs used in the flow run. This is also a good place to see the actual values translated from those dynamic content properties used in that action. + + As a result of this flow, you receive an email regarding the new project information. + +## Modify your flow + +1. In the flow designer, to edit your flow, select **Edit**. +1. Select the **Send Email** action. +1. In the **Body** input, after the **Name** dynamic property, append the following string: + + * Owner: + +1. While you are still editing the **Body** input, note the **dynamic content** list that appears aside the action. +1. In the **dynamic content** list, select values from the actions in your flow, (for example, in the **When the new item is created** trigger, the project owner information is available. +1. To add the owner information, in the **dynamic content** list, in the search box, search for **owner**. + + ![Flow designer - add owner dynamic content - overview](../../../images/gs01-designer-append-owner-dynamic-content.png) + +1. In the results, select **Owner DisplayName**. As you can see, it also displays other information, such as email, job title, picture and more. Because the **Owner** is a **person** column in SharePoint, SharePoint passes along the person details as individual properties to the flow. + + The modified **Body** input appears like this with the included **Owner** info. + + ![Flow designer - add owner dynamic content - body](../../../images/gs01-designer-email-body-with-owner.png) + +1. To test the flow, repeat these steps. + + You receive an email with the updated owner information in it. + +## Next steps + +Congratulations on creating your first flow! + +In the next topic, we will use the same flow, and add the ability to interact with Microsoft Teams. diff --git a/docs/business-apps/power-automate/guidance/customize-page-approvals.md b/docs/business-apps/power-automate/guidance/customize-page-approvals.md new file mode 100644 index 000000000..72fe0d715 --- /dev/null +++ b/docs/business-apps/power-automate/guidance/customize-page-approvals.md @@ -0,0 +1,46 @@ +--- +title: Customize SharePoint page approvals to meet your needs +description: With the help of flows in Power Automate, you can configure page approval to add to the standard publishing process for a site. The default publishing flow meets your basic needs. +ms.date: 06/28/2022 +search.app: + - Flow +search.appverid: met150 +--- + +# Customize SharePoint page approvals to meet your needs + +With the help of flows in Power Automate, you can configure page approval to add to the standard publishing process for a site. The default publishing flow meets your basic needs. + +However, you can add more processes, or even modify how the approval process works. Because page approvals create a flow, you, as the author of the flow, can modify and add whatever business processes you want. + +To customize the default page approval flow, for a few scenarios, check out the following video: + +> [!Video https://www.youtube.com/embed/pKrHoG70FrM] + +## Create more than one approval flow + +As a site owner, you are not limited to just one approval flow. You can create multiple flows so page authors can choose which flow to request approval. For example, you could have a workflow dedicated to a page, and the other one dedicated to news. + +This approach is much easier than trying to implement all the logic into one flow. + +![Multiple page approvals flow](../../../images/multiple-page-approvals-flow.png) + +## Handle news post + +With the read-only **Promoted State** property, you can easily check if the page submitted for approval is a news or standard page. For example, this is useful for scenarios where you check or enforce approvals for only news, but not for pages. + +![Promoted state](../../../images/promoted-state.png) + +## Auto approve pages + +Its a flow in Power Automate, so you can easily orchestrate it to auto approve requests. In the following scenario, see how you can easily auto approve a page request if the user is a manager who has direct reports. If you're not a manager, the flow goes through the approval process defined in the flow. + +![Auto approve requests for managers in flow](../../../images/auto-approve-requests-for-managers-in-flow.png) + +## Parallel approvals + +Occasionally, the default approval action may not help in tracking and auditing each approval. Alternatively, you can use parallel approvals, include constraints, or apply other processes. You can track, audit and perform other actions within these parallel branches and check if the approval has been approved or rejected. + +![Parallel approvals in flow](../../../images/parallel-approvals-in-flow.png) + +To learn more, see [Create parallel approval workflows with Power Automate](/power-automate/parallel-modern-approvals). diff --git a/docs/business-apps/power-automate/guidance/manage-list-flows.md b/docs/business-apps/power-automate/guidance/manage-list-flows.md new file mode 100644 index 000000000..52416dbef --- /dev/null +++ b/docs/business-apps/power-automate/guidance/manage-list-flows.md @@ -0,0 +1,53 @@ +--- +title: Manage owners and users in your Microsoft list flows with Power Automate +description: Manage owners and users of your Power Automate flows for Microsoft lists. You can see all users of a flow, add new users or owners, and modify existing users or owners. +ms.date: 06/28/2022 +search.app: + - Flow +search.appverid: met150 +--- + +# Manage owners and users in your Microsoft list flows with Power Automate + +Flows in Power Automate let you share your flows with others as owners or run-only users. Owners can modify flows, whereas run-only users can run or execute flows. Users' ability to run flows depends entirely on the trigger, specifically: + +- For a selected item +- For a selected file + +## Managing owners + +To manage flow owners, go to your Power Automate site, and select the desired flow. Note the Owners card in the lower right. On that card, select **See all**. + +![See all owners](../../../images/see-all-owners.png) + +Now you can add people as owners to that flow. Select the **Users and groups** tab, and enter names, email addresses, or user groups. + +![Add owners to flow](../../../images/add-owners-flow.png) + +You can also add the Microsoft list as owners. This means that users who have edit permissions on that list automatically get owner access to the flow. This is a simple way to manage list flows as it helps you to easily share it with your team. + +Select the **SharePoint** tab, select the **Site** from the dropdown, and then select the **list** from the dropdown. The site and list values depend on the trigger and actions you use in your flow. The appropriate sites and lists appear and are available for selection. + +![List owners dropdown](../../../images/list-owners-dropdown.png) + +After you select **Add**, permissions are added to the flow, and these new owner(s) now appear. + +![Add owners dropdown](../../../images/add-owners-dropdown.png) + +## Managing run-only users + +For triggers that support run-only users, below the **Owners** card, a **Manage run-only users** card appears. On the card, select **See all**. + +![Manage run-only users card dropdown](../../../images/manage-run-only-users-card.png) + +Here, you can manage the run-only users or assign the users of the Microsoft list as run-only users. In order to run flows, users must have Edit Permissions on the list. Learn more about [list permissions and permission levels](/sharepoint/understanding-permission-levels#list-permissions-and-permission-levels). + +![Manage run-only permissions](../../../images/manage-run-only-permissions.png) + +As an added bonus, you can also select the option for run-only users to provide their connection. This means that when the flow runs, the context of the user running the flow is passed instead of using the connection configured in the flow. This is very useful when you want items or documents created based on the user. + +## Seeing your shared flows + +After you share a flow, the flow becomes a Team flow. These flows appear under the **Team flows** tab on the Power Automate site. + +![Team flows](../../../images/team-flows.png) diff --git a/docs/business-apps/power-automate/guidance/manage-list-item-file-permissions.md b/docs/business-apps/power-automate/guidance/manage-list-item-file-permissions.md new file mode 100644 index 000000000..2a5f77c7d --- /dev/null +++ b/docs/business-apps/power-automate/guidance/manage-list-item-file-permissions.md @@ -0,0 +1,102 @@ +--- +title: Manage list item and file permissions with Power Automate +description: "SharePoint connector in Power Automate lets you grant access, create sharing links, or rescind access for items or folders." +ms.date: 12/01/2022 +search.app: + - Flow +search.appverid: met150 +--- + +# Manage list item and file permissions with Power Automate flows + +SharePoint connector in Power Automate provides the following actions to manage permissions of an individual list item in a list or a file in a document library. + +- Grant access to an item or a folder +- Create sharing link for a file or folder +- Stop sharing an item or a file + +All of the above actions let you customize permissions for the item or a file to allow the right users to access that item or the file. To grant access or stop sharing, you will need to be a list owner of that list or library. That means, in your flow for these actions, you must connect to the list or library using a list owner user account. + +## Grant access to an item or a folder + +The 'Grant access to an item or a folder' action requires the following inputs: + +- SharePoint site URL +- List or library name or identifier +- The item or the file identifier for which to grant access +- The recipients whom you want to grant access +- The permission role you want to grant + +![Grant access to an item or a folder](../../../images/grant-access-item-file-action-flow.png) + +In the flow action, you can also include a message and choose to notify the recipients once they get access to the item or the file. + +> [!NOTE] +> 'Grant access to an item or a folder' does not support granting access to external users. + +### Choosing a permission role to grant access + +Depending on the user, you may want to grant them either access to edit or read. You can choose the right access in the Roles property. + +![Choose the right role to grant access to an item or a file](../../../images/grant-access-item-file-roles-flow.png) + +The permission roles map to [simplified standard SharePoint permission groups](/sharepoint/modern-experience-sharing-permissions): + +- Members +- Visitors + +### Using custom-defined roles to grant access + +In advanced scenarios where you need to specify a custom-defined permission role, you can do so in the flow action by entering a custom value for the *Roles* property in the following format: + +``` +role: +``` + +![Use a custom role to grant access to an item or a file](../../../images/grant-access-item-file-custom-role-flow.png) + +If you want to get the role id for the custom-defined role permission, you can do so by navigating to the SharePoint URL in your web browser and then search for that role. + +``` +https:///_api/web/roledefinitions +``` + +For example: + +``` +https://contoso.microsoft.com/teams/itweb/_api/web/roledefinitions +``` + +You can find the role Id in the *category* property of an role item. + +![SharePoint site role definitions](../../../images/sp-web-roledefinitions.png) + +## Grant access using sharing links + +Instead of granting users access to files directly, you can provide access to a specific file using [shareable links](/sharepoint/modern-experience-sharing-permissions#sharable-links). + +You can use the '[Create sharing link for a file or folder](/sharepoint/dev/business-apps/power-automate/sharepoint-connector-actions-triggers#create-sharing-link-for-a-file-or-folder)' action to create shareable links for a given file. + +> [!NOTE] +> 'Create sharing link for a file or folder' only supports files or folders in a document library. List items are not supported yet. + +![Create sharing link for a file or folder flow action](../../../images/create-sharing-link-file-action-flow.png) + +When creating a shareable link using the action, you can specify: + +- Link type + - Type of sharing link - view and edit or view only +- Link scope + - Who gets access to the link - anyone with the link, including anonymous or people in your organization + +## Stop sharing an item or a file + +The 'Stop sharing an item or a file' action requires the following inputs: + +- SharePoint site address +- List or library name or identifier +- The item or the file identifier for which to stop sharing + +![Stop sharing an item or a file flow action](../../../images/stop-sharing-item-action-flow.png) + +Applying this flow action will remove all permissions on that item or file except for site owners. diff --git a/docs/business-apps/power-automate/guidance/migrate-from-classic-workflows-to-power-automate-flows.md b/docs/business-apps/power-automate/guidance/migrate-from-classic-workflows-to-power-automate-flows.md new file mode 100644 index 000000000..c2a03fc9c --- /dev/null +++ b/docs/business-apps/power-automate/guidance/migrate-from-classic-workflows-to-power-automate-flows.md @@ -0,0 +1,234 @@ +--- +title: Guidance - Migrate from classic workflows to Power Automate flows in SharePoint +description: This article specifically provides guidance about how to plan for transitioning from classic SharePoint Workflows to Power Automate flows. +ms.date: 05/12/2023 +ms.service: power-automate +search.app: + - Flow +search.appverid: met150 +--- + +# Guidance: Migrate from classic workflows to Power Automate flows in SharePoint + +## Current landscape + +For business users building apps and process automations in SharePoint today and into the future, Microsoft **Power Apps** and *flows* within Microsoft **Power Automate** are your tools of choice. This natural transition is well underway as SharePoint evolves from InfoPath and SharePoint Designer workflows to the simplicity and versatility of Power Apps and flows within Power Automate. + +Current landscape + +![Current landscape](../../../images/bizapps-current-landscape.png) + +This article specifically provides guidance about how to plan for transitioning from classic SharePoint Workflows to Power Automate flows. + +## Classic workflows in SharePoint + +Classic workflows in SharePoint constitutes two workflow systems namely + +- SharePoint 2010 workflow ([deprecated in November 2020](https://support.microsoft.com/en-us/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f)) +- SharePoint 2013 workflow + +While both workflow systems allow users to build and publish workflows in SharePoint, see the following key differences: + +- SharePoint 2010 workflows, released along with SharePoint Server 2010, are hosted, and executed in SharePoint workflow runtime. +- SharePoint 2013 workflows, released along with SharePoint Server 2013, are hosted in SharePoint, and executed in Workflow Manager, that runs independently. + +Users primarily use SharePoint Designer to author and publish workflows in SharePoint, while professional developers, looking to extend and build workflows, use Visual Studio to build and publish workflows in SharePoint. + +> [!Important] +> After August 1, 2020, new Microsoft 365 customers can use SharePoint 2013 workflows or Power Automate. However, SharePoint 2013 workflows will follow a similar retirement path in the future, so it's highly recommended to use Power Automate or other supported solutions. If you want to learn more about the SharePoint 2013 workflow usage inside your tenant you can use the [Workflow 2013 Assessment tool](https://aka.ms/microsoft365assessmenttool). This tool will assess your tenant on SharePoint 2013 workflow usage and generates a Power BI report with the findings. + +>[!Note] +>The SharePoint Migration Tool (SPMT) lets you migrate SharePoint Server 2010 out-of-the-box workflows and SharePoint Designer 2010 & 2013 workflows to Power Automate. [Learn more about migrating your SharePoint Server and SharePoint Designer workflows with SPMT.](/sharepointmigration/spmt-workflow-overview) + +## Modern workflows with Power Automate flows + +Since the release of classic workflows, SharePoint and Microsoft 365 apps have evolved to provide compelling, flexible and more performant experiences. Modern experiences in SharePoint integrate with rest of the Microsoft 365 apps and services driving security, productivity, and collaboration. + +[Power Automate](/power-automate/getting-started) helps users and businesses to create automated workflows between your favorite apps and services to get notifications, collect data, automate business policies and more. + +> [!VIDEO https://www.youtube.com/embed/hCuxuUaGC6Y] + +Using Microsoft Power Automate, SharePoint users can use the SharePoint Connector to create automations for when data changes in a list or a library. Users can build simple to complex workflows such as, but not limited to: + +- Send an email when a new item is created in a list. +- Start approval when a new file is added in a library. + +To create and author flows, users primarily use [Power Automate website](https://flow.microsoft.com/) while users can also [create flows from within SharePoint](https://support.microsoft.com/office/create-a-flow-for-a-list-or-library-in-sharepoint-or-onedrive-a9c3e03b-0654-46af-a254-20252e580d01?ui=en-us&rs=en-us&ad=us) or using the [Power Automate mobile app](/power-automate/mobile-create-flow). + +To learn more about building workflows using Power Automate in SharePoint, start here: Business apps and Business process [Business apps and business process automation](../../introduction-to-sharepoint-business-process-integration.md). + +## Pain points in moving between classic workflows in SharePoint and Power Automate flows + +Many people feel there are significant gaps between SharePoint Designer (classic) workflows and Power Automate flows, but the list is not long. Of course, there are some workarounds you should consider in your planning as you move from classic workflows to Power Automate flows. + +- **30 day run limit for flows** – SharePoint Designer workflows can run endlessly, but flows have a 30 day lifespan. Getting beyond this limitation means your flow will need to call itself in a re-entrant way to restart the clock ticking. Depending on the solution you choose to accomplish this, this may require a Premium Power Automate license. +- **HTTP Connector** – If you make calls to SharePoint's REST API, then you can use the ['Send HTTP Request to SharePoint'](../guidance/working-with-send-sp-http-request.md) action available in the SharePoint connector. Flow also has a generic HTTP connector (as an action), but it is a Premium connector. If you use HTTP calls extensively, you may want to create a “service account” user with a Power Automate license and run these flows with that user account. This also will make it easier to manage the set of flows you consider "enterprise" flows. +- **Reusable Flows** – Using some modular thinking, you can create a master flow which a flow per list or library can call to do the heavy lifting. In some ways this is even preferable, as you can edit a flow which is used in many locations centrally. This will however require a Premium Power Automate license. Alternatively, you can use flow actions to discover all of the lists or libraries which match some criteria and run the flow on them all on a timer rather than based on events. +- **Workflow history storage** – Flows maintain an extensively detailed history in the context of the flow itself in the Power Automate dashboard for the runs that have occured in the last 28 days. If you need tracking in your sites, or keep historical logging longer than 28 days, you can have the flow log information in a list you create. +- **Impersonation** - In SharePoint 2010 workflows, you can add an impersonation step to act as a different user. You could achieve similar functionality by using different user accounts with different (elevated) priviledges for certain actions. Alternatively you can consider using an Azure Active Directory Application registration, assigning it permissions and using that to directly call into the APIs. The latter will require a Premium Power Automate license and requires more manual effort to make the calls. + +While these pain points do exist, you can see there are workarounds for each of them. Do beware that some of these workarounds will require a Power Automate Premium license. Read more about the [license implications](/power-platform/admin/power-automate-licensing/faqs#i-have-multiple-flows-running-under-a-shared-service-account-what-licenses-do-i-need) of doing so and [who will require to have a Premium license](/power-platform/admin/power-automate-licensing/faqs#who-needs-to-purchase-a-premium-license). + +## Modern approvals with Power Automate flows + +Approvals are the most common workflow scenario when it comes to automating business processes in SharePoint. Transitioning to Power Automate flows, approvals can be streamlined for data in SharePoint, Dynamics 365, forms, SQL, and so on. You can create approvals in your workflow, and view sent and received requests in a unified Actions center. Power Automate approvals enable users to customize flows and create approvals for the following types: + +- [Single approvals](/power-automate/modern-approvals) +- [Sequential approvals](/power-automate/sequential-modern-approvals) +- [Parallel approvals](/power-automate/parallel-modern-approvals) + +SharePoint approvals such as [page approvals](customize-page-approvals.md), [document approvals](require-doc-approval.md), and [hub association approvals](https://support.microsoft.com/office/set-up-your-sharepoint-hub-site-e2daed64-658c-4462-aeaf-7d1a92eba098#bkmk_managesiteassociationapprovals) are all integrated and powered by Power Automate flows, providing users the flexibility to customize the business process for each of the approval scenarios. + +## Authoring classic workflows and flows + +To fully understand the improvements of authoring workflows with flows in Power Automate and classic workflows using SharePoint Designer, users must first familiarize themselves with the workflow terminologies used by the workflow tools; that is, SharePoint Designer and Power Automate. + +To author workflows, as outlined in the previous sections, users primarily use SharePoint Designer to author classic workflows and Power Automate website portal to author flows. + +See the following tables that compare the workflow terminologies, triggers, and actions for most common workflow concepts and support. + +While the following lists show some of the most common workflow capabilities, Power Automate offers many more features, and is actively updated with new features. We highly recommend visiting the following Power Automate websites for guided learning: + +- [Microsoft SharePoint Connector in Power Automate](../sharepoint-connector-actions-triggers.md) +- [Learn Power Automate](/training/browse/?products=power-automate&term=Power%20Automate&terms=Power%20Automate) +- [Power Automate Documentation](/power-automate) + +### Workflow concepts + +| Workflow concept | SharePoint workflow | Power Automate | +| :------------------------------------------------------------------------- | :----------------------- | :----------------------------------- | +| A condition that causes the workflow to run or execute | Start options and events | Trigger | +| Building blocks that allow users to customize workflow with business logic | Actions | Actions | +| Apply and perform conditional business logic in workflows | Conditions | Conditions (available under Actions) | +| Get additional input from users when running manual workflows | Initiation form | Trigger Inputs | + +### Workflow types + +| Workflow type | SharePoint workflow | Power Automate flow | +| :----------------- | :------------------ | :------------------ | +| List workflows | Yes | Yes | +| Library workflows | Yes | Yes | +| Reusable workflows | Yes | Not available | +| Site workflows | Yes | Not available | + +### SharePoint integrations + +| SharePoint integration | SharePoint workflow | Power Automate flow | +| :--------------------------------------------------------------- | :------------------ | :------------------------------ | +| Create a custom workflow from a list or library | Yes | Yes, only in Modern Experiences | +| Run or start a custom workflow for an item or a file or a folder | Yes | Yes, only in Modern Experiences | +| Create and respond to standard approval for an item or a file | Yes | Yes | +| Create and respond to classic publishing page approvals | Yes | Not available | +| Create and respond to modern page approvals | Not available | Yes | +| Create and manage Hub Site association approval requests | Not available | Yes | + +### List triggers + +| List trigger | SharePoint workflow | Power Automate flow | +| :---------------------------------- | :------------------ | :------------------ | +| When an item is created | Yes | Yes | +| When an item is modified | Yes | Yes | +| When an item is created or modified | Not available | Yes | +| Site workflows | Yes | Not available | +| When an item is deleted | Not available | Yes | +| For a selected item | Yes | Yes | + +### List actions + +| List action | SharePoint workflow | Power Automate flow | +| :------------------------------ | :------------------ | :-------------------------------------- | +| Get items | Not available | Yes | +| Create an item | Yes | Yes | +| Update an item | Yes | Yes | +| Delete an item | Yes | Yes | +| Copy a list item | Yes | Yes, by reusing ‘Create an item' action | +| Get attachments | Not available | Yes | +| Get attachment content | Not available | Yes | +| Add attachment | Not available | Yes | +| Delete attachment | Not available | Yes | +| Set field value in current item | Yes | Yes, using ‘Update an item’ action | +| Get changes for an item | No | Yes | + +### File triggers + +| List action | SharePoint workflow | Power Automate flow | +| :--------------------------------------------- | :----------------------- | :------------------ | +| When a file is created | Yes, using List triggers | Yes | +| When a file is created in a folder | Not available | Yes | +| When a file is modified | Yes, using List triggers | Yes | +| When a file is created or modified | Not available | Yes | +| When a file is created or modified in a folder | Not available | Yes | +| When a file is deleted | Not available | Yes | +| For a selected file | Yes, using List triggers | Yes | + +### File actions + +| File action | SharePoint workflow | Power Automate flow | +| :--------------------------------------- | :----------------------- | :------------------ | +| Get files | Not available | Yes | +| Create file content | Not available | Yes | +| Get file properties | Not available | Yes | +| Create a file | Not available | Yes | +| Create new folder | Not available | Yes | +| Update file properties | Yes, using List triggers | Yes | +| Delete a file | Yes, using List triggers | Yes | +| Copy file | Not available | Yes | +| Copy folder | Not available | Yes | +| Move file | Not available | Yes | +| Get changes for a file (properties only) | No | Yes | + +### Document management actions + +| Document management action | SharePoint workflow | Power Automate flow | +| :------------------------------------------- | :------------------ | :------------------ | +| Check in file | Yes | Yes | +| Check out file | Yes | Yes | +| Discard checkout | Yes | Yes | +| Delete drafts | Yes | Not available | +| Wait for change in document check out status | Yes | Not available | + +### Permissions management actions + +| Permissions management action | SharePoint workflow | Power Automate flow | +| :--------------------------------------- | :------------------ | :------------------ | +| Grant access to an item or a folder | Yes | Yes | +| Stop sharing an item or a file | Yes | Yes | +| Create sharing link for a file or folder | Not available | Yes | + +### Approval actions + +| Approval action | SharePoint workflow | Power Automate flow | +| :--------------------------------------------------------- | :------------------ | :------------------ | +| Set content approval status of an item or a file or a page | Yes | Yes | +| Create and wait for approval for an item or a file | Yes | Yes | +| Include attachments in approval requests | Not available | Yes | +| Respond to approvals | Yes | Yes | +| Create sequential approvals | Yes | Yes | +| Create parallel approvals | Yes | Yes | +| Cancel approvals | Yes | Yes | +| Reassign approvals | Yes | Yes | +| Custom approval buttons | Yes | Yes | +| Unified approval center | Not available | Yes | + +### Workflow controls capabilities + +| Workflow controls capability | SharePoint workflow | Power Automate flow | +| :----------------------------------------------------------- | :------------------ | :-------------------------------------- | +| Workflow primitives: Loops, do until, switch-case, parallels | Yes | Yes | +| Workflow stage | Yes | Yes, works only with Modern Permissions | +| Schedule-based flows | Yes | Yes | +| Variables | Yes | Yes | +| Email designer and rich text editor | Not available | Yes | +| Versioning of workflows | Not available | Not available | +| Copy/paste actions | Yes | Yes | + +## Workflow administration + +| Workflow administration | SharePoint workflow | Power Automate flow | +| :------------------------------------------------------- | :------------------------------------------------------------------------------------------------- | :------------------------------- | +| Central location to view all workflows | Yes, only available to view for a given list or library | Yes, 'My flows' lists user flows | +| Share workflows with list or library users | Yes | Yes | +| Share workflows with users | Not available | Yes | +| Save a copy of workflow to create a copy of the workflow | Not available | Yes | +| Workflow versioning | Not available | No | +| Create a workflow with elevated permissions | Yes, by granting permissions to workflow app and then using App Step action and SharePoint Add-ins | Not available | diff --git a/docs/business-apps/power-automate/guidance/require-doc-approval.md b/docs/business-apps/power-automate/guidance/require-doc-approval.md new file mode 100644 index 000000000..c5c548834 --- /dev/null +++ b/docs/business-apps/power-automate/guidance/require-doc-approval.md @@ -0,0 +1,103 @@ +--- +title: Require approval of documents in SharePoint using Power Automate +description: Documents that contain sensitive information often require approvals. With the content approval feature in SharePoint, you can put a simple approval process for documents in a specific document library. Using this content approval process, documents pending approval will not be visible to users until they are approved. +ms.date: 06/28/2022 +search.app: + - Flow +search.appverid: met150 +--- + +# Require approval of documents in SharePoint using Power Automate + +Documents that contain sensitive information often require approvals. With the content approval feature in SharePoint, you can put a simple approval process for documents in a specific document library. Using this content approval process, documents pending approval will not be visible to users until they are approved. + +Manage the content approval settings in the library settings page: + +![Content approval settings](../../../images/setup-content-approval-settings.png) + +Settings > Versioning settings > Require content approval for submitted items + +After this setting is enabled, when users upload documents to this specific library, the document’s **Approval Status** is either in: + +- **Draft** (if minor and major versions are enabled) or +- **Pending** (if only the major version is enabled) state + +You can always visit the document library to approve and reject documents but this exercise is tedious. It requires receiving notifications about the pending document(s), finding the appropriate document(s) for approval, then identifying approvers, and finally generating the command to approve/reject the document(s). + +Alternatively, why not automate this approval process using a flow? + +## Content approval flow in Power Automate + +You can automate this entire content approval process using an approval flow. When approved, the content approval status of the document is automatically set to **Approved**; if rejected, the flow sets the content approval status of the document to **Rejected**. + +To set the content approval status of the document, with the SharePoint connector, use the **Set content approval status** action in the flow. + +The following actions occur: + +1. Power Automate uses a SharePoint *trigger* when a new file is added to the library. +1. *Get file metadata* provides the *ETag* property (along with many others) required when dealing with content approvals. + - ETag is a special identifier that identifies the specific version of that item pending approval. +1. Start an approval action: + - Include people for approving the documents. + - Approvers should be either **Site Owners** or **Site Members**. + - If you are managing users in SharePoint groups, make sure approvers are part of the **Design** permission-level group. +1. If approval response is approved: + - Set content approval status of the document to **Approved**. + - Send an email to the document author regarding the approval along with any comments. +1. If approval response is not approved: + - Set content approval status of the document to **Rejected**. + - Send an email to the document author regarding the rejection along with any comments. + +## Setting up the flow in Power Automate + +Using the following template, create a flow in Power Automate. + +1. In the SharePoint library, from the command bar, select **Integrate** > **Power Automate** > **Create a flow**. +1. Next, select the template: **When a new file is added in SharePoint, complete a custom action**. + +![File add custom action](../../../images/create-flow-template-file-added.png) + +1. Add the actions as described in the previous steps. + +![Flow content approval full](../../../images/flow-content-approval-full.png) + +## Set content approval status action + +The content approval action requires the following entries: + +- SharePoint site +- Library name +- Identifier of the item (in this case, the document ID) +- Content approval action +- Comments + +To see the *ETag*, expand **Show advanced options**. + +> [!NOTE] +> While the content approval action help says that ETag is optional, it is required for documents and pages while it may be optional for list items. + +![Content approval status Approve](../../../images/action-content-approval-status.png) + +You must ensure you enter the correct site and library name. However, you can get the rest of the values from the previous actions in the flow. + +- Identifier + - Using the *Id* property from the *trigger output* +- Comments + - Using the *comments* property from the *approval response* +- ETAG + - Using the *ETag* property from the *Get file metadata* action output + +You can now use the content approval status action to approve or reject the document based on the approval response. + +The end result is that: + +1. After the flow is triggered, approvers get an email to approve/reject the document with the document link. +1. Approvers can now: + - If your email client supports Outlook-actionable messages: Approve it within the email using actionable messages if your Outlook client supports it. + - If your email client does not support Outlook-actionable messages: Select **Approve** or **Reject** that takes you to Power Automate site where you can approve or reject the document. +1. After approval or rejection: + - Document creator receives an email with the approval status along with the approval comments. + +![Email approval status](../../../images/output-content-approval-status.png) + +This is an effective way to automate document approval in SharePoint using Power Automate! Use this procedure for list items and pages as well. diff --git a/docs/business-apps/power-automate/guidance/working-with-get-items-and-get-files.md b/docs/business-apps/power-automate/guidance/working-with-get-items-and-get-files.md new file mode 100644 index 000000000..284490333 --- /dev/null +++ b/docs/business-apps/power-automate/guidance/working-with-get-items-and-get-files.md @@ -0,0 +1,108 @@ +--- +title: In-depth analysis into 'Get items' and 'Get files' SharePoint actions for flows in Power Automate +description: In this article, learn more about the SharePoint actions get items & get files actions with Power Automate. +ms.date: 06/28/2022 +search.app: + - Flow +search.appverid: met150 +--- + +# In-depth analysis into **Get items** and **Get files** SharePoint actions for flows in Power Automate + +The **Get items** and **Get files** SharePoint actions for flows in Power Automate let you get items from a list and a library, respectively. Though they are different actions, the capabilities for both the actions are same. This article describes how to work with these actions. + +## Decide if you are working with lists or libraries + +First, and of primary consideration, the **Get items** action only works with lists, whereas the **Get files** action only works with libraries. + +## Item limits +The default item limit is 100 and items are paginated by default as well. + +If you are using the default options, and simply specifying the site address and list or library name, Power Automate returns 100 items from the list or library. + +If you are working with large lists, you can increase this limit up to the list view threshold limit of 5,000. + +To specify the number of items to be returned, expand the **Advanced options**, and specify the number in the **Top Count** action property. + +![Modify number of items returned in Get items action](../../../images/flow-get-items-modify-top-count.png) + +If you go beyond 5,000 item limit, Power Automate fails and generates an error dialog. + +## Limit items to a specific folder +By default, this action returns all items or files in the list or library, recursively, from all folders, if available. You can change this behavior by doing the following: +* To select a specific folder in the list or library, use _Limit Entries_ to Folder property. +* To limit entries to that specific folder or within all sub-folders, use _Include Nested Items_ property. + +![Limit entries to folder in Get items action](../../../images/flow-get-items-limit-entries-to-folder.png) + +## Limit columns returned by view +List views is a useful configuration where you can customize what columns to show along with any other conditions or groupings of list items. This is not only useful for users, but also for any other computation you want to do using that view data. + +To retrieve the list items along with their columns, select the **Get items** and **Get files** actions. However, retrieving the columns retrieves all the columns. While this is useful, it could be excessive when you only need to work with a specific set of columns configured in a specific view. + +To limit your column retrieval, in the **Get items** and **Get files** actions, expand **Advanced options**, select the **Limit columns by view** option. While retrieving list items, you can now limit the columns by view. + +![Limits columns returned by view in Get items action](../../../images/flow-get-items-limit-columns-by-view.png) + +This option is useful in cases where you want to perform a set of operations on specific data, like in the previous example where you want a view for different events. In this case, working with food events, it would be optimal to limit the columns by the *Food Events*. + +## Filter queries +This action also supports specifying filter queries so you can filter items on the server. Using filter queries are as functional as filtering the returned results in your flow in Power Automate. + +We support the following OData filter queries in SharePoint that you can use: + +- Filter by column name: + +``` +Location eq 'Midwest' +``` + +*Location* is the column name used with the operator equals (eq), and *Midwest* is the value of the column. + +Other examples: + +* Location eq 'Midwest' and Status eq 'Approved' +* startswith(Title, 'A') +* startswith(Title, 'A') and Start_x0020_Date gt 'formatDateTime(utcNow(),'yyyy-MM-dd')' + * formatDateTime(utcNow(),'yyyy-MM-dd') is an expression. +* Country/Title eq 'New Zealand' + * Country is a lookup column in the list and Title is a column in the referenced list. + +![ODATA filter queries in Get items action](../../../images/flow-get-items-filter-query.png) + +We support the following query methods and operators. + +### Numeric comparisons +* lt + * less than +* le + * less than or equals +* gt + * greater than +* ge + * greater than or equals +* eq + * equals +* ne + * not equal + +### String comparisons +* startsWith +* substringOf +* eq +* ne + +## Order by query +To order items based off of a column either in ascending or descending order, you can also specify an order by query. For example: + +* Start_x0020_Date desc +* Title asc + +Spaces in the column name are replaced with `_x0020_` (0 is numeral zero). + +![ODATA order by in Get items action](../../../images/flow-get-items-filter-query.png) + +The format is the column name followed by asc or desc depending on ascending or descending order, respectively. + +### Known Limitation +While using Get items on lists with more than 5000 items with a filter query, you may observe that no records are returned if there are no items matching the filter query in the first 5000 items. To fix this, enable Pagination on Get items from the action settings menu when working with lists with more than 5000 items. diff --git a/docs/business-apps/power-automate/guidance/working-with-send-sp-http-request.md b/docs/business-apps/power-automate/guidance/working-with-send-sp-http-request.md new file mode 100644 index 000000000..18c911428 --- /dev/null +++ b/docs/business-apps/power-automate/guidance/working-with-send-sp-http-request.md @@ -0,0 +1,60 @@ +--- +title: Working with the SharePoint Send HTTP Request flow action in Power Automate +description: In Power Automate, the SharePoint Send HTTP Request flow action lets you construct and execute SharePoint REST API queries. +ms.date: 01/27/2023 +search.app: + - Flow +search.appverid: met150 +--- +# Working with the SharePoint Send HTTP Request flow action in Power Automate + +In Power Automate, the SharePoint Send HTTP Request flow action lets you construct and execute SharePoint REST API queries. This action is particularly useful in cases where the existing SharePoint flow actions do not handle your requirements, or the action you are looking for is not yet available in the SharePoint connector. + +![Send an HTTP Request to SharePoint action](../../../images/flow-send-http-request-to-sp-action.png) + +To work effectively with the SharePoint Send HTTP Request action, see the following tips. + +> [!NOTE] +> This is a developer-focused action. You must understand how SharePoint REST API works and also how to parse JSON strings in Power Automate. +> +> Additionally, this action only supports SharePoint REST APIs (excluding any deprecated APIs), if you need to access another Microsoft service, you will need to leverage the "HTTP with Microsoft Entra ID" connector. + +## Get to know the SharePoint REST/OData APIs + +SharePoint has many APIs. The focus here is the REST/OData APIs. For the complete set of REST/OData APIs, see [Get to know the SharePoint REST service](/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service#bk_learnmore). + +Although, in some cases, you can use the SharePoint 2010 REST APIs *(_vti_bin/listdata.svc)*, we recommend using REST/OData APIs instead. + +## Use JSON light + +SharePoint REST/OData APIs support [JSON light](https://www.microsoft.com/en-us/microsoft-365/blog/2014/08/13/json-light-support-rest-sharepoint-api-released/). This means that you can set headers in your API request that inform SharePoint whether to include any metadata in the response. In many cases, you do not require the metadata. Metadata makes things simpler to parse the output of the action. + +To do this, just add the following header: + +```http +Accept: application/json; odata=nometadata +``` + +## Parse the response + +If you execute a GET request, you generally want to parse the response. The default response is JSON, making execution simpler. + +Parse the response by querying the body of the action, and then parsing through the JSON array or object depending on your response. + +To do that, build an expression: + +```http +body('Send_an_HTTP_request_to_SharePoint' )['Id'] +``` + +In cases where you have an array, you have a JSON array object. You can use the previous expression and then construct an apply to each action, and use the following expression to input the variable to work with: + +```http +body('Send_an_HTTP_request_to_SharePoint' )['value'] +``` + +Inside the apply to each action, you can then access the individual elements with the following expression: + +```http +items('Apply_to_each')['Title'] +``` diff --git a/docs/business-apps/power-automate/sharepoint-connector-actions-triggers.md b/docs/business-apps/power-automate/sharepoint-connector-actions-triggers.md new file mode 100644 index 000000000..6566e5ef0 --- /dev/null +++ b/docs/business-apps/power-automate/sharepoint-connector-actions-triggers.md @@ -0,0 +1,379 @@ +--- +title: Microsoft SharePoint Connector for Power Automate +description: In Power Automate, Microsoft SharePoint Connector supports the following flow triggers and actions. +ms.date: 10/23/2024 +ms.service: power-automate +search.app: + - Flow +search.appverid: met150 +--- + +# Microsoft SharePoint Connector in Power Automate + +In Power Automate, Microsoft SharePoint Connector supports the following flow triggers and actions. + +## SharePoint triggers + +SharePoint triggers let you create flows that monitor for changes in a SharePoint list or library. If one or more changes occur in a subscribed list, that flow is triggered to run. + +### When an item is created + +Triggers the flow when you create an item in a SharePoint list. + +### When an item is created or modified + +Triggers the flow when you create an item, and each time you modify it in a SharePoint list. + +### When an item or a file is modified + +Triggers the flow when you modify an item or a file in a SharePoint list or a document library. + +For more info about how to use this trigger, see this tutorial video: [Introducing 'when an item or file modified' trigger and 'Get changes' action](https://youtu.be/AaWB3xlhJdc) + +### When an item is deleted + +Triggers the flow when you delete an item in a list. To get the properties of a deleted item, you must connect this trigger to the associated SharePoint site on which it is expected to run, using a site collection admin account. + +### For a selected item + +Allows users of lists to trigger a flow after selecting an item in a list. + +> [!NOTE] +> Only flows within the default environment can be executed manually from a SharePoint list. + +### When a file is classified by a content understanding model +Triggers the flow when a Microsoft Syntex content understanding model classifies a file, shown in the classification date property of the file. + +For more info about when Microsoft Syntex and how it classifies files see: [Introduction to Microsoft Microsoft Syntex](/microsoft-365/contentunderstanding) + +### When a file is created (properties only) + +Triggers the flow when you create a file in a document library and returns only the custom file properties associated with that file. + +### When a file is created in a folder [deprecated] + +> [!NOTE] +> This trigger is deprecated and may not work as expected. + +Triggers the flow when you create a file in a SharePoint folder. This trigger does not run if you add or update a file in a subfolder inside the folder this trigger is operating on. If the flow is required to trigger on subfolders, create different flows for one or more subfolder(s). + +### When a file is created or modified (properties only) + +Triggers the flow when you create a file, and each time you modify the file properties in a library. Specify a value in the "Folder" property to target a specific folder; otherwise, the trigger applies to the entire library. Returns only the custom file properties associated with that file. + +### When a file is created or modified in a folder [deprecated] + +> [!NOTE] +> This trigger is deprecated and may not work as expected. + +Triggers when a file is created, and also each time it is modified in a SharePoint folder. The trigger does not fire if a file is added/updated in a subfolder. If it is required to trigger on subfolders, multiple triggers should be created. + +### When a file is deleted + +Triggers the flow when you delete a file in a document library. You can optionally specify a folder to watch. When you delete a folder, the trigger activates only once for the deleted folder, including its subfolders. To get the properties of the deleted file, you must connect this trigger to the associated SharePoint site on which the trigger is expected to run, using a site collection admin account. + +### For a selected file + +Allows users of document libraries to trigger a flow after selecting a file. + +> [!NOTE] +> Only flows within the default environment can be executed manually from a SharePoint library. + +### When a site has requested to join a hub site + +Triggers a flow upon hub site join approval request. + +## SharePoint actions + +### Add attachment + +Adds a new attachment to the specified list item. + +### Approve hub site join request + +Approves hub site join request. This action returns an approval token to complete the join request, using the join hub site action. + +### Cancel hub site join request + +Cancels hub join request. If applicable, specify the same Approval Correlation Id as used in the **Set hub site join status to pending** action. + +### Check in file + +Checks in a checked-out file in a document library, which makes the version of the document available to others. + +### Check out file + +Checks out a file in a document library to prevent others from editing the document, and your changes from being visible until you check in the document. + +### Copy file + +Copies a file. Works similarly to the **Copy to** command in SharePoint libraries. After copying, returns info about the new file. + +### Copy file [deprecated] + +> [!NOTE] +> This action is deprecated and may not work as expected. + +Copies a file to a SharePoint site. + +### Copy folder + +Copies a folder. Works similarly to the **Copy to** command in SharePoint libraries. After copying, returns info about the new folder. + +### Create file + +Uploads a file to a SharePoint site. Make sure to pick an existing library. + +### Create item + +Creates a new item in a SharePoint list. + +### Create new folder + +Creates a new folder or folder path. + +### Create sharing link for a file or folder + +Creates a sharing link for a file or folder. + +### Delete attachment + +Deletes the specified attachment. + +### Delete file + +Deletes the file specified by the file identifier. + +### Delete item + +Deletes an item from a SharePoint list. + +### Discard checkout + +Discards the checkout, rather than saves the file, if you check out a file and don't make changes to it, or you make changes that you don't want to keep. If your organization tracks versions, a new version is created each time you check in a file to the library. By discarding the checkout, you can avoid making new versions when you haven't made any changes to the file. + +### Extract folder + +Extracts an archive file into a SharePoint folder (for example, .zip). + +### Get all lists and libraries + +Gets all lists and libraries. + +### Get attachment content + +Returns file contents, using the file identifier. The contents can be copied somewhere else, or be used as an attachment. + +### Get attachments + +Returns the list of attachments for the specified list item. To get to the contents of the file, add a **Get attachment content** step, and use the **File identifier** property returned by this action. + +### Get changes for an item or a file (properties only) + +Gets all the columns or file properties changed since and until a specified time interval. To get all the columns changed when an item or a file is modified: +- Use the _when an item or file is modified_ trigger, and, +- Use the _Trigger Window Start Token_ & _Trigger Window End Token_ outputs from the _when an item or file is modified_ trigger to infer what columns changed since the last time flow checked for item or file updates. + +For more info about how to use this action, see this tutorial video: [Introducing 'when an item or file modified' trigger and 'Get changes' action](https://youtu.be/AaWB3xlhJdc) + +> [!NOTE] +> - The list or library should have versioning configured in order to infer what columns or properties got modified since last change. +> - Only column changes are supported for lists and libraries. +> - File content changes are not supported. +> - Attachment changes are not supported. +> - _Trigger Window Start Token_ & _Trigger Window End Token_ are only available when you use _when an item or file is modified_ trigger. + +### Get file content + +Gets file contents using the file identifier. You can copy the contents somewhere else, or use it as an attachment. + +### Get file content using path + +Gets file contents, using the file path. + +### Get file metadata + +Gets info about the file, such as size, etag, created date, and so on. Uses a file identifier to select the file. To get to the values stored in the columns in the library, use the **Get file properties** action. + +### Get file metadata using path + +Gets info about the file, such as size, etag, created date, and so on. Uses a file path to select the file. To get to the values stored in the columns in the library, use the **Get file properties** action. + +### Get file properties + +Gets the properties saved in the columns in the library for the item specified by the item id. To get to the contents of the file, add a "Get file content" step, and use the "File identifier" property returned by this action. When using this with the On-Premises Data Gateway, you may need to manually enter the name of the library to connect to. + +### Get files (properties only) + +Gets the properties saved in the columns in the library for all folders and files stored in the library. You can also filter down to the items that match a condition. To work with the output from this action, use the **Apply to each** section. When using this with the On-Premises Data Gateway, you may need to manually enter the name of the library to connect to. For more info about this action, see: [In-depth analysis into **Get items** and **Get files** SharePoint actions for flows in Power Automate](../power-automate/guidance/working-with-get-items-and-get-files.md). + +### Get folder metadata + +Gets info about the folder. Uses a file identifier to select the folder. + +### Get folder metadata using path + +Gets info about the folder. Uses a folder path to select the folder. + +### Get item + +Gets a single item by its ID from a SharePoint list. + +### Get items + +Gets items from a SharePoint list. For more info about this action, see: [In-depth analysis into **Get items** and **Get files** SharePoint actions for flows in Power Automate](../power-automate/guidance/working-with-get-items-and-get-files.md). + +### Get list views + +Gets views from a SharePoint list. + +### Get lists + +Gets SharePoint lists from a site. + +### Grant access to an item or a folder + +Grants access to an item or a folder in SharePoint to specific people. + +### Join hub site + +Joins the requested site to the hub site. An Approval Token is required to complete the join successfully if that hub requires approval. If applicable, specify the same Approval Correlation Id as used in the **Set hub site join status to pending** action. + +### List folder + +Returns files contained in a SharePoint folder. + +### List root folder + +Returns files in the root SharePoint folder. + +### Move file + +Moves a file. Works similarly to the **Move to** command in SharePoint libraries. Returns info about the new file after its move. + +### Move folder + +Moves a folder. Works similarly to the **Move to** command in SharePoint libraries. Returns info about the new folder after its move. + +### Resolve person + +Returns a single matching user value so it can be assigned to a column of type person. If there are no matches or multiple matches, this action errors out. + +### Send an HTTP request to SharePoint + +Constructs a SharePoint REST API to invoke. For more info about this action, see: [Working with the SharePoint Send HTTP Request flow action in Power Automate](../power-automate/guidance/working-with-send-sp-http-request.md). + +> [!IMPORTANT] +> This action may execute any SharePoint REST API you have access to. Proceed with caution. + +### Set content approval status + +Sets the content approval status for an item in a list or library that has content approval turned on. You must provide an ETag for pages and files. You can get the ETag using the Get File Metadata action. This action is only available for SharePoint Online and SharePoint 2019. + +### Set hub site join status to pending + +Sets the requested site's hub join request status to pending. The Approval Correlation Id is an optional parameter that helps SharePoint identify a particular hub join request. The requesting site can only have one pending request at a given time. + +### Stop sharing an item or a file + +Deletes all links giving access to an item or a file, and removes all people with direct access, except for owners. + +### Update file + +Updates the contents of the file specified by the file identifier. + +### Update file properties + +Updates the properties stored in columns in a library for the item specified by the item ID. To update file contents, use the **Update file** action. When using this with the On-Premises Data Gateway, you may need to manually enter the name of the library to connect to. + +### Update item + +Updates an item in a SharePoint list. + +## Support for SharePoint Server + +The following tables list all of the actions and triggers that are supported for SharePoint On-Premises 2013, 2016, or 2019. Any actions or triggers that are not mentioned are unsupported. + +### Supported triggers + +| Trigger | SharePoint 2013 | SharePoint 2016 | SharePoint 2019| +| :-- | :-- | :-- | :-- | +| When a file is created in a folder | Yes | Yes | Yes | +| When a file is created or modified in a folder | Yes | Yes | Yes | +| When an item is created | Yes1 | Yes1 | Yes1 | +| When an item is created or modified | Yes1 | Yes1 | Yes1 | +| When a file is created (properties only) | No | No | Yes1 | +| When a file is created or modified (properties only) | No | No | Yes1 | +| When an item is deleted | No | No | Yes2 | +| When a file is deleted | No | No | Yes2 | +| Resolve Person | No | No | Yes | +| Set content approval status | No | No | Yes | + +> [!NOTE] +> 1. Does not support “Limit Columns by View”. +> 1. While this trigger is supported for SharePoint 2019, flows created using this trigger may encounter the following issues: +> - If there is no activity on the list for over 60 days or if there is some activity but no items are deleted for over 60 days, then the trigger will fail to activate. +> - The deletion of list items by the System User will activate the trigger. + + +### Supported actions + +| Action | SharePoint 2013 | SharePoint 2016 | SharePoint 2019| +| :-- | :-- | :-- | :-- | +| Get file metadata | Yes | Yes | Yes | +| Get file metadata using path | Yes | Yes | Yes | +| Get folder metadata | Yes | Yes | Yes | +| Get folder metadata using path | Yes | Yes | Yes | +| Get file content | Yes | Yes | Yes | +| Create file | Yes1 | Yes1 | Yes1 | +| Update file | Yes | Yes | Yes | +| Copy file [deprecated]2| Yes | Yes | Yes | +| List folder | Yes | Yes | Yes | +| Extract folder | Yes | Yes | Yes | +| Get attachments | Yes | Yes | Yes | +| Add attachment | Yes | Yes | Yes | +| Delete attachment | Yes | Yes | Yes | +| Get items | Yes3 | Yes3 | Yes3 | +| Get item | Yes4 | Yes4 | Yes4 | +| Create item | Yes4 | Yes4 | Yes4 | +| Update item | Yes4 | Yes4 | Yes4 | +| Delete item | Yes | Yes | Yes | +| Send an HTTP request to SharePoint | Yes | Yes | Yes | + +> [!NOTE] +> 1. Does not support creating a large file by uploading it as a set of chunks. +> 1. This action includes "[deprecated]" in its display name. The "Copy file" action is different from this action. +> 1. This action only supports OData parameters, which excludes parameters such as "Limit Entries to Folder", "Include Nested Items", and "Limit Columns by View". +> 1. Does not support “Limit Columns by View”. + +### Deprecated triggers and actions + +These triggers are deprecated and are no longer actively maintained. While they are still present in the Microsoft SharePoint Connector, we recommend not utilizing deprecated triggers or actions in any new applications or solutions. + +| Name | Type | Supported Version | Suggested Alternative | +| :-- | :-- | :-- | :-- | +| When a file is created in a folder [deprecated] | Trigger |SharePoint 2019 | When a file is created (properties only) | +| When a file is created or modified in a folder [deprecated] | Trigger | SharePoint 2019 | When a file is created or modified (properties only) | +| Copy file [deprecated] | Action | SharePoint 2019 | Copy file | + +## Known limitations + +### Supported list and library templates + +Power Automate flows for lists are only supported in generic lists (100) and generic document libraries (101). We do not currently support custom list and library templates, including but not limited to, lists such as Announcements, Contacts and Tasks. + +### Flow runs + +When you build a Power Automate flow to be triggered for an item, or for creating or modifying a file, Power Automate periodically checks for changes in the list or library, configured in the flow's trigger. In most cases, if there is a single change in the list or library, the flow run may occur within minutes after that change. However, expect that the flow may gather more than one change in subsequent flow runs due to the time between the flow interval since its last valid change, or subsequent edits to an item or a file. + +### Move files and flow runs + +When you move one or more files from one document library to another, the original file is moved from the source library to the destination library. Moving the file does not alter any custom metadata, including when the file was created and modified. Hence, this action does not trigger any flows for those file updates associated with the library where it was moved. + +### Syncing files to your OneDrive for Business and SharePoint document libraries + +When users sync one or more files from one document library to another, the original file is moved (synced) from your client to the destination library. Syncing the file will not alter any custom metadata including when the file was created and modified. Hence, this action will not trigger any flows for those file syncs in that library or in your OneDrive for business. + +### Supported lookup columns + +If your list/library has lookup columns, **Get items** and **Get files** actions support returning items with a maximum of 12 lookup columns. If your list or library exceeds this threshold, the flow in Power Automate fails. diff --git a/docs/community/community.md b/docs/community/community.md index 1219969ee..79d2ffccc 100644 --- a/docs/community/community.md +++ b/docs/community/community.md @@ -1,24 +1,23 @@ --- title: SharePoint Developer Community (SharePoint PnP) resources description: The SharePoint Development Community (also known as the SharePoint PnP community) is an open-source initiative coordinated by SharePoint engineering. -ms.date: 04/02/2019 -ms.prod: sharepoint - -localization_priority: Priority +ms.date: 06/09/2022 +ms.service: sharepoint-online +ms.localizationpriority: high --- -# SharePoint Developer Community (SharePoint PnP) resources +# Microsoft 365 Platform Community (PnP) resources around SharePoint Framework -The SharePoint Development Community (also known as the SharePoint PnP community) is an open-source initiative coordinated by SharePoint engineering. This community controls SharePoint development documentation, samples, reusable controls, and other relevant open-source initiatives related to SharePoint development. +The Microsoft 365 Platform Community (also known as M365 PnP community) is an open-source initiative coordinated by Microsoft 365 engineering. This community controls SharePoint development documentation, samples, reusable controls, and other relevant open-source initiatives related to SharePoint development. ## Blog posts, videos, and social media -- [SharePoint Developer Blog](https://developer.microsoft.com/en-us/office/blogs/) - Latest developer news around SharePoint and Office 365 +- [SharePoint Developer Blog](https://developer.microsoft.com/office/blogs/) - Latest developer news around SharePoint and Office 365 - [SharePoint Developer Videos](https://aka.ms/spdev-videos) - Latest guidance videos, training videos, and community call recordings -- [OfficeDev Twitter](https://twitter.com/officedev) - Official communication channel for SharePoint and Office 365 developer topics -- [OfficeDevPnP Twitter](https://twitter.com/officedevpnp) - Community account for SharePoint and Office 365 developer topics -- [OfficeDev Facebook](https://www.facebook.com/OfficeDev/) - Official communication channel for SharePoint and Office 365 developer topics -- [OfficeDevPnP Facebook](https://www.facebook.com/OfficeDevPnP/) - Community account for SharePoint and Office 365 developer topics +- [Microsoft 365 Dev Twitter](https://twitter.com/Microsoft365Dev) - Official communication channel for SharePoint, Office 365, Windows 10 and Enterprise Mobility + Security developer topics +- [Microsoft 365 PnP Twitter](https://twitter.com/m365pnp) - Community account for Microsoft 365 and SharePoint topics +- [Microsoft 365 Dev Facebook](https://www.facebook.com/Microsoft365Developer) - Official communication channel for SharePoint, Office 365, Windows 10 and Enterprise Mobility + Security developer topics +- [Microsoft 365 PnP Facebook](https://www.facebook.com/Microsoft365/community) - Community account for SharePoint and Office 365 developer topics ## GitHub @@ -38,15 +37,15 @@ Found an issue related to SharePoint development around the APIs, documentation, There are numerous community calls for SharePoint development, and you can choose which of them you'd like to join based on your interest and availability. Each call has live demos from SharePoint Engineering, MVPs, or other community members. > [!TIP] -> If you are interested in doing a live demo in any of our community calls, please reach out by leaving a comment on this page and we'll get you a spot for 10-15 minutes for demonstrating your SharePoint development topic(s). +> If you are interested in doing a live demo in any of our community calls, please reach out by [requesting a demo slot](https://aka.ms/community/request/demo) and we'll get you a spot for 10-15 minutes for demonstrating your Microsoft 365 & Power Platform development topic(s). > > **Do's & Dont's**: Interested in presenting during one of the community calls? Keep in mind these are community calls. The focus of these demos should be on learning and topics beneficial to the community. Please refrain from commercial activities such as selling or promoting products or services. Commercial activities in the community calls are not well received by the community and in certain instances may result in stopping the demo early. In your request to present, please be descriptive about what you intend to show to avoid any confusion. If you are not sure if what you want to present is appropriate, just ask in the submission. | Community call | When | Description | Microsoft Teams Link | | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -| [Monthly community call](https://aka.ms/sppnp-call) | Second Tuesday of each month at 8:00 AM PT / 3:00 PM GMT | Monthly community call covering the latest changes in SharePoint development-related topics within the last month, including news, UserVoice updates, and community contributions | [Direct MS Teams link to meeting](https://aka.ms/spdev-call-join) | -| [Special interest group call for SharePoint Framework](https://aka.ms/spdev-spfx-call) | Bi-weekly on Thursdays at 7:00 AM PT / 2:00 PM GMT | SharePoint Engineering updates, SharePoint Framework, PnPJS, Office 365 CLI, and reusable SPFx controls | [Direct MS Teams link to meeting](https://aka.ms/spdev-spfx-call-join) | -| [Special interest group call for general SharePoint development](https://aka.ms/spdev-sig-call) | Bi-weekly on Thursdays at 7:00 AM PT / 2:00 PM GMT | SharePoint Engineering updates, end-to-end solution designs, provisioning, PnP CSOM, and PnP PowerShell | [Direct MS Teams link to meeting](https://aka.ms/spdev-sig-call-join) | +| [Microsoft 365 & Power Platform Call (Microsoft Speakers)](https://aka.ms/community/ms-speakers-call-invite) | Weekly on Tuesdays at 8:00 AM PT / 3:00 PM GMT | Community call with Microsoft speakers covering the latest news from Microsoft engineerung on the Microsoft 365 & Power Platform topics including news, UserVoice updates, and demos | [Direct MS Teams link to meeting](https://aka.ms/community/ms-speakers-call-join) | +| [Viva Connections and SharePoint Framework community call](https://aka.ms/spdev-spfx-call) | Bi-weekly on Thursdays at 7:00 AM PT / 2:00 PM GMT | SharePoint Engineering updates, SharePoint Framework, PnPJS, CLI for Microsoft 365, and reusable SPFx controls | [Direct MS Teams link to meeting](https://aka.ms/spdev-spfx-call-join)| +| [Microsoft 365 & Power Platform Development Community call](https://aka.ms/community/m365-powerplat-dev-call-invite) | Bi-weekly on Thursdays at 7:00 AM PT / 2:00 PM GMT | Latest on Latest on PnP Framework and Core SDK extension, PnP PowerShell, yo Teams, Microsoft Graph Toolkit, Independent Publisher Connector Updates plus community demos | [Direct MS Teams link to meeting](https://aka.ms/community/m365-powerplat-dev-call-join) | ## What’s the supportability statement around PnP open-source components and solutions? diff --git a/docs/community/contribute.md b/docs/community/contribute.md index 5ee18d002..dfe50aef8 100644 --- a/docs/community/contribute.md +++ b/docs/community/contribute.md @@ -1,9 +1,8 @@ --- title: SharePoint Developer Community contribution description: Contribution options towards the SharePoint Developer Community. -ms.date: 03/29/2018 -ms.prod: sharepoint -localization_priority: Normal +ms.date: 06/07/2022 +ms.localizationpriority: medium --- # SharePoint Developer Community - How to contribute @@ -15,7 +14,7 @@ There are multiple ways to contribute to the SharePoint Developer Community (Sha * Do a live demo of your sample, solution, or architecture design in the SharePoint community calls. * Report and fix issues within the GitHub repositories in the [SharePoint GitHub Organization](http://github.com/sharepoint). * Report issues in the GitHub issue lists to help others find where they can assist. -* Provide input on new feature requests within [SharePoint Developer UserVoice](https://sharepoint.uservoice.com/forums/329220-sharepoint-dev-platform). +* Provide input on new feature requests within [Feedback Portal: SharePoint](https://feedbackportal.microsoft.com/feedback/forum/06735c62-321c-ec11-b6e7-0022481f8472).. ## FAQ @@ -46,4 +45,3 @@ Awesome! Here are a few suggestions: * Suggest a live demo in one of the community calls. If you have other ideas on how you might contribute, don't hesitate to reach out and let us know. - diff --git a/docs/community/open-source-projects.md b/docs/community/open-source-projects.md index 7fd6fb579..e3f81365e 100644 --- a/docs/community/open-source-projects.md +++ b/docs/community/open-source-projects.md @@ -1,25 +1,21 @@ --- title: SharePoint Developer Community open source projects description: Open-source projects coordinated by the SharePoint PnP initiative -ms.date: 06/18/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 06/07/2022 +ms.localizationpriority: high --- # SharePoint Developer Community - Open-source projects There are numerous open-source projects that are coordinated by the SharePoint PnP initiative. These are open-source, community-driven initiatives that are still closely involved with SharePoint engineering, but are not part of the standard product or service offerings. -
- | Repository | Description | |--------|--------| | [SharePoint Starter kit](https://github.com/SharePoint/sp-starter-kit) | A starter kit for showing how to extend modern experiences in SharePoint Online by extending them with modern extensibility options. | -| [SharePoint Provisioning Service templates](https://github.com/SharePoint/sp-dev-provisioning-templates) | Tenant templates used by the [SharePoint Provisioning Service](https://provisioning.sharepointpnp.com) to easily provision sample content and structures demonstrating what's possible with modern SharePoint experiences. | -| [GDPR Activity Hub](https://github.com/SharePoint/sp-dev-gdpr-activity-hub) | A starter kit for building a management hub for EU GDPR (European Global Data Protection Regulation). | -| [Office 365 CLI](https://sharepoint.github.io/office365-cli/) | A cross-platform command-line interface (CLI) that allows users on any platform to manage various configuration settings of Office 365. | +| [SharePoint Provisioning Service templates](https://github.com/SharePoint/sp-dev-provisioning-templates) | Tenant templates previously used by the Look Book Services to easily provision sample content and structures demonstrating what's possible with modern SharePoint experiences. | +| [CLI for Microsoft 365](https://pnp.github.io/cli-microsoft365/) | A cross-platform command-line interface (CLI) that allows users on any platform to manage their Microsoft 365 and SharePoint Framework projects. | | [Office 365 Developer PnP Core Component](https://github.com/SharePoint/PnP-Sites-Core) | An extension component that encapsulates commonly used remote CSOM/REST operations as reusable extension methods on out-of-the box CSOM objects. | -| [PnP PowerShell cmdlets](https://docs.microsoft.com/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps) | Allow you to perform complex provisioning and artifact management actions for SharePoint. The commands use CSOM and can work against both SharePoint Online as well as SharePoint on-premises. | +| [PnP PowerShell cmdlets](/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets) | Allow you to perform complex provisioning and artifact management actions for SharePoint. The commands use CSOM and can work against both SharePoint Online as well as SharePoint on-premises. | | [PnP remote provisioning schema](https://github.com/SharePoint/PnP-provisioning-schema) | Designed to be used as remote creation instructions for the remote provisioning engine for Office 365. | | [SharePoint Modernization tooling and guidance](https://github.com/SharePoint/sp-dev-modernization) | Tools like page transformation (classic page to modern page) and a modernization scanner do make it easy to move your classic sites into the modern SharePoint world. | | [PnPjs](https://pnp.github.io/pnpjs/) | A fluent JavaScript API for consuming SharePoint and Office 365 REST APIs in a type-safe way. | diff --git a/docs/community/repositories.md b/docs/community/repositories.md index 3961c8da3..7f09fcba3 100644 --- a/docs/community/repositories.md +++ b/docs/community/repositories.md @@ -1,9 +1,8 @@ --- title: SharePoint Developer GitHub repositories description: List of different SharePoint Developer GitHub repositories and their description -ms.date: 03/29/2018 -ms.prod: sharepoint -localization_priority: Priority +ms.date: 09/23/2022 +ms.localizationpriority: high --- # SharePoint Developer GitHub repositories @@ -20,13 +19,13 @@ There are numerous SharePoint Developer GitHub repositories, which all have diff | Repository | Description | |--------|--------| -| [sp-dev-docs](https://github.com/SharePoint/sp-dev-docs) | Source for SharePoint dev documentation exposed at https://docs.microsoft.com/sharepoint/dev/ | +| [sp-dev-docs](https://github.com/SharePoint/sp-dev-docs) | Source for SharePoint dev documentation exposed at `https://learn.microsoft.com/sharepoint/dev/` | | [sp-dev-fx-webparts](https://github.com/SharePoint/sp-dev-fx-webparts) | Samples and tutorial code around SharePoint Framework client-side web parts | | [sp-dev-fx-extensions](https://github.com/SharePoint/sp-dev-fx-extensions) | Samples and tutorial code around SharePoint Framework extensions | | [sp-dev-modernization](https://github.com/SharePoint/sp-dev-modernization) | Solutions, tools and script to help you modernize your sites | | [sp-dev-solutions](https://github.com/SharePoint/sp-dev-solutions) | More polished and fine-tuned reusable solutions built with the SharePoint Framework | -| [sp-dev-list-formatting](https://github.com/SharePoint/sp-dev-list-formatting) | Various [column formatting](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting) json files shared among the community | -| [sp-dev-site-scripts](https://github.com/SharePoint/sp-dev-site-scripts) | Various [Site Script and Site Design](https://docs.microsoft.com/sharepoint/dev/declarative-customization/site-design-overview) json files shared among the community | +| [sp-dev-list-formatting](https://github.com/SharePoint/sp-dev-list-formatting) | Various [column formatting](../declarative-customization/column-formatting.md) json files shared among the community | +| [sp-dev-site-scripts](https://github.com/SharePoint/sp-dev-site-scripts) | Various [Site Script and Site Design](../declarative-customization/site-design-overview.md) json files shared among the community | | [sp-dev-fx-controls-react](https://github.com/SharePoint/sp-dev-fx-controls-react) | Reusable content controls for SharePoint Framework solutions built with React | | [sp-dev-fx-property-controls](https://github.com/SharePoint/sp-dev-fx-property-controls) | Reusable property pane controls for use in SharePoint Framework web parts | | [sp-dev-gdpr-activity-hub](https://github.com/SharePoint/sp-dev-gdpr-activity-hub) | A reference solution for the business case of GDPR demonstrating an SPFx implementation with Power BI and modern sites | @@ -40,14 +39,14 @@ There are numerous SharePoint Developer GitHub repositories, which all have diff |--------|--------| | [pnp](https://github.com/SharePoint/pnp) | Main repository for SharePoint Add-ins, Microsoft Graph, and other samples | | [pnp-sites-core](https://github.com/SharePoint/pnp-sites-core) | Office Dev PnP CSOM Core component - Extension component for native SharePoint Client-Side Object Model | -| [pnp-powershell](https://github.com/SharePoint/pnp-powershell) | Source code for [SharePoint PnP PowerShell cmdlets](https://docs.microsoft.com/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps) | +| [pnp-powershell](https://github.com/SharePoint/pnp-powershell) | Source code for [SharePoint PnP PowerShell cmdlets](/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets) | | [pnp-provisioning-schema](https://github.com/SharePoint/PnP-Provisioning-Schema) | PnP provisioning engine schema repository | | [pnp-tools](https://github.com/SharePoint/PnP-Tools) | Repository for tools and scripts targeted primarily for IT pros and for on-premises SharePoint 2013 and SharePoint 2016 | | [pnp-partner-pack](https://github.com/SharePoint/PnP-Partner-Pack) | Packaged guidance with detailed instructions about setting things up in Office 365 and Azure | | [pnp-js-core](https://github.com/SharePoint/PnP-JS-Core) | Office Dev PnP Core component for JavaScript | | [pnp-transformation](https://github.com/SharePoint/PnP-Transformation) | Material specifically for the transformation process. Currently, includes samples around InfoPath replacement and transformation tooling from farm solutions to the add-in model | -| [pnp-js-provisioning](https://github.com/SharePoint/pnp-js-provisioning) | Repository for planned JavaScript provisioning library | -| [pnp-provisioning-templates](https://github.com/SharePoint/PnP-Provisioning-Templates) | Source for templates available from the PnP Template Gallery at http://templates-gallery.sharepointpnp.com | +| [pnp-js-provisioning](https://github.com/pnp/sp-js-provisioning) | Repository for planned JavaScript provisioning library | +| [pnp-provisioning-templates](https://github.com/SharePoint/PnP-Provisioning-Templates) | Repository for provisioning templates. | [pnp-guidance](https://github.com/SharePoint/PnP-Guidance) | Old repository on guidance, presentations, and articles that were partially synced to MSDN | | [pnp-identitymodel](https://github.com/SharePoint/PnP-IdentityModel) | Open source replacement of Microsoft.IdentityModel.Extensions.dll | diff --git a/docs/community/social-media.md b/docs/community/social-media.md new file mode 100644 index 000000000..de4293a18 --- /dev/null +++ b/docs/community/social-media.md @@ -0,0 +1,18 @@ +--- +title: Social Media +description: Please monitor and follow the Microsoft 365 community and Microsoft 365, Office, and SharePoint developers on social media. +author: andrewconnell +ms.author: v-johnco +ms.date: 06/03/2022 +ms.audience: Developer +ms.localizationpriority: high +--- + +# SharePoint Development on Social Media + +Please monitor and follow us on Twitter: + +- [@Microsoft365Dev](https://twitter.com/Microsoft365Dev) +- [@OfficeDev](https://twitter.com/officedev) +- [@SharePoint](https://twitter.com/sharepoint) +- [@m365pnp](https://twitter.com/m365pnp) diff --git a/docs/declarative-customization/column-formatting.md b/docs/declarative-customization/column-formatting.md index b257dad33..7e933a74c 100644 --- a/docs/declarative-customization/column-formatting.md +++ b/docs/declarative-customization/column-formatting.md @@ -1,15 +1,15 @@ --- title: Use column formatting to customize SharePoint description: Customize how fields in SharePoint lists and libraries are displayed by constructing a JSON object that describes the elements that are displayed when a field is included in a list view, and the styles to be applied to those elements. -ms.date: 08/21/2019 -localization_priority: Priority +ms.date: 09/08/2022 +ms.localizationpriority: high --- # Use column formatting to customize SharePoint -You can use column formatting to customize how fields in SharePoint lists and libraries are displayed. To do this, you construct a JSON object that describes the elements that are displayed when a field is included in a list view, and the styles to be applied to those elements. The column formatting does not change the data in the list item or file; it only changes how it’s displayed to users who browse the list. Anyone who can create and manage views in a list can use column formatting to configure how view fields are displayed. +You can use column formatting to customize how fields in SharePoint lists and libraries are displayed. To do this, you construct a JSON object that describes the elements that are displayed when a field is included in a list view, and the styles to be applied to those elements. The column formatting doesn't change the data in the list item or file; it only changes how it’s displayed to users who browse the list. Anyone who can create and manage views in a list can use column formatting to configure how view fields are displayed. -For example, a list with the fields Title, Effort, Assigned To, and Status with no customizations applied might look like this: +For example, a list with the fields Title, Effort, Assigned To, and Status with no customizations applied might look like this: ![SharePoint list with four unformatted columns](../images/sp-columnformatting-none.png) @@ -22,19 +22,19 @@ A list with the appearance of the **Effort**, **Assigned To**, and **Status** fi ## How is column formatting different than the Field Customizer? -Both column formatting and [SharePoint Framework Field Customizer](https://docs.microsoft.com/sharepoint/dev/spfx/extensions/get-started/building-simple-field-customizer) extensions enable you to customize how fields in SharePoint lists are displayed. The Field Customizer is more powerful because you can use it to write any code that you want to control how a field is displayed. +Both column formatting and [SharePoint Framework Field Customizer](../spfx/extensions/get-started/building-simple-field-customizer.md) extensions enable you to customize how fields in SharePoint lists are displayed. The Field Customizer is more powerful because you can use it to write any code that you want to control how a field is displayed. -Column formatting is more easily and broadly applied. However, it is less flexible, because it does not allow for custom code; it only allows for certain predefined elements and attributes. +Column formatting is more easily and broadly applied. However, it's less flexible, because it doesn't allow for custom code; it only allows for certain predefined elements and attributes. The following table compares column formatting and the Field Customizer. | Field type | Column formatting | Field Customizer | | ------------- |:-------------| :-----| | Conditional formatting based on item values and value ranges | Supported | Supported | -| Action links | Support for static hyperlinks that do not launch script | Support for any hyperlink, including those that invoke custom script | +| Action links | Support for static hyperlinks that don't launch script | Support for any hyperlink, including those that invoke custom script | | Data visualizations | Support for simple visualizations that can be expressed using HTML and CSS | Support for arbitrary data visualizations | -If you can accomplish your scenario by using column formatting, it’s typically quicker and easier to do that than to use a Field Customizer. Anyone who can create and manage views in a list can use column formatting to create and publish customizations. Use a Field Customizer for more advanced scenarios that column formatting does not support. +If you can accomplish your scenario by using column formatting, it’s typically quicker and easier to do that than to use a Field Customizer. Anyone who can create and manage views in a list can use column formatting to create and publish customizations. Use a Field Customizer for more advanced scenarios that column formatting doesn't support. ## Get started with column formatting @@ -51,7 +51,7 @@ To preview the formatting, select **Preview**. To commit your changes, select ** The easiest way to use column formatting is to start from an example and edit it to apply to your specific field. The following sections contain examples that you can copy, paste, and edit for your scenarios. There are also several samples available in the [SharePoint/sp-dev-column-formatting repository](https://github.com/SharePoint/sp-dev-column-formatting). > [!NOTE] -> All examples in this document refer to the json schema used in SharePoint Online. To format columns on SharePoint 2019, please use `https://developer.microsoft.com/json-schemas/sp/v1/column-formatting.schema.json` as the schema. +> All examples in this document refer to the JSON schema used in SharePoint Online and SharePoint Server Subscription Edition starting with the Version 22H2 feature update. To format columns in SharePoint 2019 or SharePoint Server Subscription Edition before the Version 22H2 feature update, please use `https://developer.microsoft.com/json-schemas/sp/v1/column-formatting.schema.json` as the schema. ## Display field values (basic) @@ -134,7 +134,7 @@ The following image shows an example of conditional formatting applied to a text ![Status field with done colored green, blocked colored red, and in review colored orange](../images/sp-columnformatting-conditionaladvanced.png) -You can apply conditional formatting to text or choice fields that might contain a fixed set of values. The following example applies different classes depending on whether the value of the field is Done, In Review, Has Issues, or another value. This example applies a CSS class (`sp-field-severity--low, sp-field-severity--good, sp-field-severity--warning, sp-field-severity--severeWarning, sp-field-severity--blocked`) to the `
` based on the field's value. It then outputs a `` element with an `IconName` attribute. This attribute automatically applies another CSS class to that `` that shows an [Office UI Fabric](https://dev.office.com/fabric#/) icon inside that element. Finally, another `` element is output that contains the value inside the field. +You can apply conditional formatting to text or choice fields that might contain a fixed set of values. The following example applies different classes depending on whether the value of the field is Done, In Review, Has Issues, or another value. This example applies a CSS class (`sp-field-severity--low, sp-field-severity--good, sp-field-severity--warning, sp-field-severity--severeWarning, sp-field-severity--blocked`) to the `
` based on the field's value. It then outputs a `` element with an `IconName` attribute. This attribute automatically applies another CSS class to that `` that shows an [Fluent UI](https://developer.microsoft.com/fluentui#/) icon inside that element. Finally, another `` element is output that contains the value inside the field. This pattern is useful when you want different values to map to different levels of urgency or severity. You can start from this example and edit it to specify your own field values and the styles and icons that should map to those values. @@ -174,7 +174,7 @@ The following image shows a field with conditional date formatting applied: ![Status field with the Overdue text colored red](../images/sp-columnformatting-overdue.png) -This example colors the current field red when the value inside an item's DueDate is before the current date/time. Unlike some of the previous examples, this example applies formatting to one field by looking at the value inside another field. Note that DueDate is referenced using the `[$FieldName]` syntax. FieldName is assumed to be the internal name of the field. This example also takes advantage of a special value that can be used in date/time fields - `@now`, which resolves to the current date/time, evaluated when the user loads the list view. +This example colors the current field red when the value inside an item's DueDate is before the current date/time. Unlike some of the previous examples, this example applies formatting to one field by looking at the value inside another field. Note that `DueDate` is referenced using the `[$FieldName]` syntax. FieldName is assumed to be the internal name of the field. This example also takes advantage of a special value that can be used in date/time fields - `@now`, which resolves to the current date/time, evaluated when the user loads the list view. > [!NOTE] > If you have spaces in the field name, those are defined as `_x0020_`. For example, a field named "Due Date" should be referenced as `$Due_x0020_Date`. @@ -193,7 +193,7 @@ This example colors the current field red when the value inside an item's DueDat ### Formatting items based on arbitrary dates (advanced) -To compare the value of a date/time field against a date that's not `@now`, follow the pattern in the following example. The following example colors the current field red if the due date was <= tomorrow. This is accomplished using date math. You can add milliseconds to any date and the result will be a new date. For example, to add a day to a date, you'd add (24\*60\*60\*1000 = 86,400,000). +To compare the value of a date/time field against a date that's not `@now`, follow the pattern in the following example. The following example colors the current field red if the due date was <= tomorrow. This is accomplished using date math. You can add milliseconds to any date and the result will be a new date. For example, to add a day to a date, you'd add (24\*60\*60\*1000 = 86,400,000). This example demonstrates an alternate syntax to express a conditional expression, using the ternary (`?`) operator inside an abstract syntax tree. @@ -289,7 +289,9 @@ Here's the same sample from above, using the Excel-style expression syntax: ## Create clickable actions -You can use column formatting to provide hyperlinks that go to other webpages, or start custom functionality. This functionality is limited to static links that can be paramaterized with values from fields in the list. You can't use column formatting to output links to protocols other than `http://`, `https://`, or `mailto:`. +You can use column formatting to provide hyperlinks that go to other webpages, or start custom functionality. This functionality is limited to static links that can be parameterized with values from fields in the list. You can't use column formatting to output links to protocols other than `http://`, `https://`, `mailto:` or `tel:`. + +`tel:` protocol only allows digits, `*+#` special characters and `.-/()` visual separators. ### Turn field values into hyperlinks (basic) @@ -309,6 +311,10 @@ This example shows how to turn a text field that contains stock ticker symbols i } ``` +> [!TIP] +> In a List Web Part, the above anchor tag will navigate user to a new tab. In order to navigate within the same tab, add `data-interception` attribute and set it to `on`. [More information about data-interception attibute.](../spfx/hyperlinking.md) + + ### Add an action button to a field (advanced) The following image shows action buttons added to a field. @@ -318,7 +324,7 @@ The following image shows action buttons added to a field. You can use column formatting to render quick action links next to fields. The following example, intended for a person field, renders two elements inside the parent `
` element: - A `` element that contains the person’s display name. -- An `` element that opens a mailto: link that creates an email with a subject and body populated dynamically via item metadata. The `` element is styled using the `ms-Icon`, `ms-Icon—Mail`, and `ms-QuickAction` [Fabric](https://developer.microsoft.com/fabric) classes to make it look like a clickable email icon. +- An `` element that opens a mailto: link that creates an email with a subject and body populated dynamically via item metadata. The `` element is styled using the `ms-Icon`, `ms-Icon—Mail`, and `ms-QuickAction` [Fluent UI](https://developer.microsoft.com/fluentui) classes to make it look like a clickable email icon. ```JSON { @@ -334,6 +340,9 @@ You can use column formatting to render quick action links next to fields. The f }, { "elmType": "a", + "style": { + "text-decoration": "none" + }, "attributes": { "iconName": "Mail", "class": "sp-field-quickActions", @@ -468,7 +477,7 @@ Here's the same sample from above, using the Excel-style expression syntax: "elmType": "span", "attributes": { "class": "=if([$After] > [$Before], 'sp-field-trending--up', 'sp-field-trending--down')", - "iconName": "=if([$After] > [$Before], 'SortUp', "=if([$After] < [$Before], 'SortDown', ''))" + "iconName": "=if([$After] > [$Before], 'SortUp', if([$After] < [$Before], 'SortDown', ''))" } }, { @@ -479,56 +488,6 @@ Here's the same sample from above, using the Excel-style expression syntax: } ``` -## Create a button to launch a Flow - -The following screenshot shows a list with a Flow button added to the Action column: - -![screenshot of the sample](../images/sp-columnformatting-flow.png) - -You can use column formatting to create buttons that, when selected, run Flows on the corresponding list item. The Flow Launch Panel will be displayed after choosing the button and the Flow will just run. - -To use the sample below, you must substitute the ID of the Flow you want to run. This ID is contained within the `customRowAction` attribute inside the `button` element. To obtain a Flow's ID: - -1. Choose Flow > See your flows in the SharePoint list where the Flow is configured. -2. Choose the Flow you want to run. -3. Copy the ID from the end of the URL. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "button", - "customRowAction": { - "action": "executeFlow", - "actionParams": "{\"id\": \"edf627d9-20f4-45ba-8bc9-4494bf2ff1be\"}" - }, - "attributes": { - "class": "ms-fontColor-themePrimary ms-fontColor-themeDarker--hover" - }, - "style": { - "border": "none", - "background-color": "transparent", - "cursor": "pointer" - }, - "children": [ - { - "elmType": "span", - "attributes": { - "iconName": "Flow" - }, - "style": { - "padding-right": "6px" - } - }, - { - "elmType": "span", - "txtContent": "It's Flow Time!" - } - ] -} -``` - -Additionally, you can use `headerText` and `runFlowButtonText` options within the `actionParams` property to customize portions of the Flow panel itself! See the [button elements](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting#button-elements) portion of the Detailed syntax reference for more details. - ## Formatting multi-value fields You can use column formatting to apply styles to each member of a multi-value field of type Person, Lookup and Choice. @@ -546,7 +505,8 @@ This example uses the `length` operator to detect the number of members of the f "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", "elmType": "a", "style": { - "display": "=if(length(@currentField) > 0, 'flex', 'none')" + "display": "=if(length(@currentField) > 0, 'flex', 'none')", + "text-decoration": "none" }, "attributes": { "href": { @@ -595,7 +555,7 @@ The following image shows an example of constructing a simple sentence from the ![Screenshot of a field reads "North America, APAC, and Europe"](../images/sp-columnformatting-multi-value-1.png) -This examples uses operator `loopIndex` and `length` to identify the last member of the field, and attribute `forEach` to duplicate HTML elements. +This example uses operator `loopIndex` and `length` to identify the last member of the field, and attribute `forEach` to duplicate HTML elements. ```json { @@ -629,11 +589,12 @@ This examples uses operator `loopIndex` and `length` to identify the last member ``` ### Complex HTML elements formatting + The following image shows an example of building a list of users with pictures, email addresses and a simple counter for the number of members at the top. ![List with name "Owners" and 3 rows where each user in the field has a profile picture, name and email displayed, and a small gray counter of owners at top left corner that has a different color when it says 0.](../images/sp-columnformatting-multi-value-2.png) -This examples uses operator `loopIndex` to control the margins all rows but the first one, and attribute `forEach` to build the list of members. +This example uses operator `loopIndex` to control the margins all rows but the first one, and attribute `forEach` to build the list of members. ```json { @@ -679,7 +640,7 @@ This examples uses operator `loopIndex` to control the margins all rows but the { "elmType": "img", "attributes": { - "src": "=[$person.picture]" + "src": "=getUserImage([$person.email], 'S')" }, "style": { "width": "3em", @@ -728,10 +689,11 @@ The following column types support column formatting: * Choice * ContentType * Counter (ID) -* Currency* +* Currency * Date/Time * Hyperlink -* Location* +* Image +* Location * Lookup * Multi-Choice * Multi-Line Text @@ -742,14 +704,18 @@ The following column types support column formatting: * Single line of text * Title (in Lists) * Yes/No - -_* Formats for these column types can only be applied through Field Settings_ +* Managed Metadata +* Average Rating +* Likes +* Approval Status +* Attachments The following are currently **not** supported: -* Managed Metadata * Filename (in Document Libraries) * Retention Label +* Sealed columns +* Multi-Line Text column with enhanced rich text ## Style guidelines @@ -773,866 +739,28 @@ You can use the following predefined classes for several common scenarios. > [!NOTE] > The icons shown above for the `sp-field-severity` classes are **NOT** part of the class. Only the background color is included. Icons can be added by using the `iconName` attribute. -In addition to the classes listed above, the classes (such as the theme color, typography, grid system, etc.) defined by the Office UI Fabric can be used. For details, see the [Fabric website](https://dev.office.com/fabric#/styles/colors). +In addition to the classes listed above, the classes (such as the theme color, typography, grid system, etc.) defined by the Fluent UI can be used. For details, see the [Fluent UI website](https://developer.microsoft.com/fluentui#/styles/web/colors/products). ### Predefined icons -You can use predefined icons from Office UI Fabric. For details, see the [Fabric website](https://dev.office.com/fabric#/styles/icons). +You can use predefined icons from Fluent UI. For details, see the [Fluent UI website](https://developer.microsoft.com/fluentui#/styles/web/icons). ## Creating custom JSON -Creating custom column formatting JSON from scratch is simple if you understand the schema. To create your own custom column formatting: - -1. [Download Visual Studio Code](https://code.visualstudio.com/Download). It's free and fast to download. - -2. In Visual Studio Code, create a new file, and save the empty file with a .json file extension. - -3. Paste the following lines of code into your empty file. - - ```JSON - { - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json" - } - ``` - - You now have validation and autocomplete to create your JSON. You can start adding your JSON after the first line that defines the schema location. +Creating custom column formatting JSON from scratch is simple if user understands the schema, Monaco Editor is integrated in the formatting pane with pre-filled JSON column schema reference to help creation of column formatting, Monaco editor has validation and autocomplete to help in crafting right JSON. User can start adding JSON after the first line that defines the schema location. > [!TIP] -> At any point, select **Ctrl**+**Space** to have Visual Studio Code offer suggestions for properties and values. For more information, see [Editing JSON with Visual Studio Code](https://code.visualstudio.com/Docs/languages/json). +> At any point, select **Ctrl**+**Space** for property/value suggestions. > [!TIP] -> SharePoint Patterns and Practices provides a free web part, [Column Formatter](https://github.com/SharePoint/sp-dev-solutions/blob/master/solutions/ColumnFormatter/docs/documentation/docs/getting-started.md), that can be used to edit and apply formats directly in the browser. - -## Detailed syntax reference - -### elmType - -Specifies the type of element to create. Valid elements include: - -- div -- span -- a -- img -- svg -- path -- button - -Any other value will result in an error. - -#### button elements - -`Button` elements can be used to launch a specific action on the parent item. Every `button` element has a required property, `customRowAction`, that specifies an `action` that's taken when the button is clicked. This action must be one of the following values: - -- **defaultClick**: buttons with this action will do the same thing as clicking the list item in an uncustomized view. Below is an example of a button that, when clicked, simulates a click on the item, which results in the details pane being opened. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "button", - "txtContent": "Open this item", - "customRowAction": { - "action": "defaultClick" - } -} - -``` - -- **share**: Clicking the button will open the sharing dialog. Below is an example of this type of button. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "button", - "txtContent": "Share this item", - "customRowAction": { - "action": "share" - } -} - -``` - -- **delete**: Clicking the button will open the delete confirmation dialog. -- **editProps**: Clicking the button will open the item properties page in edit mode. -- **executeFlow**: Clicking the button will launch the specified Flow, specified by ID inside the `actionParams` attribute. For an example of this, see the [Create a button to launch a Flow](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting#create-a-button-to-launch-a-flow) section in this document. Below is an example of this type of button. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json", - "elmType": "button", - "txtContent": "It's Flow Time!", - "customRowAction": { - "action": "executeFlow", - "actionParams": "{\"id\":\"f7ecec0b-15c5-419f-8211-302a5d4e94f1\", \"headerText\":\"It's Flow Time!\",\"runFlowButtonText\":\"Do it\"}" - } -} -``` - -The `actionParams` attribute can have the following options when using the `executeFlow` action: -- **id**: ID of the Flow to launch _(required)_ -- **headerText**: Sets the text at the top of the flow panel _(optional)_ -- **runFlowButtonText**: Sets the text of the primary button in the flow panel _(optional)_ - -### txtContent - -An optional property that specifies the text content of the element specified by `elmType`. The value of this property can either be a string (including special strings) or an Expression object. - -### style - -An optional property that specifies style attributes to apply to the element specified by `elmType`. This is an object with name-value pairs that correspond to CSS names and values. The values of each property in the style object can either be a string (including special strings) or an Expression object. The following style attributes are allowed. - - 'background-color' - 'fill' - 'background-image' - 'border' - 'border-bottom' - 'border-bottom-color' - 'border-bottom-style' - 'border-bottom-width' - 'border-color' - 'border-left' - 'border-left-color' - 'border-left-style' - 'border-left-width' - 'border-right' - 'border-right-color' - 'border-right-style' - 'border-right-width' - 'border-style' - 'border-top' - 'border-top-color' - 'border-top-style' - 'border-top-width' - 'border-width' - 'outline' - 'outline-color' - 'outline-style' - 'outline-width' - 'border-bottom-left-radius' - 'border-bottom-right-radius' - 'border-radius' - 'border-top-left-radius' - 'border-top-right-radius' - 'box-decoration-break' - 'box-shadow' - 'box-sizing' - - 'overflow-x' - 'overflow-y' - 'overflow-style' - 'rotation' - 'rotation-point' - - 'opacity' - 'cursor' - - 'height' - 'max-height' - 'max-width' - 'min-height' - 'min-width' - 'width' - - 'flex-grow' - 'flex-shrink' - 'flex-flow' - 'flex-direction' - 'flex-wrap' - 'flex' - 'justify-content' - 'align-items' - - 'box-align' - 'box-direction' - 'box-flex' - 'box-flex-group' - 'box-lines' - 'box-ordinal-group' - 'box-orient' - 'box-pack' - - 'font' - 'font-family' - 'font-size' - 'font-style' - 'font-variant' - 'font-weight' - 'font-size-adjust' - 'font-stretch' - - 'grid-columns' - 'grid-rows' - - 'margin' - 'margin-bottom' - 'margin-left' - 'margin-right' - 'margin-top' - - 'column-count' - 'column-fill' - 'column-gap' - 'column-rule' - 'column-rule-color' - 'column-rule-style' - 'column-rule-width' - 'column-span' - 'column-width' - 'columns' - - 'padding' - 'padding-bottom' - 'padding-left' - 'padding-right' - 'padding-top' - - 'bottom' - 'clear' - 'clip' - 'display' - 'float' - 'left' - 'overflow' - 'position' - 'right' - 'top' - 'visibility' - 'z-index' - - 'border-collapse' - 'border-spacing' - 'caption-side' - 'empty-cells' - 'table-layout' - - 'color' - 'direction' - 'letter-spacing' - 'line-height' - 'text-align' - 'text-decoration' - 'text-indent' - 'text-transform' - 'unicode-bidi' - 'vertical-align' - 'white-space' - 'word-spacing' - 'hanging-punctuation' - 'punctuation-trim' - 'text-align-last' - 'text-justify' - 'text-outline' - 'text-shadow' - 'text-wrap' - 'word-break' - 'word-wrap' - -The following example shows the value of a style object. In this example, two style properties (`padding` and `background-color`) will be applied. The `padding` value is a hard-coded string value. The `background-color` value is an Expression that is evaluated to either red (`#ff0000`) or green (`#00ff00`) depending on whether the value of the current field (specified by `@currentField`) is less than 40. For more information, see the Expression object section. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "div", - "style": { - "padding": "4px", - "background-color": { - "operator": "?", - "operands": [ - { - "operator": "<", - "operands": [ - "@currentField", - 40 - ] - }, - "#ff0000", - "#00ff00" - ] - } - } -} -``` - -Here's the same sample from above, using the Excel-style expression syntax: - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "div", - "style": { - "padding": "4px", - "background-color": "=if(@currentField < 40, '#ff0000', '#00ff00')" - } -} -``` - -### attributes - -An optional property that specifies additional attributes to add to the element specified by `elmType`. This is an object with name-value pairs. Attribute names must be one of the following: - -- href -- rel -- src -- class -- target -- title -- role -- iconName -- d -- aria - -Any other attribute name will result in an error. Attribute values can either be Expression objects or strings. The following example adds two attributes (`target` and `href`) to the element specified by `elmType`. The `target` attribute is hard-coded to a string. The `href` attribute is an expression that will be evaluated at runtime to http://finance.yahoo.com/quote/ + the value of the current field (`@currentField`). - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "target": "_blank", - "href": "='http://finance.yahoo.com/quote/' + @currentField" -} -``` - -### children - -An optional property that specifies child elements of the element specified by `elmType`. The value is specified as an array of `elm` objects. There can be an arbitrary level of nesting. If an element has the `txtContent` property, the child properties are ignored. - -### debugMode - -An optional property that is meant for debugging. It outputs error messages and logs warnings to the console. - -### forEach - -An optional property that allows an element to duplicate itself for each member of a specific multi-value field. The value of `"forEach"` property should be in the format of either `"iteratorName in @currentField"` or `"iteratatorName in [$FieldName]"`. - -`iteratorName` represents the name of iterator variable that is used to represent the current member of the multi-value field. The name of the iterator can be any combination of alphanumeric characters and underscore (`_`) that does not start with a digit. - -The field used in the loop must be in a supported field type with multi-value option enabled: Person, Lookup, and Choice. - -In the element with `forEach` or its children elements, the iterator variable can be referred as if it is a new field. The index of the iterator can be accessed with `loopIndex` operator. - -`forEach` cannot be applied to the root element, and will render no element if there is no value in the field. - -See [here](#formatting-multi-value-fields) for examples. - -### Expressions - -Values for `txtContent`, style properties, and attribute properties can be expressed as expressions, so that they are evaluated at runtime based on the context of the current field (or row). Expression objects can be nested to contain other Expression objects. - -Expressions can be written using Excel-style expressions in SharePoint Online, or by using Abstract Syntax Tree expressions in SharePoint Online and SharePoint 2019. - -#### Excel-style expressions - -All Excel-style expressions begin with an equal (`=`) sign. This style of expression is only available in SharePoint Online (not SharePoint 2019). - -This simple conditional expression evaluates to `none` if `@me` is not equal to `[$Author.email]`, and evaluates to \`\` otherwise: -```JSON -=if(@me != [$Author.email], 'none', '') -``` - -More complex if/else statements can be written like this: -```JSON -=if([$Sentiment] <= 0.3, 'sp-field-severity--blocked', if([$Sentiment] < 0.9,'sp-field-severity--warning','sp-field-severity--good')) -``` - -Non-conditional operators that take one or two operands can be written like this: -```JSON -=[$foo] * -7 -``` -```JSON -=sin(@currentField) -``` -```JSON -=toString(60 + (sin(6.2831853 * @currentField) * 60)) -``` - -#### Abstract Syntax Tree expressions - -The following example contains an Expression object that performs the following expression: - -`(@currentField > 40) ? '100%' : (((@currentField * 2.5).toString() + '%')` - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "operator": "?", - "operands": [ - { - "operator": ">", - "operands": [ - "@currentField", - "40" - ] - }, - "100%", - { - "operator": "+", - "operands": [ - { - "operator": "toString()", - "operands": [ - { - "operator": "*", - "operands": [ - "@currentField", - 2.5 - ] - } - ] - }, - "%" - ] - } - ] -} -``` - -### Operators - -Operators specify the type of operation to perform. The following operators are valid values: - -- \+ -- \- -- / -- \* -- < -- \> -- == -- != -- <= -- \>= -- || -- && -- toString() -- Number() -- Date() -- cos -- sin -- ? -- toLocaleString() -- toLocaleDateString() -- toLocaleTimeString() -- indexOf -- toLowerCase -- join -- length -- abs -- loopIndex -- floor -- ceiling -- pow -- substring -- getDate -- getMonth -- getYear - -**Binary arthmetic operators** - The following are the standard arithmetic binary operators that expect two operands: - -- \+ -- \- -- / -- \* -- < -- \> -- <= -- \>= - -**Unary operators** - The following are standard unary operators that expect only one operand: - -- **toString()**: returns a string representing the object - - `"txtContent": "=toString(45)"` results in _"45"_ - -- **Number()**: returns the numeric value, if the operand is not a number, NaN is returned - - `"txtContent": "=Number('365')"` results in _365_ - - `"txtContent": "=Number('Wowee')"` results in _NaN_ - - `"txtContent": "=Number(Date('12/26/1981'))"` results in _378190800000_ - -- **Date()**: returns a datetime object from the parameter (converts strings or numbers to dates, sensitive to locale) - - `"txtContent": "=Date('12/26/1981')"` results in _12/26/1981, 12:00:00 AM_ - -- **cos**: returns the cosine of the specified angle which should be specified in radians - - `"txtContent": "=cos(5)"` results in _0.28366218546322625_ - -- **sin**: returns the sine of a number - - `"txtContent": "=sin(90)"` results in _0.8939966636005579_ - -- **toLocaleString()**: returns a language sensitive representation of a date - - `"txtContent":"=toLocaleString(@now)"` results vary based on user's locale, but en-us looks like _"2/5/2019, 1:22:24 PM"_ - -- **toLocaleDateString()**: returns a language sensitive representation of just the date portion of a date - - `"txtContent":"=toLocaleDateString(@now)"` results vary based on user's locale, but en-us looks like _"2/5/2019"_ - -- **toLocaleTimeString()**: returns a language sensitive representation of just the time portion of a date - - `"txtContent":"=toLocaleTimeString(@now)"` results vary based on user's locale, but en-us looks like _"1:22:24 PM"_ - -- **toLowerCase**: returns the value converted to lower case (only works on strings) - _Only available in SharePoint Online_ - - `"txtContent":"=toLowerCase('DogFood')"` results in _"dogfood"_ - -- **abs**: returns the absolute value for a given number - _Only available in SharePoint Online_ - - `"txtContent":"=abs(-45)"` results in _45_ - -- **length**: returns the number of items in an array (multi-select person or choice field), for all other value types it returns 1 when true and 0 when false. It does NOT provide the length of a string value. - _Only available in SharePoint Online_ - - `"txtContent":"=length(@currentField)"` might result in _2_ if there are 2 selected values - - `"txtContent":"=length('Some Text')"` results in _1_ - - `"txtContent":"=length('')"` results in _0_ - - `"txtContent":"=length(45)"` results in _1_ - - `"txtContent":"=length(0)"` results in _0_ - -- **floor**: returns the largest integer less than or equal to a given number. - _Only available in SharePoint Online_ - - `"txtContent":"=floor(45.5)"` results in _45_ - -- **ceiling**: rounds the given number up to the next largest whole number or integer. - _Only available in SharePoint Online_ - - `"txtContent":"=ceiling(45.5)"` results in _46_ - -- **getDate**: returns the day of the month of the given date. - _Only available in SharePoint Online_ - - `"txtContent":"=getDate(Date('12/26/1981'))"` results in _26_ - -- **getMonth**: returns the month in the specified date according to local time, as a zero-based value (where zero indicates the first month of the year). - _Only available in SharePoint Online_ - - `"txtContent":"=getMonth(Date('12/26/1981'))"` results in _11_ - -- **getYear**: returns the year of the given date. - _Only available in SharePoint Online_ - - `"txtContent":"=getYear(Date('12/26/1981'))"` results in _1981_ - -**Binary operators** - The following are operators that expect two operands: - -- **indexOf**: takes 2 operands. The first is the text you would like to search within, the second is the text you would like to search for. Returns the index value of the first occurence of the search term within the string. Indexes start at 0. If the search term is not found within the text, -1 is returned. This operator is case-sensitive. - _Only available in SharePoint Online_ - - `"txtContent": "=indexOf('DogFood', 'Dog')"` results in _0_ - - `"txtContent": "=indexOf('DogFood', 'F')"` results in _3_ - - `"txtContent": "=indexOf('DogFood', 'Cat')"` results in _-1_ - - `"txtContent": "=indexOf('DogFood', 'f')"` results in _-1_ - -- **join**: takes 2 operands. The first is an array (multi-select person or choice field) and the second is the separating string. Returns a string concatenation of the array values separated by the separating string. - _Only available in SharePoint Online_ - - `"txtContent": "=join(@currentField, ', ')"` might result in _"Apple, Orange, Cherry"_ (depending on the selected values) - - `"txtContent": "=join(@currentField.title, '|')"` might result in _"Chris Kent|Vesa Juvonen|Jeff Teper"_ (depending on the selected persons) - -- **pow**: returns the base to the exponent power. - _Only available in SharePoint Online_ - - `"txtContent":"=pow(2,3)"` results in _8_ - -**Ternary operators** - The following are operators that expect three operands: - -- **substring**: returns the part of the string between the start and end indicies. - _Only available in SharePoint Online_ - - `"txtContent":"=substring('DogFood', 3, 4)"` results in _Fo_ - - `"txtContent":"=substring('DogFood', 4, 3)"` results in _Fo_ - - `"txtContent":"=substring('DogFood', 3, 6)"` results in _Food_ - - `"txtContent":"=substring('DogFood', 6, 3)"` results in _Food_ - - The substring() method returns the part of the string between the start and end indexes, or to the end of the string. - -**Conditional operator** - The conditional operator is: - -- **?**: Conditional operations written in Abstract Tree Syntax use `?` as the operator. This is to achieve an expression equivalent to a ? b : c, where if the expression a evaluates to true, then the result is b, else the result is c. For Excel style expressions you write these with an `if` statement. Regardless, there are 3 operands. The first is the condition to evaluate. The second is the result when the condition is true. The third is the result when the condition is false. - - `"txtContent":"=if(4 < 5, 'yes', 'no')"` results in _"yes"_ - - `"txtContent":"=if(4 > 5, 'yes', 'no')"` results in _"no"_ - -**Multi-value field-related operators** - The following operators are only used in a context with multi-value field of type Person, Lookup, or Choice. - -- length -- join -- loopIndex - -`length`, when provided with a field name, returns the number of members in a multi-valued field. When a single-value field is provided, `length` will return 1 when there is a value in that field. - -`join` concatenates values in a multi-value field with a specified separator. The first operand shall point to a value in a multi-value field, e.g. `"@currentField.lookupValue"`, `"[$AssignedTo.title]"`. The second operand shall be a string literal that is the separator that joins the values together. - -`loopIndex`, when provided with a name of iterator variable, returns the current index (starting from 0) of the iterator. The name of iterator must be provided as a string literal. `loopIndex` would only work within the element with respective `forEach` enabled or its children elements. - -See [here](#formatting-multi-value-fields) for examples. - -### operands - -Specifies the parameters, or operands for an expression. This is an array of Expression objects or base values. - -### Special string values - -The values for `txtContent`, styles, and attributes can be either strings or Expression objects. A few special string patterns for retrieving values from the fields in the list and the user's context are supported. - -#### "@currentField" - -Will evaluate to the value of the current field. - -Some field types are represented as objects. To output a value from an object, refer to a particular property inside that object. For example, if the current field is a person/group field, specify `@currentField.title` to retrieve the person's name, which is normally displayed in list views. The following are the field types that are represented as objects with a list of their properties. - -> [!NOTE] -> The `@currentField.title` returns a person's name by default. However, if the person field's Show Field has been adjusted, it may change the value of the `title` property. For example, a person field with the Show Field configured as Department will have the person's department for the `title` property. - -**People fields** - -The people field object has the following properties (with example values): - -```JSON -{ - "id": "122", - "title": "Kalya Tucker", - "email": "kaylat@contoso.com", - "sip": "kaylat@contoso.com", - "picture": "https://contoso.sharepoint.com/kaylat_contoso_com_MThumb.jpg?t=63576928822", - "department":"Human Resources", - "jobTitle":"HR Manager" -} -``` - -**Date/Time fields** - -The value of Date/Time fields can be retrieved a few different ways, depending on the date format you'd like to display. The following methods for converting date values to specific formats are supported: - -* `toLocaleString()` - Displays a date type fully expanded with date and time. -* `toLocaleDateString()` - Displays a date type with just the date. -* `toLocaleTimeString()` - Displays a date type with just the time. - -For example, the following JSON will display the current field (assuming it's a date field) as a date and time string. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "div", - "txtContent": { - "operator": "toLocaleString()", - "operands" : ["@currentField"] - } -} -``` - -Here's the same sample from above, using the Excel-style expression syntax: -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "div", - "txtContent": "=toLocaleString(@currentField)" -} -``` - -**Location fields** - -The location field object has the following properties (with example values): - -```JSON -{ - "Address": { - "City": "Knoxville", - "CountryOrRegion": "United States", - "State": "TN", - "Street": "963 Worlds Fair Park Dr" - }, - "Coordinates": { - "Latitude": "35.961673736572266", - "Longitude": "-83.92420959472656" - }, - "DisplayName": "World's Fair Park", - "LocationUri: "https://www.bingapis.com/api/v6/localentities/8346bf26-6da4-104c-6ba5-2334b83f6ac8?setLang=en" -} -``` - -> [!NOTE] -> Location fields do not currently have a "Format this column" option in the list view and formats applied directly to these fields will need to be done through field settings. - -
- -The following example shows how a location field might be used on a current field. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json", - "elmType": "div", - "style": { - "display": "block" - }, - "children": [ - { - "elmType": "a", - "txtContent": "@currentField.DisplayName", - "attributes": { - "href": "='https://www.bing.com/maps?cp=' + @currentField.Coordinates.Latitude + '~' + @currentField.Coordinates.Longitude + '&lvl=17&sV=2'", - "target": "_blank", - "title": "=@currentField.Coordinates.Latitude + ', ' + @currentField.Coordinates.Longitude" - }, - "style": { - "display": "block" - } - }, - { - "elmType": "div", - "txtContent": "@currentField.Address.Street" - }, - { - "elmType": "div", - "txtContent": "=@currentField.Address.City + ', ' + @currentField.Address.State" - }, - { - "elmType": "div", - "txtContent": "@currentField.Address.CountryOrRegion" - } - ] -} -``` - - -**Lookup fields** - -The lookup field object has the following properties (with example values): - -```JSON -{ - "lookupId": "100", - "lookupValue": "North America", -} -``` - -
- -The following example shows how a lookup field might be used on a current field. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "a", - "txtContent": "@currentField.lookupValue", - "attributes": { - "href": { - "operator": "+", - "operands": [ - "https://contoso.sharepoint.com/teams/Discovery/Lists/Regions/DispForm.aspx?ID=", - "@currentField.lookupId" - ] - }, - "target": "_blank" - } -} -``` - -**Hyperlink fields** - -The hyperlink field object has the following property (with example value): - -```JSON -{ - "desc": "SharePoint Patterns and Practices", -} -``` - -
- -To reference the URL value, use `@currentField`. - -The following example shows how a hyperlink field might be used on a current field. - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "a", - "txtContent": "@currentField.desc", - "attributes": { - "href": "@currentField", - "target": "_blank" - } -} -``` - -#### "[$FieldName]" - -The column is formatted within the context of the entire row. You can use this context to reference the values of other fields within the same row by specifying the **internal name** of the field surrounded by square brackets and preceeded by a dollar sign: `[$InternalName]`. For example, to get the value of a field with an internal name of "MarchSales", use `[$MarchSales]`. - -If the value of a field is an object, the object's properties can be accessed. For example, to access the "Title" property of a person field named "SalesLead", use "[$SalesLead.title]". - -#### "@currentWeb" - -This will evaluate to the absolute url for the site. This is equivalent to the `webAbsoluteUrl` value within the page context. This value is only available in SharePoint Online. - -#### "@me" - -This will evaluate to the email address of the current logged in user. - -This field can be used to display the current user's email address, but more likely it will be used within conditions. The following is an example of setting the color for a person field to red when it is equal to the current logged in user and blue otherwise: - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "div", - "txtContent": "@currentField.title", - "style": { - "color": { - "operator": "?", - "operands": [ - { - "operator": "==", - "operands": [ - "@me", - "@currentField.email" - ] - }, - "red", - "blue" - ] - } - } -} -``` - -Here's the same sample from above, using the Excel-style expression syntax: - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "div", - "txtContent": "@currentField.title", - "style": { - "color": "=if(@me == @currentField.email, 'red', 'blue')" - } -} -``` - -#### "@now" - -This will evaluate to the current date and time. - -#### "@rowIndex" - -This will evaluate to the rendered index of a row within a view. This value is based on render position and will remain consistent based on position even as views are sorted and filtered. Indexes start at 0. This value is only available in SharePoint Online. - -Here's an example of using the value within a view format to apply alternating styles to rows: - -```JSON -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", - "additionalRowClass": "=if(@rowIndex % 2 == 0,'ms-bgColor-themeLighter ms-bgColor-themeLight--hover','')" -} -``` - -#### "@window.innerHeight" - -This will evaluate to a number equal to the height of the browser window (in pixels) when the list was rendered. - -#### "@window.innerWidth" - -This will evaluate to a number equal to the width of the browser window (in pixels) when the list was rendered. - -#### Thumbnails - -In a document library, there is a series of tokens that can be used to retrieve the URL to the thumbnail of a file, including: - -- `@thumbnail.small`, `@thumbnail.medium`, and `@thumbnail.large` evaluate to the thumbnail URL in 3 different predefined sizes. -- `@thumbnail.` evaluates to the URL to the largest thumbnails that is not larger than the bounding size in both width and height. For example, `@thumbnail.150` evaluates to the URL to a thumbnail not larger than 150×150 pixels. -- `@thumbnail.x` evaluates to the URL to the largest thumbnail that is not larger than the bounding width and bounding height. For example, `@thumbnail.100x200` evaluates to the URL to a thumbnail not wider than 100 pixels and not higher than 200 pixels. - -These tokens will yield no value on non-file items including folders. - -> [!NOTE] -> The aspect ratio of thumbnail generated is the same as how the file looks like, changing the bounding sizes will not affect the aspect ratio of the thumbnail. +> You can start from a HTML using [**formatter helper tool**](https://pnp.github.io/List-Formatting/tools/), which can convert HTML and CSS into formatter JSON with inline styles. > [!TIP] -> Thumbnails are only available for a list of supported file formats. It means that sometimes the URL generated is not accessible due to lack of support on certain formats. However, if a valid thumbnail token is set as the _only_ `src` attribute of an `img` tag, we will take care of it and hide the image when it is not available. - -```json -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", - "elmType": "img", - "attributes": { - "src": "@thumbnail.200x150", - "alt": "='Thumbnail of file ' + [$FileLeafRef]" - }, - "style": { - "width": "100%", - "max-width": "100%" - } -} -``` +> SharePoint Patterns and Practices provides a free web part, [Column Formatter](https://github.com/SharePoint/sp-dev-solutions/blob/master/solutions/ColumnFormatter/docs/documentation/docs/getting-started.md), that can be used to edit and apply formats directly in the browser. ## See also - [Column formatting](https://support.office.com/article/Column-formatting-1f927342-2bed-4745-b727-ff8b7ff96b22?ui=en-US&rs=en-US&ad=US) +- [View formatting](./view-formatting.md) +- [Advanced formatting concepts](./formatting-advanced.md) +- [Formatting syntax reference](./formatting-syntax-reference.md) diff --git a/docs/declarative-customization/customize-default-site-design.md b/docs/declarative-customization/customize-default-site-design.md index 2d0fb24b7..afffc07db 100644 --- a/docs/declarative-customization/customize-default-site-design.md +++ b/docs/declarative-customization/customize-default-site-design.md @@ -1,66 +1,60 @@ ---- -title: Customize default site designs in SharePoint -description: Customize the default site designs in either the SharePoint Team site or Communication site template. -ms.date: 04/20/2018 -localization_priority: Priority ---- - -# Customize a default site design - -SharePoint contains several site designs already available in the SharePoint Online site templates. These are the default site designs. You can modify them by using PowerShell or the REST APIs to control the entire site provisioning experience. For example, you can ensure that your company theme is applied to every site that gets created, or you can make sure a logging mechanism always runs regardless of which site design is chosen. - -## Apply a site design to the default site designs - -To customize the default site designs, apply a new one with the PowerShell **Add-SPOSiteDesign** cmdlet or the **CreateSiteDesign** REST API. Specify the **IsDefault** switch to apply the site design as the default. - -The WebTemplate ID for a group-connected Team site is 64; for a Communication site it is 68. - -The following example shows how to use the **IsDefault** switch to apply the Contoso company theme to the default site designs. The site script referenced by ID contains the JSON script to apply the correct theme. - -```powershell -C:\> Add-SPOSiteDesign ` - -Title "Contoso company theme" ` - -WebTemplate "68" ` - -SiteScripts "89516c6d-9f4d-4a57-ae79-36b0c95a817b" ` - -Description "Applies standard company theme to site" ` - -IsDefault -``` - -
- -```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteDesign", {info:{Title:"Contoso company theme", Description:"Applies standard company theme to site", SiteScriptIds:["89516c6d-9f4d-4a57-ae79-36b0c95a817b"], WebTemplate:"68", IsDefault: true}}); -``` - -### Which default site designs are updated? - -In the previous example, the **WebTemplate** value of `"68"` refers to the SharePoint Online Communication site template. That template contains the following default site designs: - -- Topic -- Showcase -- Blank - -When you apply a new site design, it updates all three default site designs at the same time. - -The SharePoint Online Team site template contains only one default site design named **Team**. In this case, when you apply a default site design, only the **Team** site design is updated. - -## Restore the default site designs - -To restore a site design to the defaults, remove the site design that you applied. In the previous example, if the site design created had the ID `db752673-18fd-44db-865a-aa3e0b28698e`, you would remove it as shown in the following example. - -```powershell -C:\> Remove-SPOSiteDesign db752673-18fd-44db-865a-aa3e0b28698e -``` - -
- -```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.DeleteSiteDesign", {id:"db752673-18fd-44db-865a-aa3e0b28698e"}); -``` - -> [!NOTE] -> If you're not sure which site design is the default, run the **Get-SPOSiteDesign** cmdlet. It will list all site designs, and indicates which ones are defaults. - -## See also - -- [SharePoint site design and site script overview](site-design-overview.md) +--- +title: Customize default site templates in SharePoint +description: Customize the default site templates for the SharePoint Team site or Communication site template. +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# Customize a default site template + +SharePoint offers several [site templates that are already available](https://support.microsoft.com/office/apply-and-customize-sharepoint-site-templates-39382463-0e45-4d1b-be27-0e96aeec8398). These are the default site templates and they can be modified by using PowerShell or the REST APIs to control the entire site provisioning experience. For example, you can ensure that your company theme is applied to every site that gets created, or you can make sure a logging mechanism always runs regardless of which site template is chosen. + +## Apply a site script to a default site template + +To customize a default site template, apply a new template script using PowerShell **Add-SPOSiteDesign** cmdlet or the **CreateSiteDesign** REST API. Specify the **IsDefault** switch to apply the site template as the default template. + +| Parameter | Value | Site template type | +| :------------------- | :------------------- |:----------------| +| WebTemplate | 64 | Team site template | +| WebTemplate | 1 | Team site (with group creation disabled) | +| WebTemplate | 68 | Communication site template | +| WebTemplate | 69 | Channel site template | + +The following example shows how to use the **IsDefault** switch to apply the Contoso company theme to the default site templates. The site script referenced by ID contains the JSON script to apply the correct theme. + +```powershell +C:\> Add-SPOSiteDesign ` + -Title "Contoso company theme" ` + -WebTemplate "68" ` + -SiteScripts "89516c6d-9f4d-4a57-ae79-36b0c95a817b" ` + -Description "Applies standard company theme to site" ` + -IsDefault +``` + +```javascript +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteDesign", {info:{Title:"Contoso company theme", Description:"Applies standard company theme to site", SiteScriptIds:["89516c6d-9f4d-4a57-ae79-36b0c95a817b"], WebTemplate:"68", IsDefault: true}}); +``` + +### Which default site templates are updated? + +The default site template for a communication site is the **Topic** template. The default for a team site is the **Team collaboration** template. When you apply a new default site template, it updates the Microsoft-provided default templates. + +## Restore the default site templates + +To restore a site template to the defaults, remove the site template script that you applied. In the previous example, if the site template created had the ID `db752673-18fd-44db-865a-aa3e0b28698e`, you would remove it as shown in the following example. + +```powershell +C:\> Remove-SPOSiteDesign db752673-18fd-44db-865a-aa3e0b28698e +``` + +```javascript +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.DeleteSiteDesign", {id:"db752673-18fd-44db-865a-aa3e0b28698e"}); +``` + +> [!NOTE] +> If you're not sure which site template is the default, run the **Get-SPOSiteDesign** cmdlet. It will list all site templates, and indicates which ones are defaults. + +## See also + +- [SharePoint site template and site script overview](site-design-overview.md) +- [Browse and customize Microsoft-provided site templates](https://support.microsoft.com/office/apply-and-customize-sharepoint-site-templates-39382463-0e45-4d1b-be27-0e96aeec8398) diff --git a/docs/declarative-customization/formatting-advanced.md b/docs/declarative-customization/formatting-advanced.md new file mode 100644 index 000000000..5a4d79813 --- /dev/null +++ b/docs/declarative-customization/formatting-advanced.md @@ -0,0 +1,376 @@ +--- +title: Advanced formatting concepts +description: Advanced formatting concepts +ms.date: 07/16/2025 +ms.localizationpriority: high +--- +# Advanced formatting concepts + +You can use some of the following features to make your view and column formatting more information-rich and interactive. + +## Create a button to launch a Flow + +The following screenshot shows a list with a Flow button added to the Action column: + +![screenshot of the sample](../images/sp-columnformatting-flow.png) + +You can use column formatting to create buttons that, when selected, run Flows on the corresponding list item. For flows that are [solution-aware](/power-automate/overview-solution-flows), the Flow Launch Panel will be displayed after choosing the button, and you must select Run Flow to start the flow. For flows that aren't solution-aware, the Flow Launch Panel will be displayed after selecting the button, and the Flow will just run. + +To use the sample below, you must substitute the ID of the Flow you want to run. This ID is contained within the `actionParams` property of the `customRowAction` attribute inside the `button` element. + +To obtain the ID of a flow that is solution-aware: + +1. Select **Flow > See your flows** in the SharePoint list where the Flow is configured. +1. If applicable, [switch to the environment](/power-platform/admin/working-with-environments#switch-the-environment) in which the Flow is hosted. +1. Select the Solutions area. +1. Select the solution in which the Flow was created. +1. Filter for Cloud flows and select the Flow you want to run. +1. Select Export > Get flow identifier. +1. Copy the ID. + +To obtain the ID of a flow that isn't solution-aware: + +1. Switch to the environment in which the Flow is hosted. +1. Select the Flow you want to run. +1. Select Export > Get flow identifier. +1. Copy the ID. + + ```JSON + { + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "button", + "customRowAction": { + "action": "executeFlow", + "actionParams": "{\"id\": \"edf627d9-20f4-45ba-8bc9-4494bf2ff1be\"}" + }, + "attributes": { + "class": "ms-fontColor-themePrimary ms-fontColor-themeDarker--hover" + }, + "style": { + "border": "none", + "background-color": "transparent", + "cursor": "pointer" + }, + "children": [ + { + "elmType": "span", + "attributes": { + "iconName": "Flow" + }, + "style": { + "padding-right": "6px" + } + }, + { + "elmType": "span", + "txtContent": "Send to Manager" + } + ] + } + ``` + +Additionally, you can use `headerText` and `runFlowButtonText` options within the `actionParams` property to customize portions of the Flow panel itself! See the [button elements](./formatting-syntax-reference.md#customrowaction) portion of the Detailed syntax reference for more details. + +## Custom cards on hover + +The following image shows a list with a custom hover added to a List: + +On hover - Metadata on the column "Status" is made available in view formatting: + +![Preview Image 1](../images/HoverImage-1.png) + +On hover - Metadata on the column "Status" is made available in column formatting: + +![Preview Image 2](../images/HoverImage-2.png) + +You can use formatting to define a custom callout that can be commissioned user-defined basis, actions like click or hover. + +This example uses `customCardProps`, `openOnEvent`, `directionalHint`, and `isBeakVisible`: + +```JSON +{ + "elmType": "div", + "style": { + "font-size": "12px" + }, + "txtContent": "[$Status]", + "customCardProps": { + "formatter": { + "elmType": "div", + "txtContent": "Define your formatter options inside the customCardProps/formatter property" + }, + "openOnEvent": "hover", + "directionalHint": "bottomCenter", + "isBeakVisible": true, + "beakStyle" : { + "backgroundColor": "white" + } + } +} +``` + +## Default cards on hover + +Users can now have a profile card or a file hover card on formatters too. Some of the things users can now do: + +- Profile card or File Hover card on any column +- Profile card or Hover card with view formatting + +Hover on a filename with formatting with the default file card: + +![Preview Image 3](../images/HoverImage-3.png) + +Hover on a person column with formatting with the default Profile card: + +![Preview Image 4](../images/HoverImage-4.png) + +This example uses `defaultHoverField`: + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "children": [ + { + "elmType": "img", + "style": { + "width": "32px", + "height": "32px", + "overflow": "hidden", + "border-radius": "50%", + "margin": "2px" + }, + "attributes": { + "src": "=getUserImage([$Editor.email], 's')", + "title": "[$Editor.title]" + } + }, + { + "elmType": "span", + "style": { + "vertical-align": "middle", + "margin-left": "2px" + }, + "txtContent": "[$Editor.title]" + } + ], + "defaultHoverField": "[$Editor]" +} +``` + +## Column formatter reference + +Users can refer to a column's formatter JSON inside another column/view formatter and use it along with other elements to build a custom column visualization. This can be done by using `columnFormatterReference` property. + +The following image shows a list with a Gallery layout referencing the Category column formatter: + +![Gallery layout referring Category column](../images/sp-columnformatting-formatter-reference-1.png) + +![List layout with Category column formatted](../images/sp-columnformatting-formatter-reference-2.png) + +``` JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json", + "height": 127, + "width": 254, + "hideSelection": false, + "formatter": { + "elmType": "div", + "attributes": { + "class": "sp-card-container" + }, + "children": [ + { + "elmType": "button", + "attributes": { + "class": "sp-card-defaultClickButton" + }, + "customRowAction": { + "action": "defaultClick" + } + }, + { + "elmType": "div", + "attributes": { + "class": "ms-bgColor-white sp-css-borderColor-neutralLight sp-card-borderHighlight sp-card-subContainer" + }, + "children": [ + { + "elmType": "div", + "attributes": { + "class": "sp-card-displayColumnContainer" + }, + "children": [ + { + "elmType": "p", + "attributes": { + "class": "ms-fontColor-neutralSecondaryAlt sp-card-label" + }, + "txtContent": "[!Title.DisplayName]" + }, + { + "elmType": "p", + "attributes": { + "title": "[$Title]", + "class": "ms-fontColor-neutralPrimary sp-card-content sp-card-highlightedContent" + }, + "txtContent": "=if ([$Title] == '', '–', [$Title])" + } + ] + }, + { + "elmType": "div", + "attributes": { + "class": "sp-card-lastTextColumnContainer" + }, + "children": [ + { + "elmType": "p", + "attributes": { + "class": "ms-fontColor-neutralSecondaryAlt sp-card-label" + }, + "txtContent": "[!Category.DisplayName]" + }, + { + "elmType": "div", + "attributes": { + "class": "sp-card-content" + }, + "style": { + "height": "32px", + "font-size":"12px" + }, + "children": [ + { + "columnFormatterReference": "[$Category]" + } + ] + } + ] + } + ] + } + ] + } +} +``` + +## Inline Editing + +With inline editing, formatters have the ability to load field editors to edit field data on an item. +Users need to have edit permissions on the list item, and the field type should belong to a set of supported types for this feature to work. + +A special JSON property `inlineEditField` is used with value as the field internal name __`[$FieldName]`__ at the target element in the JSON. + +```json +{ + "elmType": "div", + "inlineEditField": "[$FieldName]", + "txtContent": "[$FieldName]" +} +``` + +![Inline Editing using inlineEditField property](../images/sp-columnformatting-inline-editing.gif) + +This allows the users to edit items in-place, within the view, without navigating away to grid-based editing or to an item edit form. + +### Supported Field Types + +List of supported field types for inline editing: + +- Single line text +- Multiline text (without RTF) +- Number +- DateTime +- Choice and MultiChoice +- User and Multiuser +- Lookup + +### Hover Borders and Customizations + +The inline editing adds a hover border on the elements to indicate that these elements have an associated action. The default border is `neutralSecondary`, and on click, the editor appears with a `themePrimary` border. These border colors can be overridden via setting style on the same element with `inlineEditField` by using some special attributes - `--inline-editor-border-width`, `--inline-editor-border-style`, `--inline-editor-border-radius`, and `--inline-editor-border-color`. + +```json +{ + "elmType": "div", + "inlineEditField": "[$FieldName]", + "txtContent": "[$FieldName]", + "style": { + "--inline-editor-border-color": "transparent transparent red transparent", + "border-color": "gray", + "border-width": "1px", + "border-style": "solid" + } +} +``` + +## Set multiple field values of an Item using customRowAction + +With the new `setValue` and `customRowAction` properties, formatters can render action buttons that modify the item internally without opening editors or forms. `setValue` also allows setting multiple field values of the item at once. + +The below JSON will set the value of `FieldInternalName_1`, `FieldInternalName_2`, and `FieldInternalName_3`with the values provided: + +```json +{ + "elmType": "div", + "txtContent": "[$FieldName]", + "customRowAction":{ + "action": "setValue", + "actionInput": { + "FieldInternalName_1": "FieldValue_1", + "FieldInternalName_2": "FieldValue_2", + "FieldInternalName_3": "=if([$Status] == 'Completed', 'yes', 'no')" + } + } +} +``` + +### Supported Field Types + +- Single line text +- Multiline text (without RTF) +- Number +- DateTime +- Choice and MultiChoice +- User and Multiuser + +### Value Field values in `actionInput`: + +- Text values: + - a valid string like `"Choice 1"` + - value from other columns: `[$ColumnName]` + - an [expression](./formatting-syntax-reference.md#expressions) such as: + + ``` + "if([$column]> 10, "Choice A", "Choice B")" + ``` + + or + + ``` + {operator: "+", operands" : ["Choice", "A"]} + ``` + +- Number: + - a valid number + - value from other columns: `[$ColumnName]` + - an [expression](./formatting-syntax-reference.md#expressions) +- Date values: + - a date string + - `@now` token + - [expressions](./formatting-syntax-reference.md#expressions) that return a date using built-in date functions + - `addDays` and `addMinutes`, two new functions to support [expressions](./formatting-syntax-reference.md#expressions) like seven days from today + - an empty string `""` clears the field value +- Multi-Choice and Multi-Person: + - Multi-value fields are special, as they need an array value to save multiple values. + - `appendTo`, `removeFrom`, and `replace`, three functions that can operate on multivalue fields. + - `appendTo([$MultiChoiceField], 'MyValue')` + - `removeFrom([$MultiUserField], @me)`: removes all occurrences that match the second parameter + - `replace([$MultiChoiceField], 'Choice 1', 'Choice 3')`: replaces all occurrences of the second parameter with the third. +- Person field values: + - user name or email + - An empty string `""` clears the field value + - an [expression](./formatting-syntax-reference.md#expressions) which returns these values + + > [!NOTE] + > A query runs with the string value provided on the people column, and the first person in the returned results is used. diff --git a/docs/declarative-customization/formatting-syntax-reference.md b/docs/declarative-customization/formatting-syntax-reference.md new file mode 100644 index 000000000..bf3f244cf --- /dev/null +++ b/docs/declarative-customization/formatting-syntax-reference.md @@ -0,0 +1,1229 @@ +--- +title: Formatting syntax reference +description: Formatting syntax reference +ms.date: 02/19/2025 +ms.localizationpriority: high +--- + +# Formatting syntax reference + +## elmType + +Specifies the type of element to create. Valid elements include: + +- `div` +- `span` +- `a` +- [`img`](#img-src-security) +- `svg` +- `path` +- `button` +- `p` +- [`filepreview`](#filepreview) + +Any other value will result in an error. + +### filepreview + +Use the special `elmType` `filepreview` with the `src` attribute set to [`@thumbnail.`](#thumbnails) to view thumbnails for files in your document library. + +If the thumbnail loads successfully, a small [brand type icon](https://developer.microsoft.com/fluentui#/styles/web/office-brand-icons) is visible on the bottom left. If the thumbnail fails to load (or if the file type doesn't support thumbnails), a [file type icon](https://developer.microsoft.com/fluentui#/styles/web/file-type-icons) is shown instead. + +```json +"elmType": "filepreview", +"attributes": { + "src": "@thumbnail.medium" +} +``` + +### img src security + +Images from the following domains are allowed: + +- tenant domain, configured multi-geo domains and vanity domains (`company.sharepoint.com`) +- `cdn.office.net`, `akamaihd.net`, `static2.sharepointonline.com` CDNs + +Most other external image sources are blocked by default in custom formatters. To include external images and allow specific domains or CDNs, the domain needs to be added to a site-level setting. For more information see: [Allow or restrict the ability to embed content on SharePoint pages](https://support.microsoft.com/office/allow-or-restrict-the-ability-to-embed-content-on-sharepoint-pages-e7baf83f-09d0-4bd1-9058-4aa483ee137b) + +## txtContent + +An optional property that specifies the text content of the element specified by `elmType`. The value of this property can either be a string (including special strings) or an Expression object. + +## style + +An optional property that specifies style attributes to apply to the element specified by `elmType`. This is an object with name-value pairs that correspond to CSS names and values. The values of each property in the style object can either be a string (including special strings) or an Expression object. The following style attributes are allowed. + +> [!CAUTION] +> Float style prop no longer supported in custom formatter. Users are encouraged to use Gallery View as a more stable alternative. + +```javascript +'background-color' +'fill' +'background-image' +'border' +'border-bottom' +'border-bottom-color' +'border-bottom-style' +'border-bottom-width' +'border-color' +'border-left' +'border-left-color' +'border-left-style' +'border-left-width' +'border-right' +'border-right-color' +'border-right-style' +'border-right-width' +'border-style' +'border-top' +'border-top-color' +'border-top-style' +'border-top-width' +'border-width' +'outline' +'outline-color' +'outline-style' +'outline-width' +'border-bottom-left-radius' +'border-bottom-right-radius' +'border-radius' +'border-top-left-radius' +'border-top-right-radius' +'box-decoration-break' +'box-shadow' +'box-sizing' + +'overflow-x' +'overflow-y' +'overflow-style' +'rotation' +'rotation-point' + +'opacity' +'cursor' + +'height' +'max-height' +'max-width' +'min-height' +'min-width' +'width' + +'flex-grow' +'flex-shrink' +'flex-flow' +'flex-direction' +'flex-wrap' +'flex' +'justify-content' +'align-items' + +'box-align' +'box-direction' +'box-flex' +'box-flex-group' +'box-lines' +'box-ordinal-group' +'box-orient' +'box-pack' + +'font' +'font-family' +'font-size' +'font-style' +'font-variant' +'font-weight' +'font-size-adjust' +'font-stretch' + +'grid-columns' +'grid-rows' + +'margin' +'margin-bottom' +'margin-left' +'margin-right' +'margin-top' + +'column-count' +'column-fill' +'column-gap' +'column-rule' +'column-rule-color' +'column-rule-style' +'column-rule-width' +'column-span' +'column-width' +'columns' + +'padding' +'padding-bottom' +'padding-left' +'padding-right' +'padding-top' + +'bottom' +'clear' +'clip' +'display' +'float' (Deprecated) +'left' +'overflow' +'position' +'right' +'top' +'visibility' +'z-index' + +'border-collapse' +'border-spacing' +'caption-side' +'empty-cells' +'table-layout' + +'color' +'direction' +'letter-spacing' +'line-height' +'text-align' +'text-decoration' +'text-indent' +'text-transform' +'unicode-bidi' +'vertical-align' +'white-space' +'word-spacing' +'hanging-punctuation' +'punctuation-trim' +'text-align-last' +'text-justify' +'text-outline' +'text-overflow' +'text-shadow' +'text-wrap' +'word-break' +'word-wrap' + +'stroke' +'fill-opacity' + +'--inline-editor-border-width' +'--inline-editor-border-style' +'--inline-editor-border-radius' +'--inline-editor-border-color' + +'-webkit-line-clamp' + +'object-fit' +'transform' // Only translate(arg) and translate(arg, arg) are currently supported +``` + +The following example shows the value of a style object. In this example, two style properties (`padding` and `background-color`) will be applied. The `padding` value is a hard-coded string value. The `background-color` value is an Expression that is evaluated to either red (`#ff0000`) or green (`#00ff00`) depending on whether the value of the current field (specified by `@currentField`) is less than 40. For more information, see the [Expression object section](#expressions). + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "style": { + "padding": "4px", + "background-color": { + "operator": "?", + "operands": [ + { + "operator": "<", + "operands": [ + "@currentField", + 40 + ] + }, + "#ff0000", + "#00ff00" + ] + } + } +} +``` + +Here's the same sample from above, using the Excel-style expression syntax: + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "style": { + "padding": "4px", + "background-color": "=if(@currentField < 40, '#ff0000', '#00ff00')" + } +} +``` + +## attributes + +The `attributes` optional property specifies more attributes to add to the element specified by `elmType`. This is an object with name-value pairs. Attribute names must be one of the following: + +- href +- rel +- src +- class +- target +- title +- role +- iconName +- d +- aria +- data-interception +- viewBox +- preserveAspectRatio +- draggable + +Any other attribute name will result in an error. Attribute values can either be Expression objects or strings. The following example adds two attributes (`target` and `href`) to the element specified by `elmType`. The `target` attribute is hard-coded to a string. The `href` attribute is an expression that will be evaluated at runtime to `http://finance.yahoo.com/quote/` + the value of the current field (`@currentField`). + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "target": "_blank", + "href": "='http://finance.yahoo.com/quote/' + @currentField" +} +``` + +## children + +The `children` optional property specifies child elements of the element specified by `elmType`. The value is specified as an array of `elm` objects. There can be an arbitrary level of nesting. If an element has the `txtContent` property, the child properties are ignored. + +## debugMode + +The `debugMode` optional property is meant for debugging. It outputs error messages and logs warnings to the console. + +## forEach + +The `forEach` optional property allows an element to duplicate itself for each member of a specific multi-value field or an array. The value of `"forEach"` property should be in the format of either `"iteratorName in @currentField"` or `"iteratorName in [$FieldName]"` or `"iteratorName in Expression-Returning-An-Array"`. + +`iteratorName` represents the name of the iterator variable that is used to represent the current member of the multi-value field. The name of the iterator can be any combination of alphanumeric characters and an underscore (`_`) that doesn't start with a digit. + +The field used in the loop must be in a supported field type with multi-value options enabled: Person, Lookup, and Choice. An expression returning an array can also be used. + +In the element with `forEach` or its children elements, the iterator variable can be referred to as if it's a new field. The index of the iterator can be accessed with `loopIndex` operator. + +`forEach` can't be applied to the root element, and will render no element if there's no value in the field. + +See [Formatting multi-value fields](column-formatting.md#formatting-multi-value-fields) for examples. + +## customRowAction + +`button` elements can be used to launch a specific action on the parent item. Every `button` element has a required property, `customRowAction`, that specifies an `action` that's taken when the button is selected. This action must be one of the following values: + +- **defaultClick**: buttons with this action will do the same thing as clicking the list item in an uncustomized view. The following example demonstrates a button that, when selected, simulates a selection on the item, which results in opening the list item. Adding this example button to a document library simulates a selection on the file or folder, which results in the file or folder being opened. + + ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "button", + "txtContent": "Open this item", + "customRowAction": { + "action": "defaultClick" + } + } + ``` + +- **share**: Selecting the button will open the sharing dialog. The following is an example of this type of button: + + ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "button", + "txtContent": "Share this item", + "customRowAction": { + "action": "share" + } + } + ``` + +- **delete**: Selecting the button will open the delete confirmation dialog. +- **editProps**: Selecting the button will open the item properties page in edit mode. +- **openContextMenu**: Selecting the button will open the item's default context menu. +- **setValue**: Selecting the element will update the item with the field values provided. + + ```json + { + "elmType": "div", + "txtContent": "[$FieldName]", + "customRowAction":{ + "action": "setValue", + "actionInput": { + "FieldInternalName_1": "FieldValue_1", + "FieldInternalName_2": "FieldValue_2" + } + } + } + ``` + +- **executeFlow**: Selecting the button will launch the specified Flow, specified by ID inside the `actionParams` attribute. For an example of this, see [Create a button to launch a Flow](./formatting-advanced.md#create-a-button-to-launch-a-flow). The following example demonstrates this type of button: + + ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json", + "elmType": "button", + "txtContent": "It's Flow Time!", + "customRowAction": { + "action": "executeFlow", + "actionParams": "{\"id\":\"f7ecec0b-15c5-419f-8211-302a5d4e94f1\", \"headerText\":\"It's Flow Time!\",\"runFlowButtonText\":\"Do it\"}" + } + } + ``` + + The `actionParams` attribute can have the following options when using the `executeFlow` action: + + - **id**: ID of the Flow to launch _(required)_ + - **headerText**: Sets the text at the top of the flow panel _(optional)_ + - **runFlowButtonText**: Sets the text of the primary button in the flow panel _(optional)_ + +- **embed**: Clicking on the button will open a callout with content embedded in it. The content will be determined by the URL provided in the `src` attribute in `actionInput`. You can also control the `height` and `width` of the callout using the `actionInput`. + + > [!NOTE] + > + > - The `src` needs to be just the `url` part of an embeddable code generated by an app (usually found in the `src` attribute of the `iframe` element). + > - This action is only available in the newer version of the Microsoft Lists App. + + For more information about allowing or restricting domains, see [Allow or restrict the ability to embed content on SharePoint Lists using custom formatters](https://go.microsoft.com/fwlink/p/?linkid=2258033). + + + ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "button", + "customRowAction": { + "action": "embed", + "actionInput": { + "src": "https://www.relecloud.com/embed/ll00hWQMJxQ", + "height": "350", + "width": "700" + } + }, + "txtContent": "Click here to open recipe video 👩‍🍳" + } + ``` + + The `actionInput` attribute can have the following options when using the `embed` action: + + - **src**: The URL of the content you want to embed. _(required)_ + - **height**: The height of the callout within which the embedded content will render. The default value is 300. _(optional)_ + - **width**: The width of the callout within which the embedded content will render. The default value is 300. _(optional)_ + +## customCardProps + +Add a custom card to the element, that shows up on hover or `click` event. The following customizations are available: + +- `"formatter"`: JSON object that defines formatting for custom cards. +- `"openOnEvent"`: Event on which the customCard should open. + - Valid values: `click`, `hover` +- `"directionalHint"`: Specify the direction relative to the target in which the custom card will be positioned. This is the preferred location but it isn't guaranteed depending on space. + - Valid values: `bottomAutoEdge`, `bottomCenter`, `bottomLeftEdge`, `bottomRightEdge`, `leftBottomEdge`, `leftCenter`, `leftTopEdge`, `rightBottomEdge`, `rightCenter`, `rightTopEdge`, `topAutoEdge`, `topCenter`, `topLeftEdge`, `topRightEdge` +- `"isBeakVisible"`: Specify if the beak is to be shown or not. +- `"beakStyle"`: Specifies the style object for the custom card's beak. + +## defaultHoverField + +Adds the profile card for the people fields or file hovercard for files in the document library. + +- `"defaultHoverField": "[$Editor]"` adds a profile card for the editor field +- `"defaultHoverField": "[$FileLeafRef]"` adds a file hover card in documentLibrary + +## columnFormatterReference + +This will be replaced with the referenced column's formatter JSON. Multi-level reference isn't supported. + +References for multi-choice column formatter templates and column formatters not based on templates are not supported. + +```json +{ + "columnFormatterReference": "[$FieldName]" +} +``` + +## inlineEditField + +Adds the field editor for the referenced column. + +```json +{ + "elmType": "div", + "inlineEditField": "[$FieldName]", + "txtContent": "[$FieldName]" +} +``` + +## filePreviewProps + +The `filePreviewProps` is an optional property that allows overriding the default styles of file type icon and brand type icon in `filepreview`.elmType. + +The `fileTypeIconClass` and `brandTypeIconClass` can be used to provide CSS class names to the file type icon and the brand type icon elements respectively. + +The `fileTypeIconStyle` and `brandTypeIconStyle` can be used to provide [styles](#style) to the file type icon and the brand type icon respectively. These styles will take precedence over the same styles coming from the CSS classes provided by the above two properties. + +```json +"elmType": "filepreview", +"attributes": { + "src": "@thumbnail.medium", + }, +"filePreviewProps": { + "fileTypeIconClass": "sp-css-borderColor-neutralLight", + "fileTypeIconStyle": { + "width": "100px" + }, + "brandTypeIconClass": "sp-css-borderColor-neutralLight", + "brandTypeIconStyle": { + "width": "68px" + } +} +``` + +## Expressions + +Values for `txtContent`, style properties, and attribute properties can be expressed as expressions so that they're evaluated at runtime based on the context of the current field (or row). Expression objects can be nested to contain other Expression objects. + +Expressions can be written using Excel-style expressions in SharePoint Online and SharePoint Server Subscription Edition starting with the 22H2 feature update, or by using Abstract Syntax Tree expressions in SharePoint Online, SharePoint Server Subscription Edition, and SharePoint Server 2019. + +All fields in `ViewFields` can be referred to in expressions, even if it's marked `Explicit`. + +### Excel-style expressions + +All Excel-style expressions begin with an equal (`=`) sign. This style of expression is only available in SharePoint Online and SharePoint Server Subscription Edition starting with the 22H2 feature update. This style of expression isn't available in SharePoint Server 2019 or SharePoint Server Subscription Edition prior to the 22H2 feature update. + +This simple conditional expression evaluates to `none` if `@me` isn't equal to `[$Author.email]`, and evaluates to `''` otherwise: + +```json +=if(@me != [$Author.email], 'none', '') +``` + +More complex if/else statements can be written like the following: + +```json +=if([$Sentiment] <= 0.3, 'sp-field-severity--blocked', if([$Sentiment] < 0.9,'sp-field-severity--warning','sp-field-severity--good')) +``` + +Non-conditional operators that take one or two operands can be written like the following: + +```json +=[$foo] * -7 +``` + +```json +=sin(@currentField) +``` + +```json +=toString(60 + (sin(6.2831853 * @currentField) * 60)) +``` + +### Abstract Syntax Tree expressions + +The following example contains an Expression object that performs the expression: + +`(@currentField > 40) ? '100%' : (((@currentField * 2.5).toString() + '%')` + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "operator": "?", + "operands": [ + { + "operator": ">", + "operands": [ + "@currentField", + "40" + ] + }, + "100%", + { + "operator": "+", + "operands": [ + { + "operator": "toString()", + "operands": [ + { + "operator": "*", + "operands": [ + "@currentField", + 2.5 + ] + } + ] + }, + "%" + ] + } + ] +} +``` + +## Operators + +Operators specify the type of operation to perform. Valid operator values include: + +- `+` +- `-` +- `/` +- `*` +- `<` +- `>` +- `%` +- `==` +- `!=` +- `<=` +- `>=` +- `||` +- `&&` +- `toString()` +- `Number()` +- `Date()` +- `cos` +- `sin` +- `?` +- `:` +- `toLocaleString()` +- `toLocaleDateString()` +- `toLocaleTimeString()` +- `indexOf` +- `toLowerCase` +- `join` +- `length` +- `abs` +- `loopIndex` +- `floor` +- `ceiling` +- `pow` +- `substring` +- `getDate` +- `getMonth` +- `getYear` +- `toUpperCase` +- `lastIndexOf` +- `startsWith` +- `endsWith` +- `replace` +- `replaceAll` +- `padStart` +- `padEnd` +- `getThumbnailImage` +- `getUserImage` +- `addDays` +- `addMinutes` +- `appendTo` +- `removeFrom` +- `split` + +**Binary arithmetic operators** - The standard arithmetic binary operators that expect two operands include are: + +- `+` +- `-` +- `/` +- `*` +- `<` +- `>` +- `%` +- `==` +- `!=` +- `<=` +- `>=` + +**Unary operators** - The standard unary operators that expect only one operand are: + +- `toString()`: returns a string representing the object + - `"txtContent": "=toString(45)"` results in _"45"_ +- `Number()`: returns the numeric value, if the operand isn't a number, NaN is returned + - `"txtContent": "=Number('365')"` results in _365_ + - `"txtContent": "=Number('Wowee')"` results in _NaN_ + - `"txtContent": "=Number(Date('12/26/1981'))"` results in _378190800000_ +- `Date()`: returns a datetime object from the parameter (converts strings or numbers to dates, sensitive to locale) + - `"txtContent": "=Date('12/26/1981')"` results in _12/26/1981, 12:00:00 AM_ +- `cos`: returns the cosine of the specified angle that should be specified in radians + - `"txtContent": "=cos(5)"` results in _0.28366218546322625_ +- `sin`: returns the sine of a number + - `"txtContent": "=sin(90)"` results in _0.8939966636005579_ +- `toDateString()`: returns a date in a short-friendly format + - `"txtContent": "=toDateString(@now)"` result doesn't vary based on the user's locale and it will look like _"Wed Aug 03 2022"_ +- `toLocaleString()`: returns a language-sensitive representation of a date + - `"txtContent":"=toLocaleString(@now)"` results vary based on the user's locale, but en-us looks like _"2/5/2019, 1:22:24 PM"_ +- `toLocaleDateString()`: returns a language-sensitive representation of just the date portion of a date + - `"txtContent":"=toLocaleDateString(@now)"` results vary based on the user's locale, but en-us looks like _"2/5/2019"_ +- `toLocaleTimeString()`: returns a language-sensitive representation of just the time portion of a date + - `"txtContent":"=toLocaleTimeString(@now)"` results vary based on the user's locale, but en-us looks like _"1:22:24 PM"_ +- `toLowerCase`: returns the value converted to lower case (only works on strings) - _Only available in SharePoint Online_ + - `"txtContent":"=toLowerCase('DogFood')"` results in _"dogfood"_ +- `abs`: returns the absolute value for a given number - _Only available in SharePoint Online_ + - `"txtContent":"=abs(-45)"` results in _45_ +- `length`: returns the number of items in an array (multi-select person or choice field), for all other value types it returns 1 when true and 0 when false. It does NOT provide the length of a string value (*see the `indexOf` workaround explained later on for such operation*). - _Only available in SharePoint Online_ + - `"txtContent":"=length(@currentField)"` might result in _2_ if there are two selected values + - `"txtContent":"=length('Some Text')"` results in _1_ + - `"txtContent":"=length('')"` results in _0_ + - `"txtContent":"=length(45)"` results in _1_ + - `"txtContent":"=length(0)"` results in _0_ +- `floor`: returns the largest integer less than or equal to a given number. - _Only available in SharePoint Online_ + - `"txtContent":"=floor(45.5)"` results in _45_ +- `ceiling`: rounds the given number up to the next largest whole number or integer. - _Only available in SharePoint Online_ + - `"txtContent":"=ceiling(45.5)"` results in _46_ +- `getDate`: returns the day of the month of the given date. - _Only available in SharePoint Online_ + - `"txtContent":"=getDate(Date('12/26/1981'))"` results in _26_ +- `getMonth`: returns the month in the specified date according to local time, as a zero-based value (where zero indicates the first month of the year). - _Only available in SharePoint Online_ + - `"txtContent":"=getMonth(Date('12/26/1981'))"` results in _11_ +- `getYear`: returns the year of the given date. - _Only available in SharePoint Online_ + - `"txtContent":"=getYear(Date('12/26/1981'))"` results in _1981_ +- `toUpperCase`: returns the value converted to upper case (only works on strings) - _Only available in SharePoint Online_ + - `"txtContent":"=toUpperCase('DogFood')"` results in _"DOGFOOD"_ + +**Binary operators** - The following are operators that expect two operands: + +- `indexOf`: takes two operands. The first is the text (or array) you would like to search within, the second is the text you would like to search for. Returns the index value of the first occurrence of the search term within the string (or array). Indexes start at 0. If the search term isn't found within the text (or array), -1 is returned. This operator is case-sensitive. - _Only available in SharePoint Online_ + - `"txtContent": "=indexOf('DogFood', 'Dog')"` results in _0_ + - `"txtContent": "=indexOf('DogFood', 'F')"` results in _3_ + - `"txtContent": "=indexOf('DogFood', 'Cat')"` results in _-1_ + - `"txtContent": "=indexOf('DogFood', 'f')"` results in _-1_ +- `join`: takes two operands. The first is an array (multi-select person or choice field) and the second is the separating string. Returns a string concatenation of the array values separated by the separating string. - _Only available in SharePoint Online_ + - `"txtContent": "=join(@currentField, ', ')"` might result in _"Apple, Orange, Cherry"_ (depending on the selected values) + - `"txtContent": "=join(@currentField.title, '|')"` might result in _"Megan Bowen|Alex Wilber"_ (depending on the selected persons) +- `pow`: returns the base to the exponent power. - _Only available in SharePoint Online_ + - `"txtContent":"=pow(2,3)"` results in _8_ +- `lastIndexOf`: returns the position of the last occurrence of a specified value in a string (or array) + - `"txtContent": "=lastIndexOf('DogFood DogFood', 'Dog')"` results in _8_ + - `"txtContent": "=lastIndexOf('DogFood DogFood', 'F')"` results in _11_ + - `"txtContent": "=lastIndexOf('DogFood DogFood', 'Cat')"` results in _-1_ + - `"txtContent": "=lastIndexOf('DogFood DogFood', 'f')"` results in _-1_ +- `startsWith`: determines whether a string begins with the characters of a specified string + - `"txtContent":"=startsWith('DogFood', 'Dog')"` results in _true_ + - `"txtContent":"=startsWith('DogFood', 'Food')"` results in _false_ +- `endsWith`: determines whether a string ends with the characters of a specified string + - `"txtContent":"=endsWith('DogFood', 'Dog')"` results in _false_ + - `"txtContent":"=endsWith('DogFood', 'Food')"` results in _true_ +- `getUserImage`: returns a URL pointing to user's profile image for a given email and preferred size + - `"src":"=getUserImage('kaylat@contoso.com', 'small')"` returns a URL pointing to user's profile picture in small resolution + - `"src":"=getUserImage('kaylat@contoso.com', 's')"` returns a URL pointing to user's profile picture in small resolution + - `"src":"=getUserImage('kaylat@contoso.com', 'medium')"` returns a URL pointing to user's profile picture in medium resolution + - `"src":"=getUserImage('kaylat@contoso.com', 'm')"` returns a URL pointing to user's profile picture in medium resolution + - `"src":"=getUserImage('kaylat@contoso.com', 'large')"` returns a URL pointing to user's profile picture in large resolution + - `"src":"=getUserImage('kaylat@contoso.com', 'l')"` returns a URL pointing to user's profile picture in large resolution +- `appendTo`: returns an array with the given entry appended to the given array + - `"txtContent": "=appendTo(@currentField, 'Choice 4')"` returns an array with 'Choice 4' added to the @currentField array + - `"txtContent": "=appendTo(@currentField, 'kaylat@contoso.com')"` returns an array with 'kaylat@contoso.com' added to the @currentField array +- `removeFrom`: returns an array with the given entry removed from the given array, if present + - `"txtContent": "=removeFrom(@currentField, 'Choice 4')"` returns an array with 'Choice 4' removed from the @currentField array + - `"txtContent": "=removeFrom(@currentField, 'kaylat@contoso.com')"` returns an array with 'kaylat@contoso.com' removed from the @currentField array +- `split`: divides the given string into an ordered list of substrings by searching for the given pattern, and returns an array of these substrings + - `"txtContent": "=split('Hello World', ' ')"` returns an array with two strings - 'Hello' and 'World' +- `addDays`: returns a datetime object with days added (or deducted) from the given datetime value + - `"txtContent": "=addDays(Date('11/14/2021'), 3)"` returns a 11/17/2021, 12:00:00 AM + - `"txtContent": "=addDays(Date('11/14/2021'), -1)"` returns a 11/13/2021, 12:00:00 AM +- `addMinutes`: returns a datetime object with minutes added (or deducted) from the given datetime value + - `"txtContent": "=addMinutes(Date('11/14/2021'), 3)"` returns a 11/14/2021, 12:03:00 AM + - `"txtContent": "=addMinutes(Date('11/14/2021'), -1)"` returns a 11/13/2021, 11:59:00 AM + +**Ternary operators** - The following are operators that expect three operands: + +- `substring`: returns the part of the string between the start and end indices. - _Only available in SharePoint Online_ + - `"txtContent":"=substring('DogFood', 3, 4)"` results in _F_ + - `"txtContent":"=substring('DogFood', 4, 3)"` results in _F_ + - `"txtContent":"=substring('DogFood', 3, 6)"` results in _Foo_ + - `"txtContent":"=substring('DogFood', 6, 3)"` results in _Foo_ + + The substring() method returns the part of the string between the start and end indexes or to the end of the string. + +- `replace`: searches a string (or array) for a specified value and returns a new string (or array) where the specified value is replaced. For strings, only the first instance of the value will be replaced. + - `"txtContent":"=replace('Hello world', 'world', 'everyone')"` results in _Hello everyone_ + - `"txtContent":"=replace([$MultiChoiceField], 'Choice 1', 'Choice 2')"` returns an array replacing Choice 1 with Choice 2 + - `"txtContent":"=replace([$MultiUserField], @me, 'kaylat@contoso.com')"` returns an array replacing @me with 'kaylat@contoso.com' +- `replaceAll`: searches a string for a specified value and returns a new string (or array) where the specified value is replaced. For strings, all instances of the value will be replaced. + - `"txtContent":"=replaceAll('H-e-l-l-o W-o-r-l-d', '-', '')"` results in _Hello World_ +- `padStart`: pads the current string with another string until the resulting string reaches the given length. The padding is applied from the start of the current string. + - `"txtContent":"=padStart('DogFood', 10, 'A')"` results in _AAADogFood_ + - `"txtContent":"=padStart('DogFood', 10, 'AB')"` results in _ABADogFood_ + - `"txtContent":"=padStart('DogFood', 5, 'A')"` results in _DogFood_ +- `padEnd`: pads the current string with a given string until the resulting string reaches the given length. The padding is applied from the end of the current string. + - `"txtContent":"=padEnd('DogFood', 10, 'A')"` results in _DogFoodAAA_ + - `"txtContent":"=padEnd('DogFood', 10, 'AB')"` results in _DogFoodABA_ + - `"txtContent":"=padEnd('DogFood', 5, 'A')"` results in _DogFood_ +- `getThumbnailImage`: returns a URL pointing to an image for a given image field and preferred size. + - `"src":"=getThumbnailImage([$ImageField], 400, 200)"` results in a URL pointing to an image for a given image field with 400 width and 200 height + +**Conditional operator** - The conditional operator is: + +- `?`: Conditional operations written in Abstract Tree Syntax use `?` as the operator. This is to achieve an expression equivalent to `a ? b : c`, where if the expression `a` evaluates to true, then the result is `b`, else the result is `c`. For Excel-style expressions, you write these with an `if` statement. Regardless, there are three operands. The first is the condition to evaluate. The second is the result when the condition is true. The third is the result when the condition is false. + - `"txtContent":"=if(4 < 5, 'yes', 'no')"` results in _"yes"_ + - `"txtContent":"=if(4 > 5, 'yes', 'no')"` results in _"no"_ + +**Multi-value field-related operators** - The following operators are only used in a context with multi-value fields of type Person, Lookup, or Choice. + +- `length` +- `join` +- `loopIndex` + +`length`, when provided with a field name, returns the number of members in a multi-valued field. When a single-value field is provided, `length` will return 1 when there's a value in that field. + +`join` concatenates values in a multi-value field with a specified separator. The first operand shall point to a value in a multi-value field, for example `"@currentField.lookupValue"`, `"[$AssignedTo.title]"`. The second operand shall be a string literal that is the separator that joins the values together. + +`loopIndex`, when provided with the name of the iterator variable, returns the current index (starting from 0) of the iterator. The name of the iterator must be provided as a string literal. `loopIndex` would only work within the element with respective `forEach` enabled or its children elements. + +For examples, see [Formatting multi-value fields](column-formatting.md#formatting-multi-value-fields). + +**String-related operators** - Some of the previously detailed operators can be used when working with string values: + +- `+` +- `indexOf` (*for string length workaround*) + +`+` can be used when there's a need to concatenate strings, for instance: + +```txt +"txtContent": "=[$column1] + ' ' + [$column2] + 'some other text'" +``` + +`indexOf` Since the operator `length` doesn't work for string value types (it will return 1 or 0), `indexOf` can serve us as a nice workaround to get the length of a string, for instance: `indexOf([$column1] + '^', '^')`. We'll use `'^'` or any other character to use to find out the end of the string. + +## Operands + +Specifies the parameters, or operands for an expression. This is an array of Expression objects or base values. + +## Special string values + +The values for `txtContent`, styles, and attributes can be either strings or Expression objects. A few special string patterns for retrieving values from the fields in the list and the user's context are supported. + +### "@currentField" + +Will evaluate the value of the current field. + +Some field types are represented as objects. To output a value from an object, refer to a particular property inside that object. For example, if the current field is a person/group field, specify `@currentField.title` to retrieve the person's name, which is normally displayed in list views. The following are the field types that are represented as objects with a list of their properties. + +> [!NOTE] +> The `@currentField.title` returns a person's name by default. However, if the person field's Show Field has been adjusted, it may change the value of the `title` property. For example, a person field with the Show Field configured as Department will have the person's department for the `title` property. + +**People fields** + +The people field object has the following properties (with example values): + +```json +{ + "id": "122", + "title": "Kalya Tucker", + "email": "kaylat@contoso.com", + "sip": "kaylat@contoso.com", + "picture": "https://contoso.sharepoint.com/kaylat_contoso_com_MThumb.jpg?t=63576928822", + "department":"Human Resources", + "jobTitle":"HR Manager" +} +``` + +People field can have profile hover cards along with formatting: + +```json +{ + "elmType": "div", + "txtContent": "[$Editor.title]", + "defaultHoverField": "[$Editor]" +} +``` + +**Date/Time fields** + +The value of Date/Time fields can be retrieved a few different ways, depending on the date format you'd like to display. The following methods for converting date values to specific formats are supported: + +- `toLocaleString()` - Displays a date type fully expanded with date and time. +- `toLocaleDateString()` - Displays a date type with just the date. +- `toLocaleTimeString()` - Displays a date type with just the time. + +For example, the following JSON will display the current field (assuming it's a date field) as a date and time string. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "txtContent": { + "operator": "toLocaleString()", + "operands" : ["@currentField"] + } +} +``` + +Here's the same sample from above, using the Excel-style expression syntax: + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "txtContent": "=toLocaleString(@currentField)" +} +``` + +**Location fields** + +The location field object has the following properties (with example values): + +```json +{ + "Address": { + "City": "Knoxville", + "CountryOrRegion": "United States", + "State": "TN", + "Street": "963 Worlds Fair Park Dr" + }, + "Coordinates": { + "Latitude": "35.961673736572266", + "Longitude": "-83.92420959472656" + }, + "DisplayName": "World's Fair Park", + "LocationUri": "https://www.bingapis.com/api/v6/localentities/8346bf26-6da4-104c-6ba5-2334b83f6ac8?setLang=en" +} +``` + +The following example shows how a location field might be used on a current field. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/column-formatting.schema.json", + "elmType": "div", + "style": { + "display": "block" + }, + "children": [ + { + "elmType": "a", + "txtContent": "@currentField.DisplayName", + "attributes": { + "href": "='https://www.bing.com/maps?cp=' + @currentField.Coordinates.Latitude + '~' + @currentField.Coordinates.Longitude + '&lvl=17&sV=2'", + "target": "_blank", + "title": "=@currentField.Coordinates.Latitude + ', ' + @currentField.Coordinates.Longitude" + }, + "style": { + "display": "block" + } + }, + { + "elmType": "div", + "txtContent": "@currentField.Address.Street" + }, + { + "elmType": "div", + "txtContent": "=@currentField.Address.City + ', ' + @currentField.Address.State" + }, + { + "elmType": "div", + "txtContent": "@currentField.Address.CountryOrRegion" + } + ] +} +``` + +**Lookup fields** + +The lookup field object has the following properties (with example values): + +```json +{ + "lookupId": "100", + "lookupValue": "North America", +} +``` + +The following example shows how a lookup field might be used on a current field. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "a", + "txtContent": "@currentField.lookupValue", + "attributes": { + "href": { + "operator": "+", + "operands": [ + "https://contoso.sharepoint.com/teams/Discovery/Lists/Regions/DispForm.aspx?ID=", + "@currentField.lookupId" + ] + }, + "target": "_blank" + } +} +``` + +**Hyperlink fields** + +The hyperlink field object has the following property (with example value): + +```json +{ + "desc": "SharePoint Patterns and Practices", +} +``` + +To reference the URL value, use `@currentField`. + +The following example shows how a hyperlink field might be used on a current field. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "a", + "txtContent": "@currentField.desc", + "attributes": { + "href": "@currentField", + "target": "_blank" + } +} +``` + +**Image fields** + +The image field object has the following `fileName` property: + +```json +{ + "fileName": "image.png", +} +``` +> [!NOTE] +> As of July 2024, just the `fileName` property has a value. + + +The following example shows how an image field can be used on a current field. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "img", + "attributes": { + "src": "=getThumbnailImage(@currentField, 400, 300)", + "alt": "@currentField.fileName" + }, + "style": { + "width": "100%", + "max-width": "100%" + } +} +``` + +**Approval Status fields** + +The Approval Status field object has the following property (with example value): + +```json +{ + "displayValue": "Approved", + "numeric": 0 +} +``` + +`displayValue` is a localized string of the approval status. + +`@currentField` or `[$__ModerationStatus]` will also internally map to the following internal numeric value: + +- 0: Approved +- 1: Denied +- 2: Pending +- 3: Draft +- 4: Scheduled + +`[$_ModerationStatus]` field supports comparisons to both strings and the numeric value. The numeric comparisons work across locales and languages which will be the recommended way for this field. + +The following expressions evaluate to the output on the right, for when the status is `Pending`: + +```javascript +// reading field value +"[$_ModerationStatus]" => "Pending" + +// obtaining the internal numeric value: +"=Number([$_ModerationStatus])" => 2 +"=[$_ModerationStatus.numeric]" => 2 + +// addition results in string concatenation: +"='status:'+[$_ModerationStatus]" => 'status:Pending' + +// numeric comparisons +"=([$_ModerationStatus] == 2)" => true +"=([$_ModerationStatus] != 1)" => true + +// other comparators are rarely useful, for cases where you want might want to exclude Draft & Scheduled +"=([$_ModerationStatus] < 3)" => true + +// localized string comparison, works only with one locale (en-us here) +"=if([$_ModerationStatus]=='Pending','This Works too!', 'Nope!')" => 'This Works too!' +``` + +The following example shows how an approval status field might be used on a current field: + +```json +{ + "elmType": "div", + "txtContent": "@currentField.displayValue", + "style": { + "color": "=if(@currentField == 2, 'red', '')" + } +} +``` + +### "[$FieldName]" + +The column is formatted within the context of the entire row. You can use this context to reference the values of other fields within the same row by specifying the **internal name** of the field surrounded by square brackets and preceded by a dollar sign: `[$InternalName]`. For example, to get the value of a field with an internal name of "MarchSales", use `[$MarchSales]`. + +> [!NOTE] +> Reference to other fields will work only if they are included in the same view. + +If the value of a field is an object, the object's properties can be accessed. For example, to access the "Title" property of a person field named "SalesLead", use "[$SalesLead.title]". + +### "[!FieldName]" + +In column and view formatting, you can refer to any field's metadata by specifying the **internal name** of the field surrounded by square brackets and preceded by an exclamation mark: `[!InternalName]`. + +Currently field's display name is available in this metadata, and can be accessed using `DisplayName` property: `[!SalesLead.DisplayName]`. + +### "@currentWeb" + +This will evaluate the absolute URL for the site. This is equivalent to the `webAbsoluteUrl` value within the page context. This value is only available in SharePoint Online. + +### "@me" + +This will evaluate the email address of the currently logged-in user. + +This field can be used to display the current user's email address, but more likely it will be used within conditions. The following is an example of setting the color for a person field to red when it's equal to the currently logged-in user and blue otherwise: + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "txtContent": "@currentField.title", + "style": { + "color": { + "operator": "?", + "operands": [ + { + "operator": "==", + "operands": [ + "@me", + "@currentField.email" + ] + }, + "red", + "blue" + ] + } + } +} +``` + +Here's the same sample from above, using the Excel-style expression syntax: + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "div", + "txtContent": "@currentField.title", + "style": { + "color": "=if(@me == @currentField.email, 'red', 'blue')" + } +} +``` + +### "@now" + +This will evaluate the current date and time. + +### "@rowIndex" + +This will evaluate the rendered index of a row within a view. This value is based on render position and will remain consistent based on position even as views are sorted and filtered. Indexes start at 0. This value is only available in SharePoint Online. + +Here's an example of using the value within a view format to apply alternating styles to rows: + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", + "additionalRowClass": "=if(@rowIndex % 2 == 0,'ms-bgColor-themeLighter ms-bgColor-themeLight--hover','')" +} +``` + +### "@window.innerHeight" + +This will be evaluated to a number equal to the height of the browser window (in pixels) when the list is rendered. + +### "@window.innerWidth" + +This will evaluate to a number equal to the width of the browser window (in pixels) when the list was rendered. + +### Thumbnails + +In a document library, there's a series of tokens that can be used to retrieve the URL to the thumbnail of a file, including: + +- `@thumbnail.small`, `@thumbnail.medium`, and `@thumbnail.large` evaluate the thumbnail URL in three predefined sizes. +- `@thumbnail.` evaluates the URL to the largest thumbnail that isn't larger than the bounding size in both width and height. For example, `@thumbnail.150` evaluates to the URL to a thumbnail not larger than 150×150 pixels. +- `@thumbnail.x` evaluates the URL to the largest thumbnail that isn't larger than the bounding width and bounding height. For example, `@thumbnail.100x200` evaluates to the URL to a thumbnail not wider than 100 pixels and not higher than 200 pixels. + +These tokens will yield no value on non-file items including folders. + +> [!NOTE] +> The aspect ratio of the thumbnail generated is the same as how the file looks, changing the bounding sizes will not affect the aspect ratio of the thumbnail. + +> [!TIP] +> Thumbnails are only available for a list of supported file formats. It means that sometimes the URL generated is not accessible due to lack of support on certain formats. However, if a valid thumbnail token is set as the _only_ `src` attribute of an `img` tag, we will take care of it and hide the image when it is not available. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json", + "elmType": "img", + "attributes": { + "src": "@thumbnail.200x150", + "alt": "='Thumbnail of file ' + [$FileLeafRef]" + }, + "style": { + "width": "100%", + "max-width": "100%" + } +} +``` + +Default file hover card using FileLeafRef + +```json +{ + "elmType": "img", + "style": { + "width": "100%", + "height": "100%", + "display": "=if([$File_x0020_Type] == '', 'none', '')" + }, + "attributes": { + "src": "@thumbnail.300x300" + }, + "defaultHoverField": "[$FileLeafRef]" +} +``` + +### displayValue + +The following column types can use `displayValue` property to get the default-rendered value, based on the column setting: + +- Date/Time +- Number +- Yes/No +- Currency +- Approval Status + +```json +{ + "elmType": "div", + "txtContent": "@currentField.displayValue" +} +``` + +This also works with field name: + +```json +{ + "elmType": "div", + "txtContent": "[$FieldName.displayValue]" +} +``` + +### "@isSelected" + +This will evaluate to `true` for the selected item(s) in a view and `false` otherwise. + +### "@lcid" + +This will evaluate to the LCID of the current culture. This can be used to format the date, time, and numbers. + +### "@UIlcid" + +This will evaluate to the LCID of the current UI culture. This can be used to show localized display strings. diff --git a/docs/declarative-customization/get-started-create-site-design.md b/docs/declarative-customization/get-started-create-site-design.md index 4e9ceffe5..92b22361c 100644 --- a/docs/declarative-customization/get-started-create-site-design.md +++ b/docs/declarative-customization/get-started-create-site-design.md @@ -1,156 +1,162 @@ ---- -title: Get started creating SharePoint site designs and site scripts -description: Create site designs to provide reusable lists, themes, layouts, pages, or custom actions so that your users can quickly build new SharePoint sites with the features they need. -ms.date: 12/19/2018 -localization_priority: Priority ---- - -# Get started creating site designs and site scripts - -You can create site designs to provide reusable lists, themes, layouts, pages, or custom actions so that your users can quickly build new SharePoint sites with the features they need. - -This article describes how to build a simple site design that adds a SharePoint list for tracking customer orders. You'll use the site design to create a new SharePoint site with the custom list. You'll learn how to use SharePoint PowerShell cmdlets to create site scripts and site designs. You can also use REST APIs to perform the same actions. The corresponding REST calls are shown for reference in each step. - -## Create the site script in JSON - -A site design is a collection of actions that SharePoint runs when creating a new site. Actions describe changes to apply to the new site, such as creating a new list or applying a theme. The actions are specified in a JSON script, which is a list of all actions to apply. When a script runs, SharePoint completes each action in the order listed. - -Each action is specified by the "verb" value in the JSON script. Also, actions can have subactions that are also "verb" values. In the following JSON, the script specifies to create a new list named **Customer Tracking**, and then subactions set the description and add several fields to define the list. - -1. Download and install the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588). If you already have a previous version of the shell installed, uninstall it first and then install the latest version. - -2. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. - -3. Create - and assign the JSON that describes the new script - to a variable as shown in the following PowerShell code. You can view and reference the latest JSON schema file here: https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json - - ```powershell - $site_script = ' - { - "$schema": "schema.json", - "actions": [ - { - "verb": "createSPList", - "listName": "Customer Tracking", - "templateType": 100, - "subactions": [ - { - "verb": "SetDescription", - "description": "List of Customers and Orders" - }, - { - "verb": "addSPField", - "fieldType": "Text", - "displayName": "Customer Name", - "isRequired": false, - "addToDefaultView": true - }, - { - "verb": "addSPField", - "fieldType": "Number", - "displayName": "Requisition Total", - "addToDefaultView": true, - "isRequired": true - }, - { - "verb": "addSPField", - "fieldType": "User", - "displayName": "Contact", - "addToDefaultView": true, - "isRequired": true - }, - { - "verb": "addSPField", - "fieldType": "Note", - "displayName": "Meeting Notes", - "isRequired": false - } - ] - } - ], - "bindata": { }, - "version": 1 - } - ' - ``` - -
- -The previous script creates a new SharePoint list named **Customer Tracking**. It sets the description and adds four fields to the list. Note that each of these are considered an action. Site scripts are limited to 30 cumulative actions (across one or more scripts that may be called in a site design) if applied programmatically using the Invoke-SPOSiteDesign command. If they are applied through the UX or using the Add-SPOSiteDesignTask command then the limit is 300 cumulative actions (or 100K characters) . - -## Add the site script - -Each site script must be registered in SharePoint so that it is available to use. Add a new site design by using the **Add-SPOSiteScript** cmdlet. The following example shows how to add the JSON script described previously. - -```powershell -C:\> Add-SPOSiteScript - -Title "Create customer tracking list" - -Content $site_script - -Description "Creates list for tracking customer contact information" -``` - -After running the cmdlet, you get a result that lists the site script **ID** of the added script. Keep track of this ID somewhere because you will need it later when you create the site design. - -The REST API to add a new site script is **CreateSiteScript**. - -## Create the site design - -Next, you need to create the site design. The site design appears in a drop-down list when someone creates a new site from one of the templates. It can run one or more site scripts that have already been added. - -- Run the following cmdlet to add a new site design. Replace `` with the site script ID from when you added the site script. - -```powershell -C:\> Add-SPOSiteDesign - -Title "Contoso customer tracking" - -WebTemplate "64" - -SiteScripts "" - -Description "Tracks key customer data in a list" -``` - -The previous cmdlet creates a new site design named Contoso customer tracking. The `-WebTemplate` value selects which base template to associate with. The value `"64"` indicates Team site template, and the value `"68"` indicates the Communication site template. If you have disabled modern Group creation (or restricted to a subset of users) and wish to still allow your users to apply site designs to the "group-less" modern Team site template, publish your site designs using the `-WebTemplate` value `"1"`. - -The JSON response displays the **ID** of the new site design. You can use it in subsequent cmdlets to update or modify the site design. - -The REST API to add a new site design is **CreateSiteDesign**. - -## Use the new site design - -Now that you've added a site script and site design, you can use it to create new sites through the self-service site creation experience or apply the site design to an existing site using the **Invoke-SPOSiteDesign** command in PowerShell. If you are using hub sites you can even associate a site design to a hub so it gets applied to all joining sites. - -### New site creation - -1. Go to the home page of the SharePoint site that you are using for development. - -2. Choose **Create site**. - -3. Choose **Team site**. - -4. In the **Choose a design** drop-down, select your site design **customer orders**. - -5. In **Site name**, enter a name for the new site **Customer order tracking**. - -6. Choose **Next**. - -7. Choose **Finish**. - -8. A notification bar will be displayed indicating that your script is being applied. To invoke the site design information panel, click the **View progress** link. Once the script(s) have completed the notification banner message will change to **Site Design applied. Refresh this site to see the changes.**, allowing you to either invoke the panel or refresh the page. - -9. You will see the custom list on the page. - -### Apply to an existing site collection - -You can also apply a published site design to an existing site collection using the [Invoke-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Invoke-SPOSiteDesign?view=sharepoint-ps) cmdlet. - -You can apply a published site design to: -1. Group-connected Team site -2. Team site not connected to an Office 365 Group -3. Communication site -4. Classic team site -5. Classic publishing site - -### Associate with a hub site - -You can also associate a published site design to a hub site in hub site settings so it can be applied to all joining sites. For details on how to associate the site design either through the UI or using the Set-SPOHubSite command please review the [Set up a site design for your hub site](https://docs.microsoft.com/sharepoint/set-up-site-design-hub-site) article. - -## See also - -- [SharePoint site design and site script overview](site-design-overview.md) +--- +title: Get started creating SharePoint site templates and site scripts +description: Create site templates to provide reusable lists, themes, layouts, pages, or custom actions so that your users can quickly build new SharePoint sites with the features they need. +ms.date: 09/30/2022 +ms.localizationpriority: high +--- + +# Get started creating site templates and site scripts + +You can create site templates to provide reusable lists, themes, layouts, or custom actions so that your users can quickly build new SharePoint sites with the features they need. + +This article describes how to build a simple site template that adds a SharePoint list for tracking customer orders. You'll use the site template to create a new SharePoint site with the custom list. You'll learn how to use SharePoint PowerShell cmdlets to create site scripts and site templates. You can also use REST APIs to perform the same actions. The corresponding REST calls are shown for reference in each step. + +## Create the site script in JSON + +A site script is a collection of actions that SharePoint runs when creating a new site. Actions describe changes to apply to the new site, such as creating a new list or applying a theme. The actions are specified in a JSON script, which is a list of all actions to apply. When a script runs, SharePoint completes each action in the order listed. + +Each action is specified by the "verb" value in the JSON script. Also, actions can have subactions that are also "verb" values. In the following JSON, the script specifies to create a new list named **Customer Tracking**, and then subactions set the description and add several fields to define the list. + +1. Download and install the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588). If you already have a previous version of the shell installed, uninstall it first and then install the latest version. +1. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. +1. Create - and assign the JSON that describes the new script - to a variable as shown in the following PowerShell code. You can view and reference the latest JSON schema file: [https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json](https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json) + + ```powershell + $site_script = ' + { + "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json", + "actions": [ + { + "verb": "createSPList", + "listName": "Customer Tracking", + "templateType": 100, + "subactions": [ + { + "verb": "setDescription", + "description": "List of Customers and Orders" + }, + { + "verb": "addSPField", + "fieldType": "Text", + "displayName": "Customer Name", + "isRequired": false, + "addToDefaultView": true + }, + { + "verb": "addSPField", + "fieldType": "Number", + "displayName": "Requisition Total", + "addToDefaultView": true, + "isRequired": true + }, + { + "verb": "addSPField", + "fieldType": "User", + "displayName": "Contact", + "addToDefaultView": true, + "isRequired": true + }, + { + "verb": "addSPField", + "fieldType": "Note", + "displayName": "Meeting Notes", + "isRequired": false + } + ] + } + ] + } + ' + ``` + +The previous script creates a new SharePoint list named **Customer Tracking**. It sets the description and adds four fields to the list. Note that each of these are considered an action. Site scripts are limited to 30 cumulative actions (across one or more scripts that may be called in a site template) if applied programmatically using the `Invoke-SPOSiteDesign` command. If they are applied through the UI or using the `Add-SPOSiteDesignTask` command then the limit is 300 cumulative actions (or 100K characters). + +## Add the site script + +Each site script must be registered in SharePoint so that it is available to use. Add a new site script by using the **Add-SPOSiteScript** cmdlet. The following example shows how to add the JSON script described previously. + +```powershell +C:\> Add-SPOSiteScript + -Title "Create customer tracking list" + -Content $site_script + -Description "Creates list for tracking customer contact information" +``` + +After running the cmdlet, you get a result that lists the site script **ID** of the added script. Keep track of this ID somewhere because you will need it later when you create the site template. + +The REST API to add a new site script is **CreateSiteScript**. + +## Create the site template + +Next, you need to create the site template. The site template appears in a drop-down list when someone creates a new site from one of the templates. It can run one or more site scripts that have already been added. + +- Run the following cmdlet to add a new site template. Replace `` with the site script ID from when you added the site script. + +```powershell +C:\> Add-SPOSiteDesign + -Title "Contoso customer tracking" + -WebTemplate "64" + -SiteScripts "" + -Description "Tracks key customer data in a list" +``` + +The previous cmdlet creates a new site template named Contoso customer tracking. + +| Parameter | Value | Site template type | +| :---------- | :---- | :--------------------------------------- | +| WebTemplate | 64 | Team site template | +| WebTemplate | 1 | Team site (with group creation disabled) | +| WebTemplate | 68 | Communication site template | +| WebTemplate | 69 | Channel site template | + +The JSON response displays the **ID** of the new site template. You can use it in subsequent cmdlets to update or modify the site template. + +The REST API to add a new site template is **CreateSiteDesign**. + +## Use the new site template + +Now that you've added a site script and site template, you can use it to create new sites through the self-service site creation experience or apply the site template to an existing site using the **Invoke-SPOSiteDesign** command in PowerShell. If you are using hub sites you can even associate a site template to a hub so it gets applied to all joining sites. + +### New site creation + +1. Go to the home page of the SharePoint site that you are using for development. +1. Choose **Create site**. +1. Choose the type of site you need to use. SharePoint will create a team site using the Microsoft **Team collaboration template** or a communication site using the Microsoft **Topic** template unless another custom site template is set as default. +1. Choose **Next**. +1. In **Site name**, enter a name for the new site **Customer order tracking**. +1. Choose **Finish**. +1. Next, go to **Settings** and select **Apply a site template**. +1. Select the site template you just created. +1. Once applied, your new template will display under the tab in the template viewer titled **From your organization.** +1. When the new template has been applied, you will see the custom list on the page. + +### Apply to an existing site + +You can also apply a published site template to existing sites. On the home page of the site, site owners can navigate to **Settings** and then **Apply a site template** to browse and apply templates provided by your organization and Microsoft. + +You can apply templates to existing site collections in bulk by using the [Invoke-SPOSiteDesign](/powershell/module/sharepoint-online/Invoke-SPOSiteDesign) cmdlet. + +**Published site templates can be applied to:** + +1. Group-connected team sites +1. Team sites that not connected to a Microsoft 365 group +1. Communication sites +1. Channel sites +1. Classic team sites +1. Classic publishing sites + +The REST API to apply a site template to an existing site collection is **ApplySiteDesign**. + +### Associate with a hub site + +Apply a published site template to a new or existing hub site. Then, all associated sites will inherit the hub site template and theme. Navigate to the home page of the hub and go to **Settings** and then **Apply a site template**. Learn more about how to [enable site associations for your hub site](https://support.microsoft.com/office/set-up-your-sharepoint-hub-site-e2daed64-658c-4462-aeaf-7d1a92eba098). + +You can also use the `Set-SPOHubSite` cmdlet. Review the [PowerShell cmdlets for SharePoint hub sites](../features/hub-site/hub-site-powershell.md) article. + +>[!NOTE] +> [Channel sites](/sharepoint/teams-connected-sites) are automatically blocked from joining a hub site. + +## See also + +- [SharePoint site template and site script overview](site-design-overview.md) +- [How to apply and customize SharePoint site templates](https://support.microsoft.com/office/apply-and-customize-sharepoint-site-templates-39382463-0e45-4d1b-be27-0e96aeec8398) diff --git a/docs/declarative-customization/images/list-form-configuration-body.png b/docs/declarative-customization/images/list-form-configuration-body.png new file mode 100644 index 000000000..2fc608c00 Binary files /dev/null and b/docs/declarative-customization/images/list-form-configuration-body.png differ diff --git a/docs/declarative-customization/images/list-form-configuration-footer.png b/docs/declarative-customization/images/list-form-configuration-footer.png new file mode 100644 index 000000000..0f39e670f Binary files /dev/null and b/docs/declarative-customization/images/list-form-configuration-footer.png differ diff --git a/docs/declarative-customization/images/list-form-configuration-header.png b/docs/declarative-customization/images/list-form-configuration-header.png new file mode 100644 index 000000000..a3c4d6093 Binary files /dev/null and b/docs/declarative-customization/images/list-form-configuration-header.png differ diff --git a/docs/declarative-customization/images/list-form-configuration-menu.png b/docs/declarative-customization/images/list-form-configuration-menu.png new file mode 100644 index 000000000..9aac6a9ee Binary files /dev/null and b/docs/declarative-customization/images/list-form-configuration-menu.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-app-files.menu.png b/docs/declarative-customization/images/pnpprovisioning-app-files.menu.png new file mode 100644 index 000000000..04e43297f Binary files /dev/null and b/docs/declarative-customization/images/pnpprovisioning-app-files.menu.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-create-function-queue.png b/docs/declarative-customization/images/pnpprovisioning-create-function-queue.png index c774078b1..28f3244be 100644 Binary files a/docs/declarative-customization/images/pnpprovisioning-create-function-queue.png and b/docs/declarative-customization/images/pnpprovisioning-create-function-queue.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-create-function.png b/docs/declarative-customization/images/pnpprovisioning-create-function.png index a1cd549b1..6a95fea92 100644 Binary files a/docs/declarative-customization/images/pnpprovisioning-create-function.png and b/docs/declarative-customization/images/pnpprovisioning-create-function.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-experimental-features.png b/docs/declarative-customization/images/pnpprovisioning-experimental-features.png index caf4b8ddd..1a03fd9f2 100644 Binary files a/docs/declarative-customization/images/pnpprovisioning-experimental-features.png and b/docs/declarative-customization/images/pnpprovisioning-experimental-features.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-runtime-settings.png b/docs/declarative-customization/images/pnpprovisioning-runtime-settings.png new file mode 100644 index 000000000..8d232d008 Binary files /dev/null and b/docs/declarative-customization/images/pnpprovisioning-runtime-settings.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-runtime-stack-selection.png b/docs/declarative-customization/images/pnpprovisioning-runtime-stack-selection.png new file mode 100644 index 000000000..bed159697 Binary files /dev/null and b/docs/declarative-customization/images/pnpprovisioning-runtime-stack-selection.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-switch-classic-experience.png b/docs/declarative-customization/images/pnpprovisioning-switch-classic-experience.png new file mode 100644 index 000000000..b4595454d Binary files /dev/null and b/docs/declarative-customization/images/pnpprovisioning-switch-classic-experience.png differ diff --git a/docs/declarative-customization/images/pnpprovisioning-view-files.png b/docs/declarative-customization/images/pnpprovisioning-view-files.png deleted file mode 100644 index 502ed5fd8..000000000 Binary files a/docs/declarative-customization/images/pnpprovisioning-view-files.png and /dev/null differ diff --git a/docs/declarative-customization/list-form-conditional-show-hide.md b/docs/declarative-customization/list-form-conditional-show-hide.md new file mode 100644 index 000000000..1d4afe455 --- /dev/null +++ b/docs/declarative-customization/list-form-conditional-show-hide.md @@ -0,0 +1,161 @@ +--- +title: Show or hide columns in a list form +description: Customize which columns to show or hide using a conditional formula in the list form by constructing a simple formula that are equations performing conditional checks on values in a SharePoint list or library. +ms.date: 07/28/2025 +ms.localizationpriority: high +--- + +# Show or hide columns in a list or library form + +You can show or hide columns in a list or library form as an alternative to deleting them. When you hide a column, it doesn't affect the column or the data in the column, as it would if you delete it. To re-use the column, you can simply show it again in the form. + +To show or hide a column in a list or library form: + +1. Go to the list or library for which you want to show or hide columns in the form. +1. If you are in a list: + + - Open an item to view the item details in the display form. + +1. If you are in a document library: + + - Select a file. + - In the **Information Pane**: + - Locate the **Properties** section. + - Click **Edit all**. + +1. At the top of the form, select **Edit form > Edit columns**. +1. In the **Edit columns** pane, check (to show) or uncheck (to hide) the checkbox for the column or columns as needed. + + > [!NOTE] + > If you want to re-arrange the order of the columns, either drag-and-drop the column name or first select the far right-hand edge of the column name to display the options menu **(...)** and then select Move Up or Move Down as preferred. + +1. When you're finished, select **Save**. + +## Specify conditional formula to show or hide columns + +You can show or hide columns in a list form based on another column's value by specifying a formula that are equations performing conditional checks on values in a SharePoint list or library. + +To specify a conditional formula for a column, in the **Edit columns** pane: + +1. Navigate to the desired column for which you want to set a conditional formula +1. Select the far right-hand edge of the column name to display the options menu **(...)** +1. In the more options, select **Edit conditional formula**. +1. In the **Edit conditional formula** dialog: + - To determine whether this column is shown or hidden, specify a conditional formula based on the value of another column. + - To clear the condition, leave it blank. + +1. When you are finished, select **Save**. + +### Get started with conditional formulas + +Formulas are equations that perform conditional checks on column values in a list or library. A formula starts with an equal sign (=) followed by the _if_ function that returns either a _true_ or a _false_ result. + +For example, the following formula checks if the value for the *Category* column is *Product Management*: + +``` +=if([$Category] == 'Product Management', 'true', 'false') +``` + +Returning _true_ shows the column on the form while returning _false_ hides the column. + +The column is represented by specifying the **internal name** of the field preceded by a dollar sign and surrounded by square brackets: `[$InternalName]`. For example, to get the value of a field with an internal name of "ProductName", use `[$ProductName]`. + +#### Unsupported column types in conditional formulas + +While the formula supports many of the available column types, we do not currently support the following column types: + +- Person or Group with multiple selections +- Choice with multiple selections +- Lookup with multiple selections +- Time calculations in **Date and Time** column +- Currency columns +- Location columns +- Calculated columns +- Managed Metadata columns + +#### Quick formula reference + +##### Choice column + +The following formula checks if the choice column `[$Category]` has a value *Product Management*: + +``` +=if([$Category] == 'Product Management', 'true', 'false') +``` + +##### Number column + +The following formula checks if the number column `[$Flightscost]` is less than or equal to *120*: + +``` +=if([$Flightscost] <= 120, 'true', 'false') +``` + +You can also do arithmetic calculations, such as adding the value of two columns and checking its sum as given in the following formula: + +``` +=if(([$Flightscost] + [$Hotelcost]) > 500, 'true', 'false') +``` + +##### Date column + +The following formula checks if the date column `[$StartDate]` equals a specific date. To do so, it uses the *Date()* function to convert a given string into a date: + +``` +=if([$StartDate] == Date('4/6/2020'), 'true', 'false') +``` + +An example of checking if the date column `[$StartDate]` is less than or equal to a specific date: + +``` +=if([$StartDate] <= Date('4/6/2020'), 'true', 'false') +``` + +An example of checking if the dates from `[$StartDate]` and `[$EndDate]` columns are between specific dates: + +``` +=if([$StartDate] >= Date('4/6/2020') && [$EndDate] <= Date('6/10/2020'), 'true', 'false') +``` + +##### Person column + +The following formula checks if an email of person column `[$Owner]` is equal to a specific user's email: + +``` +=if([$Owner.email] == 'nestorw@contoso.com', 'true', 'false') +``` + +##### Boolean (Yes/No) column + +The following formula checks if the Yes/No column `[$Promoted]` equals a Yes. To do so, it checks for the value _true_ which maps to _Yes_ for users. + +``` +=if([$Promoted] == true, 'true', 'false') +``` + +The following are also valid: + +``` +=if([$Promoted], 'true', 'false') +``` + +``` +=[$Promoted] +``` + +##### Lookup column + +> [!NOTE] +> When accessing lookup columns in a column or view formatting, you can access the lookup value and lookup id as separate values. In form formatting and conditional field expressions, both values are returned as a single line of text. For instance, a lookup column referencing an item with item ID 1 (in the source list) with a value of `Toronto` will have a value of `1;#Toronto` when used in form formatting or conditional field expressions. + +The following formula checks if the lookup column `[$City]` has a value equal to *Toronto*. To do so, it splits the lookup value result by the separator and checks against the value. + +``` +=if(substring([$City],indexOf([$City],';#')+2,1000) == 'Toronto', 'true', 'false') +``` + +Similarly, you can compare against the ID portion of the lookup using this expression: + +``` +=if(Number(substring([$City],0,indexOf([$City],';#'))) == 1, 'true', 'false') +``` diff --git a/docs/declarative-customization/list-form-configuration.md b/docs/declarative-customization/list-form-configuration.md new file mode 100644 index 000000000..ab641654f --- /dev/null +++ b/docs/declarative-customization/list-form-configuration.md @@ -0,0 +1,302 @@ +--- +title: Configure the list form +description: Configure list form with a custom header, footer and body with one or more sections. +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# Configure the list form + +You can configure the list form in a list or library with a custom header, footer and the form body with one or more sections with fields in each of those sections. The form configuration does not change the data in the list item or file; it only changes how the form is displayed to users who browse the list or library. Anyone who can create and manage views in a list can use form configuration to configure the form with header, footer, and body with sections. + +To configure a form, you will use JSON formatters that you are already familiar with when formatting a [column](column-formatting.md) or a [view](view-formatting.md) in a list or library. Form configuration allows for certain predefined elements and attributes to build the custom header, footer, and body with one or more sections. + +## Get started + +To configure the form in a list or library: + +1. Go to the list or library for which you want to configure the form. +1. If you are in a list: + + - Open an item to view the item details in the display form. + +1. If you are in a document library: + + - Select a file. + - Select ... + - Select More + - Select Properties + +1. At the top of the form, expand **Edit Form** icon and then select **Configure layout** + + ![Configure list form](images/list-form-configuration-menu.png) + +1. In the **Format** pane, you can choose to apply formatting to the following form sections: + + - Header + - Body + - Footer + +## Configure custom header + +1. To apply formatting to the header, select **Header** in the **Apply formatting to** dropdown. +1. Paste your custom header formatter in the JSON text input area. + + > [!NOTE] + > Form configuration allows for certain [predefined elements and attributes](column-formatting.md#creating-custom-json) to build the custom header. + +1. Below is an example of a custom header & JSON: + + ![Custom list form header](images/list-form-configuration-header.png) + + ```JSON + { + "elmType": "div", + "attributes": { + "class": "ms-borderColor-neutralTertiary" + }, + "style": { + "width": "99%", + "border-top-width": "0px", + "border-bottom-width": "1px", + "border-left-width": "0px", + "border-right-width": "0px", + "border-style": "solid", + "margin-bottom": "16px" + }, + "children": [ + { + "elmType": "div", + "style": { + "display": "flex", + "box-sizing": "border-box", + "align-items": "center" + }, + "children": [ + { + "elmType": "div", + "attributes": { + "iconName": "Group", + "class": "ms-fontSize-42 ms-fontWeight-regular ms-fontColor-themePrimary", + "title": "Details" + }, + "style": { + "flex": "none", + "padding": "0px", + "padding-left": "0px", + "height": "36px" + } + } + ] + }, + { + "elmType": "div", + "attributes": { + "class": "ms-fontColor-neutralSecondary ms-fontWeight-bold ms-fontSize-24" + }, + "style": { + "box-sizing": "border-box", + "width": "100%", + "text-align": "left", + "padding": "21px 12px", + "overflow": "hidden" + }, + "children": [ + { + "elmType": "div", + "txtContent": "='Contact details for ' + [$Title]" + } + ] + } + ] + } + ``` + +1. To preview your changes, click the **Preview** button. +1. To save your changes, click the **Save** button. +1. Close and open the form again to view the custom header. + +## Configure custom footer + +1. To apply formatting to the footer, in the **Format** pane, select **Footer** in the **Apply formatting to** dropdown. +1. Paste your custom footer formatter in the JSON text input area. + + > [!NOTE] + > Form configuration allows for certain [predefined elements and attributes](column-formatting.md#creating-custom-json) to build the custom footer. + +1. Below is an example of a custom footer & JSON: + + ![Custom list form footer](images/list-form-configuration-footer.png) + + ```JSON + { + "elmType": "div", + "style": { + "width": "100%", + "text-align": "left", + "overflow": "hidden", + "border-top-width": "1px" + }, + "children": [ + { + "elmType": "div", + "style": { + "width": "100%", + "padding-top": "10px", + "height": "24px" + }, + "children": [ + { + "elmType": "a", + "txtContent": "='Contact Details for ' + [$Title]", + "attributes": { + "target": "_blank", + "href": "='https://aka.ms/contacts?email=' + [$Email]", + "class": "ms-fontColor-themePrimary ms-borderColor-themePrimary ms-fontWeight-semibold ms-fontSize-m ms-fontColor-neutralSecondary–hover ms-bgColor-themeLight–hover" + } + } + ] + } + ] + } + ``` + +1. To preview your changes, click the **Preview** button. +1. To save your changes, click the **Save** button. +1. Close and open the form again to view the custom footer. + +## Configure custom body with one or more sections + +1. To apply formatting to the body, in the **Format** pane, select **Body** in the **Apply formatting to** dropdown. +1. Paste your custom body formatter in the JSON text input area. +1. Unlike the header and the footer, body configuration only allows defining one or more sections and adding one or more columns into each of those sections. + + - One or more sections can be defined for a body. + - Each section can reference one or more columns in the list or library. + - A column can be referenced only in one section. + - If a column is referenced in multiple sections, the first section where the column is referenced will take precedence. + - A column not referenced in any of the sections will be automatically referenced in the last section. + - New columns added will be automatically referenced in the last section. + +1. Below is the JSON structure to get started with defining sections and referencing columns in the sections: + + ```JSON + { + "sections": [ + { + //give a display name for the section + "displayname": "", + "fields": [ + //reference your fields here using their display name + "Title" + ] + }, + { + //give a display name for the section + "displayname": "", + "fields": [ + //reference your fields here using their display name + ] + } + ] + } + ``` + +1. Below is an example of a custom body JSON with sections: + + ```JSON + { + "sections": [ + { + "displayname": "", + "fields": [ + "Title" + ] + }, + { + "displayname": "Details", + "fields": [ + "Department", + "Email", + "Country" + ] + }, + { + "displayname": "Application", + "fields": [ + "Application Id", + "Approver", + "Reviewer" + ] + } + ] + } + ``` + +1. Once the body is customized with one or more sections, the list or library form will switch to a multi-column layout. + + > [!NOTE] + > Configuring form body will switch your list or library form layout from single-column to a multi-column layout. We will add support for configuring the body with single-column layout in a future update. + + ![Custom list form body with sections](images/list-form-configuration-body.png) + +1. To preview your changes, click the **Preview** button. +1. To save your changes, click the **Save** button. +1. Close and open the form again to view the custom body. + + +## Custom Formatter for Read-Only Fields + +### Introduction + +Microsoft Lists offers a powerful way to organize information and collaborate with your team. With the rise of AI-based list item creation, users often need to view but not edit certain fields — like system-generated data or bot-added details. To meet this need, a new custom formatter feature is proposed to allow fields to appear as read-only in list forms. + +### Why Read-Only Fields Matter + +Currently, read-only fields are hidden from New Item and Edit forms. This creates challenges when AI bots or automated processes create items containing critical data that users need to see but not modify. For example: + +- A bot creates a customer service ticket with Issue details Issue Title, Issue Description. +- Users should see this information to take actions (e.g., send an email), but not be able to change it. + +The new custom formatter solves this by allowing these fields to display as read-only. + +### How the Custom Formatter Works + +The custom formatter introduces a new JSON configuration to mark fields as read-only in the form views. + +### JSON Structure + +```json +{ + "sections": [{}], + "fieldsettings": [ + { + "name": "fieldName", + "readonly": true + } + ] +} +``` + +- name: The internal name of the field. +- readonly: When set to true, the field is displayed as read-only. + +### Behavior in Different Form Views + +The custom formatter ensures a consistent user experience: + +- New Item form: The read-only field will not be shown. +- Edit form: The field is displayed without an editable textbox, similar to a Calculated Column. +- Edit all mode: The field remains visible and uneditable. + +The Save button works as expected — no accidental modifications to the read-only fields. + +### Example Use Case + +Imagine a CRM bot creating tickets with pre-filled Issue details. Using this formatted: + +- Issue Title (read-only): Users can see and copy the Issue Title but can't modify it. +- Issue Description (read-only): Users can see and copy the Issue Description but can't modify it. +- Issue Source (read-only): Users can click on the Issue source link but can't modify it. + +![image](https://github.com/user-attachments/assets/74c21844-a966-4930-93bb-cce10d69fa0e) diff --git a/docs/declarative-customization/site-design-json-schema.md b/docs/declarative-customization/site-design-json-schema.md index 8c0bb2d95..2ed0397a6 100644 --- a/docs/declarative-customization/site-design-json-schema.md +++ b/docs/declarative-customization/site-design-json-schema.md @@ -1,94 +1,114 @@ --- -title: Site design JSON schema -description: JSON schema reference for building site designs for SharePoint. -ms.date: 10/07/2019 -localization_priority: Priority +title: Site template JSON schema +description: JSON schema reference for building site templates for SharePoint. +ms.date: 11/18/2024 +ms.localizationpriority: high --- -# Site design JSON schema +# Site template JSON schema -The site design is a list of **actions**. For more complex actions, such as creating a list, there are also **subactions**. Each action is specified by a "verb" value. Verb actions are run in the order they appear in the JSON script. Only the verb actions listed here can be used; otherwise, an "unable to handle action" error will be thrown when trying to upload a site script. More actions will be added over time. +The site template is a list of **actions**. For more complex actions, such as creating a list, there are also **subactions**. Each action is specified by a "verb" value. Verb actions are run in the order they appear in the JSON script. Only the verb actions listed here can be used; otherwise, an "unable to handle action" error will be thrown when trying to upload a site script. More actions will be added over time. The overall JSON structure is specified as follows: ```json { - "$schema": "schema.json", - "actions": [ - ... - - ... - ], - "bindata": { }, - "version": 1 -}; + "$schema": "schema.json", + "actions": [ + ... + + ... + ] +} ``` -You can view - and reference - the latest schema here: https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json +> [!TIP] +> You can view - and reference - the latest schema here: https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json + +> [!NOTE] +> **Actions** can be run more than once on a site. Rerunning **actions** on the same site with the same parameters will result in an update to the existing schema and not duplication of schema. + + + +## addContentTypesFromHub + +Use the **addContentTypesFromHub** verb to sync content types from a content type hub to the site. + +> [!NOTE] +> Once **addContentTypesFromHub** is applied on a site, the **addContentType** subaction on a list will be able to add it to the list by name. + +### JSON value + +- `ids`: An array of the content type IDs that need to be synced. + +#### Example + +```json +{ + "verb": "addContentTypesFromHub", + "ids": ["0x01007CE30DD1206047728BAFD1C39A850120"] +} +``` -#### Applying site designs multiple times -**Actions** can be run more than once on a site. Rerunning **actions** on the same site with the same parameters will result in an update to the existing schema and not duplication of schema. ## Create a new SharePoint list Use the **createSPList** verb to create a new SharePoint list. > [!NOTE] -> Once **createSPList** is applied on a site, runnning the **createSPList** with the same list name will act as an update to the existing list. +> Once **createSPList** is applied on a site, running the **createSPList** with the same list name will act as an update to the existing list. -#### JSON values +### JSON values -- **listName** – The name of the list. -- **templateType** – Which template to apply to the list. Typically you would use value 100. The full list of template type values are documented in [SPListTemplateType enumeration](https://msdn.microsoft.com/library/microsoft.sharepoint.splisttemplatetype.aspx) - but the ones we currently support include: +- `listName`: The name of the list. +- `templateType`: Which template to apply to the list. Typically, you would use value 100. The full list of template type values is documented in [SPListTemplateType enumeration](/previous-versions/office/sharepoint-server/ms413878(v=office.15)) - but the ones we currently support include: | List Template Name | Enum | - |--------------|---------| - Generic List | 100 - Document Library | 101 - Survey | 102 - Links | 103 - Announcements | 104 - Contacts | 105 - Events | 106 - Tasks | 107 - Discussion Board | 108 - PictureLibrary | 109 - Site Pages | 119 - Issue Tracking | 1100 - - If you use 101 or 119 and reference the default names ("Documents" or "Site Pages") you can modify the library created with the template. See example below. -- **subactions** – An array of actions that run in the order listed to create your list. + | ------------------ | ---- | + | Generic List | 100 | + | Document Library | 101 | + | Survey | 102 | + | Links | 103 | + | Announcements | 104 | + | Contacts | 105 | + | Events | 106 | + | Tasks | 107 | + | Discussion Board | 108 | + | PictureLibrary | 109 | + | Site Pages | 119 | + | Issue Tracking | 1100 | + + If you use 101 or 119 and reference the default names ("Documents" or "Site Pages"), you can modify the library created with the template. See example below. +- `subactions`: An array of actions that run in the order listed to create your list. #### Example ```json { - "verb": "createSPList", - "listName": "Customer Tracking", - "templateType": 100, - "subactions": [ - { - "verb": "setDescription", - "description": "List of Customers and Orders" - } - ] + "verb": "createSPList", + "listName": "Customer Tracking", + "templateType": 100, + "subactions": [ + { + "verb": "setDescription", + "description": "List of Customers and Orders" + } + ] }, { - "verb": "createSPList", - "listName": "Documents", - "templateType": 101, - "subactions": [ - { - "verb": "setDescription", - "description": "This is a modified default document library" - } - ] + "verb": "createSPList", + "listName": "Documents", + "templateType": 101, + "subactions": [ + { + "verb": "setDescription", + "description": "This is a modified default document library" + } + ] } ``` -
- -The subactions array provides additional actions to specify how to construct the list. Subactions are also specified using a **verb** value. +The subactions array provides additional actions to specify how to construct the list. Subactions are also specified using a `verb` value. ### setDescription @@ -96,14 +116,14 @@ Sets the description of the list. #### JSON value -- **description** – The description of the new list. +- `description`: The description of the new list. #### Example ```json { - "verb": "setDescription", - "description": "List of Customers and Orders" + "verb": "setDescription", + "description": "List of Customers and Orders" } ``` @@ -113,24 +133,24 @@ Adds a new field. #### JSON values -- **fieldType** – The field type can be set to **Text**, **Note**, **Number**, **Boolean**, **User**, or **DateTime**. For other data types, see the addSPFieldXml action. -- **displayName** – The display name of the field. -- **id** – An optional attribute. If provided, specifies the id of the field. It needs to be a unique, randomly generated GUID. Providing a value for this is strongly recommended to ensure the field is not added multiple times if the script is re-run. -- **internalName** – An optional attribute. If provided, specifies the internal name of the field. If not provided, the internal name is based on the display name. -- **isRequired** – **True** if this field is required to contain information; otherwise, **false**. -- **addToDefaultView** – **True** if the field will be added to the default view; otherwise, **false**. -- **enforceUnique** – An optional attribute that defaults to **false**. If **true**, all values for this field must be unique. +- `fieldType`: The field type can be set to `Text`, `Note`, `Number`, `Boolean`, `User`, or `DateTime`. For other data types, see the addSPFieldXml action. +- `displayName`: The display name of the field. +- `id`: An optional attribute. If provided, specifies the id of the field. It needs to be a unique, randomly generated GUID. Providing a value for this is recommended to ensure the field isn't added multiple times if the script is rerun. +- `internalName`: An optional attribute. If provided, specifies the internal name of the field. If not provided, the internal name is based on the display name. +- `isRequired`: **True** if this field is required to contain information; otherwise, **False**. +- `addToDefaultView`: **True** if the field will be added to the default view; otherwise, **False**. +- `enforceUnique`: An optional attribute that defaults to **False**. If **True**, all values for this field must be unique. #### Example ```json { - "verb": "addSPField", - "fieldType": "Text", - "displayName": "Customer Name", - "isRequired": false, - "id": "c532fcb9-cdb3-45c6-8247-c784dcd58e1a" - "addToDefaultView": true + "verb": "addSPField", + "fieldType": "Text", + "displayName": "Customer Name", + "isRequired": false, + "id": "c532fcb9-cdb3-45c6-8247-c784dcd58e1a", + "addToDefaultView": true } ``` @@ -140,47 +160,47 @@ Deletes a default field that was provided by the selected template type. #### JSON value -- **displayName** – The display name to identify the field to delete. +- `displayName`: The display name to identify the field to delete. #### Example ```json { - "verb": "deleteSPField", - "displayName": "Modified" + "verb": "deleteSPField", + "displayName": "Modified" } ``` ### addSPFieldXml -Enables defining fields and their elements using Collaborative Application Markup Language (CAML). For reference, see [Field element (Field)](https://docs.microsoft.com/sharepoint/dev/schema/field-element-field). Note that providing the ID attribute in the field schemaXml is very important in order to prevent the field from being created multiple times if the script is run more than once. +Enables defining fields and their elements using Collaborative Application Markup Language (CAML). For reference, see [Field element (Field)](/sharepoint/dev/schema/field-element-field). Providing the ID attribute in the field schemaXml is important in order to prevent the field from being created multiple times if the script is run more than once. -Currently these field constructs cannot be designated as site columns nor added to content types. To create site columns with Field XML use the **createSiteColumnXml** action. +Currently these field constructs can't be designated as site columns nor added to content types. To create site columns with Field XML, use the **createSiteColumnXml** action. #### JSON value -- **schemaXml** – The CAML block to define the field. -- **addToDefaultView** – **True** if the field will be added to the default view; otherwise, **false**. +- `schemaXml`: The CAML block to define the field. +- `addToDefaultView`: **True** if the field will be added to the default view; otherwise, **False**. #### Example ```json { - "verb": "addSPFieldXml", - "schemaXml": "OperationsOperationsITLegalEngineering" + "verb": "addSPFieldXml", + "schemaXml": "OperationsOperationsITLegalEngineering" } ``` ### addSPLookupFieldXml -Enables defining lookup fields and their dependent lists element using Collaborative Application Markup Language (CAML). For reference, see [Field element (Field)](https://docs.microsoft.com/sharepoint/dev/schema/field-element-field). Note that providing the ID attribute in the field schemaXml is very important in order to prevent the field from being created multiple times if the script is run more than once. +Enables defining lookup fields and their dependent lists element using Collaborative Application Markup Language (CAML). For reference, see [Field element (Field)](/sharepoint/dev/schema/field-element-field). Providing the ID attribute in the field schemaXml is important in order to prevent the field from being created multiple times if the script is run more than once. #### JSON value -- **schemaXml** – The CAML block to define the field. -- **targetListName** – The name that identifies the list this lookup field is referencing. Provide either this or targetListUrl. -- **targetListUrl** – A web-relative URL that identifies the list this lookup field is referencing. Provide either this or targetListName. -- **addToDefaultView** – **True** if the field will be added to the default view; otherwise, **false**. +- `schemaXml`: The CAML block to define the field. +- `targetListName`: The name that identifies the list this lookup field is referencing. Provide either this or targetListUrl. +- `targetListUrl`: A web-relative URL that identifies the list this lookup field is referencing. Provide either this or targetListName. +- `addToDefaultView`: **True** if the field will be added to the default view; otherwise, **False**. #### Example @@ -191,58 +211,58 @@ Enables defining lookup fields and their dependent lists element using Collabora "targetListName": "Contoso Project Master" } ``` + ### addSiteColumn Subaction to add a previously defined site column directly to a list (existing or created through the site script). #### JSON value -- **internalName** – The internal name of the site column to add. -- **addToDefaultView** – Optional attribute that defaults to false. If true, the newly added field will also be added to the default view. - +- `internalName`: The internal name of the site column to add. +- `addToDefaultView`: Optional attribute that defaults to **False**. If **True**, the newly added field will also be added to the default view. #### Example ```json { - "verb": "addSiteColumn", - "internalName": "siteColumnUser", - "addToDefaultView": true + "verb": "addSiteColumn", + "internalName": "siteColumnUser", + "addToDefaultView": true } ``` - ### addSPView Defines and adds a view to the list. Use this action to specify the desired columns and how you want the list items displayed (using a CAML query). Action properties allow you to specify row limits, and whether the view is paged and recurses over items in nested folders. You can also designate your constructed view as the default. #### JSON value -- **name** – The name of the view. -- **viewFields** – An array of the internal names of the fields in your view. -- **query** – A CAML query string that contains the `where` clause for the view's query. See [CAML schemas] (https://docs.microsoft.com/sharepoint/dev/schema/collaborative-application-markup-language-caml-schemas). -- **rowLimit** – The row limit of the view. -- **isPaged** – Specifies whether the view is paged. -- **makeDefault** – If **true**, the view will be made the default for the list; otherwise, **false**. -- **scope** – An optional setting to specify the scope of the view. For more details, see [SPViewScope enumeration](https://msdn.microsoft.com/library/microsoft.sharepoint.spviewscope.aspx). -- **formatterJSON** – An optional settings to specify the JSON formatting for the view +- `name`: The name of the view. +- `viewFields`: An array of the internal names of the fields in your view. +- `query`: A CAML query string that contains the `where` clause for the view's query. See [CAML schemas](/sharepoint/dev/schema/collaborative-application-markup-language-caml-schemas). +- `rowLimit`: The row limit of the view. +- `isPaged`: Specifies whether the view is paged. +- `makeDefault`: If **True**, the view will be made the default for the list; otherwise, **False**. +- `scope`: An optional setting to specify the scope of the view. For more information, see [SPViewScope enumeration](/previous-versions/office/sharepoint-server/ms458474(v=office.15)). +- `formatterJSON`: An optional setting to specify the JSON formatting for the view. + #### Example ```json { - "verb": "addSPView", - "name": "Contoso Projects by Category", - "viewFields": - [ - "ID", - "Title", - "siteColumnUser", - "ProjectCategory" - ], - "query": "", - "rowLimit": 100, - "isPaged": true, - "makeDefault": true + "verb": "addSPView", + "name": "Contoso Projects by Category", + "viewFields": + [ + "ID", + "Title", + "siteColumnUser", + "ProjectCategory" + ], + "query": "", + "rowLimit": 100, + "isPaged": true, + "makeDefault": true } ``` @@ -252,14 +272,14 @@ Removes a view from a list. This action can also be used to remove a view applie #### JSON value -- **name** – The name of the view to remove. +- `name`: The name of the view to remove. #### Example ```json { - "verb": "removeSPView", - "name": "All Items" + "verb": "removeSPView", + "name": "All Items" } ``` @@ -267,20 +287,19 @@ Removes a view from a list. This action can also be used to remove a view applie Adds a content type to the list. Currently these are limited to the default content types included in the site template or ones defined in a script by using the createContentType action. - > [!NOTE] -> Currently we do not support adding enterprise content types. +> Currently we do not support adding enterprise content types. #### JSON value -- **name** – The name of the content type to add. +- `name`: The name of the content type to add. #### Example ```json { - "verb": "addContentType", - "name": "name" + "verb": "addContentType", + "name": "name" } ``` @@ -290,14 +309,14 @@ Removes a content type that was provided by the selected template type. #### JSON value -- **name** – The name of the content type to remove. +- `name`: The name of the content type to remove. #### Example ```json { - "verb": "removeContentType", - "name": "name" + "verb": "removeContentType", + "name": "name" } ``` @@ -307,106 +326,100 @@ Sets column formatting for a field. For more information, see [Use column format #### JSON values -- **fieldDisplayName** – The display name of the field to operate on. -- **formatterJSON** – A JSON object to use as the field CustomFormatter. +- `fieldDisplayName`: The display name of the field to operate on. +- `formatterJSON`: A JSON object to use as the field CustomFormatter. -#### Example +#### Example In this example, we are formatting a number column as a data bar. ```json +{ + "verb": "setSPFieldCustomFormatter", + "fieldDisplayName": "Effort (days)", + "formatterJSON": + { + "debugMode": true, + "elmType": "div", + "txtContent": "@currentField", + "attributes": { + "class": "sp-field-dataBars" + }, + "style": { + "width": { + "operator": "?", + "operands": [ + { + "operator": ">", + "operands": ["@currentField", "20"] + }, + "100%", + { + "operator": "+", + "operands": [ { - "verb": "setSPFieldCustomFormatter", - "fieldDisplayName": "Effort (days)", - "formatterJSON": + "operator": "toString()", + "operands": [ { - "debugMode": true, - "elmType": "div", - "txtContent": "@currentField", - "attributes": { - "class": "sp-field-dataBars" - }, - "style": { - "width": { - "operator": "?", - "operands": [ - { - "operator": ">", - "operands": [ - "@currentField", - "20" - ] - }, - "100%", - { - "operator": "+", - "operands": [ - { - "operator": "toString()", - "operands": [ - { - "operator": "*", - "operands": [ - "@currentField", - 5 - ] - } - ] - }, - "%" - ] - } - ] - } - } + "operator": "*", + "operands": ["@currentField",5] } - } + ] + }, + "%" + ] + } + ] + } + } + } +} ``` ### associateFieldCustomizer -Registers field extension for a list field. For more information on these client-side extensions, see [Build field customizer](https://docs.microsoft.com/sharepoint/dev/spfx/extensions/get-started/building-simple-field-customizer) tutorial. +Registers field extension for a list field. For more information on these client-side extensions, see [Build field customizer](/sharepoint/dev/spfx/extensions/get-started/building-simple-field-customizer) tutorial. #### JSON values -- **internalName** – The internal name of the field to operate on. -- **clientSiteComponentId** – The identifier (GUID) of the extension in the app catalog. This property value can be found in the manifest.json file or in the elements.xml file. -- **clientSiteComponentProperties** – An optional parameter, which can be used to provide properties for the field customizer extension instance. +- `internalName`: The internal name of the field to operate on. +- `clientSiteComponentId`: The identifier (GUID) of the extension in the App Catalog. This property value can be found in the manifest.json file or in the elements.xml file. +- `clientSiteComponentProperties`: An optional parameter, which can be used to provide properties for the field customizer extension instance. -#### Example +#### Example ```json { - "verb": "createSPList", - "listName": "Custom List with Slider Extension", - "templateType": 100, - "subactions": [ - { - "verb": "SetDescription", - "description": "Custom list to illustrate SharePoint site scripting" - }, - { - "verb": "addSPField", - "fieldType": "Text", - "displayName": "Text Field", - "isRequired": false, - "addToDefaultView": true - }, - { - "verb": "addSPField", - "fieldType": "Number", - "displayName": "Number Field", - "internalName": "ElectricSlide", - "addToDefaultView": true, - "isRequired": true - }, - { - "verb": "associateFieldCustomizer", - "internalName": "ElectricSlide", - "clientSideComponentId": "35944670-3111-4482-b152-9e9d1sean9f7", - "clientSideComponentProperties": "{\"sampleText\":\"Yes - added by a site design, what?\"}" - } - ] + "verb": "createSPList", + "listName": "Custom List with Slider Extension", + "templateType": 100, + "subactions": [ + { + "verb": "setDescription", + "description": "Custom list to illustrate SharePoint site scripting" + }, + { + "verb": "addSPField", + "fieldType": "Text", + "displayName": "Text Field", + "isRequired": false, + "addToDefaultView": true + }, + { + "verb": "addSPField", + "fieldType": "Number", + "displayName": "Number Field", + "internalName": "ElectricSlide", + "addToDefaultView": true, + "isRequired": true + }, + { + "verb": "associateFieldCustomizer", + "internalName": "ElectricSlide", + "clientSideComponentId": "35944670-3111-4482-b152-9e9d1sean9f7", + "clientSideComponentProperties": "{\"sampleText\":\"Yes - added by a site template, what?\"}" + } + ] } ``` @@ -416,155 +429,155 @@ Associates a ListViewCommandSet to the list #### JSON values -- **title** – The title of the extension. -- **location** – A required parameter to specify where the command is displayed. Options are: ContextMenu or CommandBar. -- **clientSideComponentId** – The identifier (GUID) of the extension in the app catalog. This property value can be found in the manifest.json file or in the elements.xml file. -- **clientSideComponentProperties** – An optional parameter, which can be used to provide properties for the extension instance. - +- `title`: The title of the extension. +- `location`: A required parameter to specify where the command is displayed. Options are: ClientSideExtension.ListViewCommandSet.ContextMenu or ClientSideExtension.ListViewCommandSet.CommandBar. +- `clientSideComponentId`: The identifier (GUID) of the extension in the App Catalog. This property value can be found in the manifest.json file or in the elements.xml file. +- `clientSideComponentProperties`: An optional parameter, which can be used to provide properties for the extension instance. -#### Example +#### Example ```json { - "verb": "createSPList", - "listName": "CustomList", - "templateType": 100, - "subactions": [ - { - "verb": "SetDescription", - "description": "Custom list to illustrate SharePoint site scripting" - }, - { - "verb": "addSPField", - "fieldType": "Text", - "displayName": "Text Field", - "isRequired": false, - "addToDefaultView": true - }, - { - "verb": "addSPField", - "fieldType": "Number", - "displayName": "Number Field", - "internalName": "ElectricSlide", - "addToDefaultView": true, - "isRequired": true - }, - { - "verb": "associateListViewCommandSet", - "title": "HelloWorld", - "location": "CommandBar" - "clientSideComponentId": "13234283-d6c2-408f-a9ef-31a920c8ae78", - "clientSideComponentProperties": "{\"sampleText\":\"added by a site design\"}" - } - ] + "verb": "createSPList", + "listName": "CustomList", + "templateType": 100, + "subactions": [ + { + "verb": "setDescription", + "description": "Custom list to illustrate SharePoint site scripting" + }, + { + "verb": "addSPField", + "fieldType": "Text", + "displayName": "Text Field", + "isRequired": false, + "addToDefaultView": true + }, + { + "verb": "addSPField", + "fieldType": "Number", + "displayName": "Number Field", + "internalName": "ElectricSlide", + "addToDefaultView": true, + "isRequired": true + }, + { + "verb": "associateListViewCommandSet", + "title": "HelloWorld", + "location": "ClientSideExtension.ListViewCommandSet.CommandBar", + "clientSideComponentId": "13234283-d6c2-408f-a9ef-31a920c8ae78", + "clientSideComponentProperties": "{\"sampleText\":\"added by a site template\"}" + } + ] } ``` ### setTitle -Renames the list. To create a new list with a specific name, instead of using setTitle use the **listName** parameter in the **CreateSPList** action. +Renames the list. To create a new list with a specific name, instead of using setTitle use the `listName` parameter in the `CreateSPList` action. > [!NOTE] -> Using **setTitle** will rename the list, preventing the list from updating if the site design is reapplied. +> Using `setTitle` will rename the list, preventing the list from updating if the site template is reapplied. #### JSON value -- **title** – The title of the new list. +- `title`: The title of the new list. #### Example ```json { - "verb": "setTitle", - "title": "Customers and Orders" + "verb": "setTitle", + "title": "Customers and Orders" } ``` ## Define a new site column -Use the **createSiteColumn** verb to define a new site column that can then be associated to a list directly or by using the addContentType action. +Use the `createSiteColumn` verb to define a new site column that can then be associated to a list directly or by using the addContentType action. #### JSON value -- **fieldType** – The type of column to add. Supported values - like SPField - are Text, Note, Number, Boolean, User, and DateTime. For other data types, refer to the addSPFieldXml script action. -- **internalName** – The internal name of the site column. -- **displayName** – The display name of the site column. -- **isRequired** – **True** if this field is required to contain information; otherwise, **false**. -- **id** – An optional attribute. If provided, specifies the id of the field. It needs to be a unique, randomly generated GUID. Providing a value for this is strongly recommended to ensure the field is not added multiple times if the script is re-run. -- **group** – An optional attribute to designate the column group. -- **enforceUnique** – An optional attribute that defaults to **false**. If **true**, all values for this field must be unique. +- `fieldType`: The type of column to add. Supported values - like SPField - are Text, Note, Number, Boolean, User, and DateTime. For other data types, refer to the addSPFieldXml script action. +- `internalName`: The internal name of the site column. +- `displayName`: The display name of the site column. +- `isRequired`: **True** if this field is required to contain information; otherwise, **False**. +- `id`: An optional attribute. If provided, specifies the id of the field. It needs to be a unique, randomly generated GUID. Providing a value for this is recommended to ensure the field isn't added multiple times if the script is rerun. +- `group`: An optional attribute to designate the column group. +- `enforceUnique`: An optional attribute that defaults to **False**. If **True**, all values for this field must be unique. #### Example ```json { - "verb": "createSiteColumn", - "fieldType": "User", - "internalName": "siteColumn4User", - "displayName": "Project Owner", - "isRequired": false, - "id": "181c4370-cdae-471b-9499-730046e55b75" + "verb": "createSiteColumn", + "fieldType": "User", + "internalName": "siteColumn4User", + "displayName": "Project Owner", + "isRequired": false, + "id": "181c4370-cdae-471b-9499-730046e55b75" } ``` -Use the **createSiteColumnXml** verb to define a new site column for those complex data types not supported by createSiteColumn. These columns can then be associated to a list directly or by using the addContentType action. Note that providing the ID attribute in the field schemaXml is very important in order to prevent the field from being created multiple times if the script is run more than once. +Use the `createSiteColumnXml` verb to define a new site column for those complex data types not supported by createSiteColumn. These columns can then be associated to a list directly or by using the addContentType action. Providing the ID attribute in the field schemaXml is important in order to prevent the field from being created multiple times if the script is run more than once. #### JSON value -- **schemaXml** – The CAML block to define the field. -- **pushChanges** – Indicates whether this change should be pushed to lists that already reference this field. Defaults to **true**. +- `schemaXml`: The CAML block to define the field. +- `pushChanges`: Indicates whether this change should be pushed to lists that already reference this field. Defaults to **True**. #### Example ```json { - "verb": "createSiteColumnXml", - "schemaXml": "In ProgressIn ProgressIn ReviewDoneHas Issues" + "verb": "createSiteColumnXml", + "schemaXml": "In ProgressIn ProgressIn ReviewDoneHas Issues" } ``` - ## Define a new content type -Use **createContentType** to define a new content type that can then be associated to a list by using the addContentType action. +Use **createContentType** to define a new content type that can then be associated to a list by using the addContentType action. #### JSON value > [!NOTE] > When referencing the content type ID, only one of the three references are required - ID, parentName, or parentId. -- **name** – The name of the content type to create. -- **description** – The optional description of the content type. -- **parentName** – Name of the parent content type. -- **parentId** – ID of the parent content type. -- **id** – ID of the content type. -- **hidden** – Specifies whether the content type is visible or hidden. -- **subactions** – Specifies subactions to run on the content type. These are used to designate the site columns to add. +- `name`: The name of the content type to create. +- `description`: The optional description of the content type. +- `parentName`: Name of the parent content type. +- `parentId`: ID of the parent content type. +- `id`: ID of the content type. +- `hidden`: Specifies whether the content type is visible or hidden. +- `group`: Group of the content type. +- `subactions`: Specifies subactions to run on the content type. These are used to designate the site columns to add. #### Example ```json { - "verb": "createContentType", - "name": "Contoso Projects", - "description": "custom list content type", - "parentName": "Item", - "hidden": false, - "subactions": - [ - { - "verb": "addSiteColumn", - "internalName": "siteColumn1Text" - }, - { - "verb": "addSiteColumn", - "internalName": "siteColumn2Number" - }, - { - "verb": "addSiteColumn", - "internalName": "siteColumn3Note" - } - ] + "verb": "createContentType", + "name": "Contoso Projects", + "description": "custom list content type", + "parentName": "Item", + "hidden": false, + "group": "Contoso", + "subactions": + [ + { + "verb": "addSiteColumn", + "internalName": "siteColumn1Text" + }, + { + "verb": "addSiteColumn", + "internalName": "siteColumn2Number" + }, + { + "verb": "addSiteColumn", + "internalName": "siteColumn3Note" + } + ] } ``` @@ -574,130 +587,130 @@ Subaction to add a previously defined site column directly to a content type (ex #### JSON value -- **internalName** – The internal name of the site column to add. +- `internalName`: The internal name of the site column to add. #### Example ```json { - "verb": "addSiteColumn", - "internalName": "siteColumnUser" + "verb": "addSiteColumn", + "internalName": "siteColumnUser" } ``` ### removeSiteColumn -Subaction to remove a site column from a list or content type. +Subaction to remove a site column from a list or content type. #### JSON value -- **internalName** – The internal name of the site column to remove. +- `internalName`: The internal name of the site column to remove. #### Example ```json { - "verb": "removeSiteColumn", - "internalName": "siteColumnUser" + "verb": "removeSiteColumn", + "internalName": "siteColumnUser" } ``` ## Add a navigation link -Use the **addNavLink** verb to add a new navigation link to the site QuickLaunch or Hub navigation. +Use the `addNavLink` verb to add a new navigation link to the site QuickLaunch or Hub navigation. #### JSON values -- **url** – The url of the link to add. -- **displayName** – The display name of the link. -- **navComponent** – The component where to add the link, QuickLaunch, Hub or Footer. The default is **QuickLaunch**. -- **isWebRelative** – **true** if the link is web relative; otherwise, **false**. The default is **false**. -- **parentDisplayName** – An optional parameter. If provided, it makes this navigation link a child (sub link) of the navigation link with this displayName. If both this and parentUrl are provided, it searches for a link that matches both to be the parent. -- **parentUrl** – An optional parameter. If provided, it makes this navigation link a child (sub link) of the navigation link with this url. If both this and parentDisplayName are provided, it searches for a link that matches both to be the parent. -- **isParentUrlWebRelative** – An optional parameter. **true** if the link is web relative; otherwise, **false**. The default is **false**. +- `url`: The URL of the link to add. +- `displayName`: The display name of the link. +- `navComponent`: The component where to add the link, QuickLaunch, Hub, or Footer. The default is **QuickLaunch**. +- `isWebRelative`: **True** if the link is web relative; otherwise, **False**. The default is **False**. +- `parentDisplayName`: An optional parameter. If provided, it makes this navigation link a child (sub link) of the navigation link with this displayName. If both this and parentUrl are provided, it searches for a link that matches both to be the parent. +- `parentUrl`: An optional parameter. If provided, it makes this navigation link a child (sub link) of the navigation link with this URL. If both this and parentDisplayName are provided, it searches for a link that matches both to be the parent. +- `isParentUrlWebRelative`: An optional parameter. **True** if the link is web relative; otherwise, **False**. The default value is **False**. #### Example > [!NOTE] -> If you add a link to a nested site item such as a list, be sure to add the path reference from the root. +> If you add a link to a nested site item such as a list, be sure to add the path reference from the root. ```json { - "verb": "addNavLink", - "url": "/Customer Event Collateral", - "displayName": "Event Collateral", - "navComponent":"Hub", - "isWebRelative": true + "verb": "addNavLink", + "url": "/Customer Event Collateral", + "displayName": "Event Collateral", + "navComponent":"Hub", + "isWebRelative": true }, { - "verb": "addNavLink", - "url": "/Lists/Project Activities", - "displayName": "Project Activities", - "isWebRelative": true - }, - { "verb": "addNavLink", - "url": "https://docs.microsoft.com/sharepoint/dev/declarative-customization/site-design-overview", - "displayName": "SharePoint Site Design Overview", - "parentDisplayName": "Documents" - }, - { - "verb": "addNavLink", - "url": "https://docs.microsoft.com/sharepoint/dev/declarative-customization/site-design-json-schema#add-a-navigation-link", - "displayName": "About Site Footer", - "navComponent":"Footer" - }, - { - "verb": "addNavLink", - "url": "http://linkless.header/", - "displayName": "Linkless Heading", - "isWebRelative": false - } + "url": "/Lists/Project Activities", + "displayName": "Project Activities", + "isWebRelative": true + }, +{ + "verb": "addNavLink", + "url": "https://learn.microsoft.com/sharepoint/dev/declarative-customization/site-design-overview", + "displayName": "SharePoint Site Design Overview", + "parentDisplayName": "Documents" +}, +{ + "verb": "addNavLink", + "url": "https://learn.microsoft.com/sharepoint/dev/declarative-customization/site-design-json-schema#add-a-navigation-link", + "displayName": "About Site Footer", + "navComponent":"Footer" +}, +{ + "verb": "addNavLink", + "url": "", + "displayName": "Linkless Heading", + "isWebRelative": false +} ``` ## Remove a navigation link -Use the **removeNavLink** verb to remove a navigation link from the site. +Use the `removeNavLink` verb to remove a navigation link from the site. #### JSON values -- **url** – The url of the link to remove. -- **displayName** – The display name of the link. -- **navComponent** – The component where to remove the link from, QuickLaunch, Hub or Footer. The default is **QuickLaunch**. -- **isWebRelative** – **True** if the link is web relative; otherwise, **false**. +- `url`: The URL of the link to remove. +- `displayName`: The display name of the link. +- `navComponent`: The component where to remove the link from, QuickLaunch, Hub, or Footer. The default is **QuickLaunch**. +- `isWebRelative`: **True** if the link is web relative; otherwise, **False**. #### Example > [!NOTE] -> This action can be used to remove site links added by the collaboration and communication site templates (for example, "home", "documents", "pages", "conversations", etc.). - +> This action can be used to remove site links added by the collaboration and communication site templates (for example, "home", "documents", "pages", and "conversations"). ```json { - "verb": "removeNavLink", - "displayName": "Home", - "isWebRelative": true + "verb": "removeNavLink", + "displayName": "Home", + "isWebRelative": true }, { - "verb": "removeNavLink", - "displayName": "Pages", - "isWebRelative": true + "verb": "removeNavLink", + "displayName": "Pages", + "isWebRelative": true }, { - "verb": "removeNavLink", - "displayName": "Conversations", - "isWebRelative": true + "verb": "removeNavLink", + "displayName": "Conversations", + "isWebRelative": true }, { - "verb": "removeNavLink", - "url": "/_layouts/15/groupstatus.aspx?Target=TEAM", - "displayName": "Teams", - "isWebRelative": true + "verb": "removeNavLink", + "url": "/_layouts/15/groupstatus.aspx?Target=TEAM", + "displayName": "Teams", + "isWebRelative": true } ``` #### Handle special characters -The sites created in other languages than English may contain special characters. Use UTF-8 encoding to read the JSON content containing special characters. + +The sites created in other languages than English may contain special characters. Use UTF-8 encoding to read the JSON content containing special characters. ```PowerShell Get-Content '\site-script.json' -Raw -Encoding UTF8 @@ -705,40 +718,43 @@ Get-Content '\site-script.json' -Raw -Encoding U ## Apply a theme -Use the **applyTheme** verb to add a custom theme to the site. For more information about how to construct and upload these themes, see [SharePoint site theming](site-theming/sharepoint-site-theming-overview.md). Note that this site action only works for applying custom themes; to apply one of our in-product SharePoint themes, create a copy as a custom one and reference that one. +Use the `applyTheme` verb to add a custom theme to the site. For more information about how to construct and upload these themes, see [SharePoint site theming](site-theming/sharepoint-site-theming-overview.md). This site action only works for applying custom themes; to apply one of our in-product SharePoint themes, create a copy as a custom one and reference that one. + +> [!NOTE] +> This action is automatically blocked for [channel sites](/sharepoint/teams-connected-sites). #### JSON value -- **themeName** – The name of the theme to apply. +- `themeName`: The name of the theme to apply. #### Example ```json { - "verb": "applyTheme", - "themeName": "Blue Yonder" + "verb": "applyTheme", + "themeName": "Blue Yonder" } ``` - +> [!TIP] +> The article [Calling Power Automate from a site script](/sharepoint/dev/declarative-customization/site-design-trigger-flow-tutorial) provides an end-to-end example. + #### JSON values -- **url** – A trigger URL of the flow. -- **name** – The name of the flow. -- **parameters** – An optional set of parameters to pass into the flow. +- `url`: A trigger URL of the flow. +- `name`: The name of the flow. +- `parameters`: An optional set of parameters to pass into the flow. #### Example ```json { - "verb": "triggerFlow", - "url": "
", - "name": "Record and tweet site creation event", - "parameters": { - "event": "Microsoft Event", - "product": "SharePoint" - } + "verb": "triggerFlow", + "url": "", + "name": "Record and tweet site creation event", + "parameters": { + "event": "Microsoft Event", + "product": "SharePoint" + } } ``` ## Configure regional settings -Use the **setRegionalSettings** action to configure the regional settings of the site (/_layouts/15/regionalsetng.aspx). +> [!NOTE] +> This action is automatically blocked for [channel sites](/sharepoint/teams-connected-sites). + +Use the `setRegionalSettings` action to configure the regional settings of the site (*/_layouts/15/regionalsetng.aspx*). #### JSON values -- **timeZone** – A number specifying the time zone. For a list of permissible values, see https://msdn.microsoft.com/library/microsoft.sharepoint.spregionalsettings.timezones.aspx -- **locale** – A number specifying the culture LCID. For a list of permissible values, see https://msdn.microsoft.com/library/ms912047(v=winembedded.10).aspx -- **sortOrder** – A number specifying the sort order. For a list of permissible values, see https://msdn.microsoft.com/library/microsoft.sharepoint.spregionalsettings.collation.aspx -- **hourFormat** – Specifies whether the site should use 12-hour or 24-hour time format. +- `timeZone`: A number specifying the time zone. For a list of permissible values, see [SPRegsionalSettings.TimeZones](/previous-versions/office/sharepoint-server/ms453853(v=office.15)) +- `locale`: A number specifying the culture LCID. For a list of permissible values, see [Microsoft Locale ID Values](/previous-versions/windows/embedded/ms912047(v=winembedded.10)) +- `sortOrder`: A number specifying the sort order. For a list of permissible values, see [SPRegionalSettings.Collation](/previous-versions/office/sharepoint-server/ms367805(v=office.15)) +- `hourFormat`: Specifies whether the site should use 12-hour or 24-hour time format. #### Example ```json { - "verb": "setRegionalSettings", - "timeZone": 2, /* Greenwich Mean Time */ - "locale": 1050, /* Croatia */ - "sortOrder": 6, /* Croatian */ - "hourFormat": "24" + "verb": "setRegionalSettings", + "timeZone": 2, /* Greenwich Mean Time */ + "locale": 1050, /* Croatia */ + "sortOrder": 6, /* Croatian */ + "hourFormat": "24" } ``` - ## Add users (principals) to SharePoint Groups -Use the **addPrincipalToSPGroup** action to manage addition of users and groups to select default SharePoint groups. For more information, see [Understanding SharePoint Groups](https://support.office.com/article/Understanding-SharePoint-groups-94D9B261-161E-4ACE-829E-ECA1C8CD2EB8). This action can be used for licensed users, security groups, and Office 365 Groups. +> [!NOTE] +> This action is automatically blocked for [channel sites](/sharepoint/teams-connected-sites). + +Use the `addPrincipalToSPGroup` action to manage addition of users and groups to select default SharePoint groups. For more information, see [Understanding SharePoint Groups](https://support.office.com/article/Understanding-SharePoint-groups-94D9B261-161E-4ACE-829E-ECA1C8CD2EB8). This action can be used for licensed users, security groups, and Microsoft 365 groups. #### JSON values -- **principal** – A required parameter to specify the name of the principal (user or group) to add to the SharePoint group. -- **group** – A required parameter to specify the SharePoint group to add the principal to. +- `principal`: A required parameter to specify the name of the principal (user or group) to add to the SharePoint group. +- `group`: A required parameter to specify the SharePoint group to add the principal to. #### Example @@ -964,46 +992,49 @@ Use the **addPrincipalToSPGroup** action to manage addition of users and groups ```json { - "verb": "addPrincipalToSPGroup", - "principal": "sean@contosotravel.onmicrosoft.com", /* user */ - "group": "Owners" -}, + "verb": "addPrincipalToSPGroup", + "principal": "sean@contosotravel.onmicrosoft.com", /* user */ + "group": "Owners" +}, { - "verb": "addPrincipalToSPGroup", - "principal": "travelops", /* sg */ - "group": "Owners" + "verb": "addPrincipalToSPGroup", + "principal": "travelops", /* sg */ + "group": "Owners" }, { - "verb": "addPrincipalToSPGroup", - "principal": "itexecutives", /* mail-enabled sg */ - "group": "Members" + "verb": "addPrincipalToSPGroup", + "principal": "itexecutives", /* mail-enabled sg */ + "group": "Members" }, { - "verb": "addPrincipalToSPGroup", - "principal": "Adventure@contosotravel.onmicrosoft.com", /* o365 group */ - "group": "Visitors" + "verb": "addPrincipalToSPGroup", + "principal": "Adventure@contosotravel.onmicrosoft.com", /* o365 group */ + "group": "Visitors" } ``` ## Manage guest access -Use the **setSiteExternalSharingCapability** action to manage guest access. For more information, see [Manage external sharing for your SharePoint Online environment](https://support.office.com/article/Manage-external-sharing-for-your-SharePoint-Online-environment-C8A462EB-0723-4B0B-8D0A-70FEAFE4BE85). +> [!NOTE] +> This action is automatically blocked for [channel sites](/sharepoint/teams-connected-sites). + +Use the `setSiteExternalSharingCapability` action to manage guest access. For more information, see [Manage external sharing for your SharePoint Online environment](https://support.office.com/article/Manage-external-sharing-for-your-SharePoint-Online-environment-C8A462EB-0723-4B0B-8D0A-70FEAFE4BE85). #### JSON values -- **capability** – A required parameter to specify the sharing option for the site collection. The four options are: Disabled, ExistingExternalUserSharingOnly, ExternalUserSharingOnly, ExternalUserAndGuestSharing +- `capability`: A required parameter to specify the sharing option for the site collection. The four options are: `Disabled`, `ExistingExternalUserSharingOnly`, `ExternalUserSharingOnly`, and `ExternalUserAndGuestSharing`. #### Example ```json { - "verb": "setSiteExternalSharingCapability", - "capability": "Disabled" + "verb": "setSiteExternalSharingCapability", + "capability": "Disabled" } ``` ## See also -- [SharePoint site design and site script overview](site-design-overview.md) +- [SharePoint site template and site script overview](site-design-overview.md) diff --git a/docs/declarative-customization/site-design-o365cli.md b/docs/declarative-customization/site-design-o365cli.md index 2dce12ea2..6282f7491 100644 --- a/docs/declarative-customization/site-design-o365cli.md +++ b/docs/declarative-customization/site-design-o365cli.md @@ -1,51 +1,48 @@ --- -title: SharePoint site design - Office 365 CLI commands -description: Use the Office 365 CLI to create, retrieve, and remove site designs and site scripts. -ms.date: 10/23/2018 -localization_priority: Priority +title: SharePoint site design - CLI for Microsoft 365 commands +description: Use the CLI for Microsoft 365 to create, retrieve, and remove site designs and site scripts. +ms.date: 06/27/2024 +ms.localizationpriority: high --- -# SharePoint site design: Office 365 CLI commands +# SharePoint site design: CLI for Microsoft 365 commands -Use the Office 365 CLI to create, retrieve, update, and remove site designs and site scripts to new and existing modern site collections from any platform. +Use the CLI for Microsoft 365 to create, retrieve, update, and remove site designs and site scripts to new and existing modern site collections from any platform. -> [!NOTE] -> Office 365 CLI is an open-source tool with active community providing support for it. There is no SLA for the open-source tool support from Microsoft. +[!INCLUDE [pnp-o365cli](../../includes/snippets/open-source/pnp-o365cli.md)] ## Getting started -To run the Office 365 CLI commands, you'll need to do the following: +To run the CLI for Microsoft 365 commands, you'll need to do the following: 1. Download and install [NodeJS LTS version](https://nodejs.org/en/) +1. Follow the instructions at [Installing the CLI](https://pnp.github.io/cli-microsoft365/user-guide/installing-cli/) to install the CLI for Microsoft 365 on your machine +1. Follow the instructions at [Logging in to Office 365](https://pnp.github.io/cli-microsoft365/user-guide/connecting-microsoft-365) to connect to your SharePoint tenant. -2. Follow the instructions at [Installing the CLI](https://pnp.github.io/office365-cli/user-guide/installing-cli/) to install the Office 365 CLI on your machine - -3. Follow the instructions at [Logging in to Office 365](https://pnp.github.io/office365-cli/user-guide/connecting-office-365/) to connect to your SharePoint tenant. - -To verify your setup and connection, try using the [sitedesign list](https:/pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-list) command to read the current list of site designs. If the cmdlet runs and returns with no errors, you're ready to proceed. +To verify your setup and connection, try using the [sitedesign list](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-list) command to read the current list of site designs. If the cmdlet runs and returns with no errors, you're ready to proceed. ## Site design commands -The following commands are available for managing site designs and site scripts from the Office 365 CLI: - -- [sitedesign add](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-add) -- [sitedesign apply](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-apply) -- [sitedesign get](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-get) -- [sitedesign list](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-list) -- [sitedesign remove](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-remove) -- [sitedesign set](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-set) -- [sitedesign rights grant](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-rights-grant) -- [sitedesign rights list](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-rights-list) -- [sitedesign rights revoke](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-rights-revoke) -- [sitedesign run list](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-run-list) -- [sitedesign run status get](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-run-status-get) -- [sitedesign task get](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-task-get) -- [sitedesign task list](https://pnp.github.io/office365-cli/cmd/spo/sitedesign/sitedesign-task-list) -- [sitescript add](https://pnp.github.io/office365-cli/cmd/spo/sitescript/sitescript-add) -- [sitescript get](https://pnp.github.io/office365-cli/cmd/spo/sitescript/sitescript-get) -- [sitescript list](https://pnp.github.io/office365-cli/cmd/spo/sitescript/sitescript-list) -- [sitescript remove](https://pnp.github.io/office365-cli/cmd/spo/sitescript/sitescript-remove) -- [sitescript set](https://pnp.github.io/office365-cli/cmd/spo/sitescript/sitescript-set) +The following commands are available for managing site designs and site scripts from the CLI for Microsoft 365: + +- [sitedesign add](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-add) +- [sitedesign apply](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-apply) +- [sitedesign get](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-get) +- [sitedesign list](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-list) +- [sitedesign remove](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-remove) +- [sitedesign set](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-set) +- [sitedesign rights grant](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-rights-grant) +- [sitedesign rights list](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-rights-list) +- [sitedesign rights revoke](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-rights-revoke) +- [sitedesign run list](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-run-list) +- [sitedesign run status get](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-run-status-get) +- [sitedesign task get](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-task-get) +- [sitedesign task list](https://pnp.github.io/cli-microsoft365/cmd/spo/sitedesign/sitedesign-task-list) +- [sitescript add](https://pnp.github.io/cli-microsoft365/cmd/spo/sitescript/sitescript-add) +- [sitescript get](https://pnp.github.io/cli-microsoft365/cmd/spo/sitescript/sitescript-get) +- [sitescript list](https://pnp.github.io/cli-microsoft365/cmd/spo/sitescript/sitescript-list) +- [sitescript remove](https://pnp.github.io/cli-microsoft365/cmd/spo/sitescript/sitescript-remove) +- [sitescript set](https://pnp.github.io/cli-microsoft365/cmd/spo/sitescript/sitescript-set) ## See also diff --git a/docs/declarative-customization/site-design-overview.md b/docs/declarative-customization/site-design-overview.md index 207e98608..701efedc2 100644 --- a/docs/declarative-customization/site-design-overview.md +++ b/docs/declarative-customization/site-design-overview.md @@ -1,303 +1,222 @@ ---- -title: SharePoint site design and site script overview -description: Use SharePoint site scripts and site designs to provide custom configurations to apply when new sites are created. -ms.date: 12/19/2018 -localization_priority: Priority ---- - -# SharePoint site design and site script overview - -> [!NOTE] -> Site designs and site scripts are currently only supported by SharePoint Online. - -Use site designs and site scripts to automate provisioning new or existing modern SharePoint sites that use your own custom configurations. - -When people in your organization create new SharePoint sites, you often need to ensure some level of consistency. For example, you may need proper branding and theming applied to each new site. You may also have detailed site provisioning scripts, such as using the PnP provisioning engine, that need to be applied each time a new site is created. - -This article describes how you can use site designs and site scripts to provide custom configurations to apply when new sites are created. - -## How site designs work - -Site designs are like a template. They can be used each time a new site is created to apply a consistent set of actions. They can also be applied to existing modern sites (group-connected Team and Communication sites). Most actions typically affect the site itself, such as setting the theme or creating lists. But a site design can also include other actions, such as recording the new site URL to a log, or sending a tweet. - -You create site designs and register them in SharePoint to one of the modern template sites: the Team site or the Communication site. You can see how this works in the following steps. - -1. Go to the SharePoint start page on your developer tenant. - -2. Choose **Create site**. - - You'll see the two modern template sites: **Team site** and **Communication site**. - -3. Choose **Communication site**. - -The Communication site has a **Choose a design** box, which comes with the following site designs: - -- Topic -- Showcase -- Blank - -These are the default site designs. For each site design, there is a title, description, and image. - -![Default site design title, description, and image on Communication site template](images/site-designs-listed-on-communication-site-template.png) - -Had you chosen the Team site template, it contains only one default site design named **Team site**. - -For more information about how you can change the default site designs, see [Customize a default site design](customize-default-site-design.md). - -When a site design is selected, SharePoint creates the new site, and runs site scripts for the site design. The site scripts detail the work such as creating new lists or applying a theme. These script actions are run in the background. A notification bar will be displayed, which the site creator can click to view the status of the actions being applied. - -![Notification bar showing application of script actions in progress](images/site-design-notification-bar-in-progress-state.png) - -When the scripts are complete the notification bar message will change - allowing the site creator to either refresh the page to see the results of the applied scripts or to view the site script details. - -![Notification bar showing application of script actions is complete](images/site-design-notification-bar-completed-state.png) - -The site design information panel can be invoked by a site owner at any time to see what site designs have been applied to the site (and their script details) as well as to apply new or updated site designs. - -When the actions in the scripts are completed, SharePoint displays detailed results of those actions in a progress pane. - -![Site Design Information Panel](images/site-design-information-panel-applied-site-designs.png) - -> [!NOTE] -> Site designs can now be applied to previously created modern site collections. For more information, see the [REST API](site-design-rest-api.md) and [PowerShell](site-design-powershell.md) articles. - -## Anatomy of a site script - -Site scripts are JSON files that specify an ordered list of actions to run when creating the new site. The actions are run in the order listed. - -The following example is a script that has two top-level actions. First, it applies a theme that was previously created named **Contoso Explorers**. It then creates a **Customer Tracking** list. - -```json -{ - "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json", - "actions": [ - { - "verb": "applyTheme", - "themeName": "Contoso Explorers" - }, - { - "verb": "createSPList", - "listName": "Customer Tracking", - "templateType": 100, - "subactions": [ - { - "verb": "SetDescription", - "description": "List of Customers and Orders" - }, - { - "verb": "addSPField", - "fieldType": "Text", - "displayName": "Customer Name", - "isRequired": false, - "addToDefaultView": true - }, - { - "verb": "addSPField", - "fieldType": "Number", - "displayName": "Requisition Total", - "addToDefaultView": true, - "isRequired": true - }, - { - "verb": "addSPField", - "fieldType": "User", - "displayName": "Contact", - "addToDefaultView": true, - "isRequired": true - }, - { - "verb": "addSPField", - "fieldType": "Note", - "displayName": "Meeting Notes", - "isRequired": false - } - ] - } - ], - "version": 1 -} -``` - -
- -Each action in a site script is specified by a **verb** value in the JSON. In the previous script, the first action is specified by the **applyTheme** verb. Next, the **createSPList** verb creates the list. Notice that the **createSPList** verb contains its own set of verbs that run additional actions on only the list. - -Available actions include: - -- Creating a new list or library (or modifying the default one created with the site) -- Creating site columns, content types, and configuring other list settings -- Set site branding properties like navigation layout, header layout and header background -- Applying a theme -- Setting a site logo -- Adding links to quick launch or hub navigation -- Triggering a Microsoft Flow -- Installing a deployed solution from the app catalog -- Setting regional settings for the site -- Adding principals (users and groups) to SharePoint roles -- Setting external sharing capability for the site - -For a complete list of available actions and their parameters, see the [JSON schema](https://docs.microsoft.com/sharepoint/dev/declarative-customization/site-design-json-schema). - -> [!NOTE] -> For libraries and lists, use the PowerShell command [Get-SPOSiteScriptFromList](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteScriptFromList?view=sharepoint-ps) to create the site script syntax from an existing SharePoint list. - -Site scripts can be run again on the same site after provisioning. Site scripts are non-destructive, so when they run again, they ensure that the site matches the configuration in the script. - -For example, if the site already has a list with the same name that the site script is creating, the site script will only add missing fields to the existing list. - -We'd previously capped the limit of site script actions to 30. This remains the limit for scripts applied synchronously using the [Invoke-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Invoke-SPOSiteDesign?view=sharepoint-ps) command, but based on customer feedback and support for additional actions we have bumped this limit to 300 actions (or 100,000 characters) when the scripts are applied asynchronously (either through the UI or using the [Add-SPOSiteDesignTask](https://docs.microsoft.com/powershell/module/sharepoint-online/Add-SPOSiteDesignTask?view=sharepoint-ps) command). - -There is also a limit of 100 site scripts and 100 site designs per tenant. - -## Using PowerShell or REST to work with site designs and site scripts - -You can create site designs and site scripts by using PowerShell or the REST API. The following example creates a site script and a site design that uses the site script. - - - -```powershell -C:\> Get-Content 'c:\scripts\site-script.json' ` - -Raw | ` - Add-SPOSiteScript ` - -Title "Contoso theme and list" - -Id : 2756067f-d818-4933-a514-2a2b2c50fb06 -Title : Contoso theme and list -Description : -Content : -Version : 0 - -C:\> Add-SPOSiteDesign ` - -Title "Contoso customer tracking" ` - -WebTemplate "64" ` - -SiteScripts "2756067f-d818-4933-a514-2a2b2c50fb06" ` - -Description "Creates customer list and applies standard theme" -``` - - - -
- -In the previous example, the **Add-SPOSiteScript** cmdlet or **CreateSiteScript** REST API returns a site script id. This is used for the **SiteScripts** parameter in the subsequent call to the **Add-SPOSiteDesign** cmdlet or **CreateSiteDesign** REST API. - -The **WebTemplate** parameter set to the value 64 indicates registering this site design with the Team site template. If you have disabled modern Group creation, then publish your site designs using WebTemplate 1 so that they display for the "Group-less" Team site template. The value 68 would indicate registering with the Communication site template. The **Title** and **Description** parameters are displayed when a user views site designs as they create a new Team site. - -> [!NOTE] -> A site design can run multiple scripts. The script IDs are passed in an array, and they run in the order listed. - -For step-by-step information about creating a site design, see [Get started creating site designs](get-started-create-site-design.md). - -## PnP provisioning and customization using Microsoft Flow - -One action provided by site scripts is the ability to trigger a Microsoft Flow. This allows you to specify any custom action that you need beyond the actions provided natively in site scripts. - -If you use the PnP provisioning engine to automate site creation, you can use a Microsoft Flow to integrate with site designs. You can maintain all your existing provisioning scripts as well as create new custom provisioning scripts by using this technique. - -
- -![Process of triggering a Microsoft Flow](images/process-for-triggering-a-custom-flow.png) - -The process works as follows: - -1. The script instantiates your Microsoft Flow using a URL with additional details. - -2. The flow sends a message to an Azure storage queue that you have configured. - -3. The message triggers a call to an Azure function that you have configured. - -4. The Azure function runs your custom script, such as the PnP provisioning engine, to apply your custom configurations. - -For a step-by-step tutorial about how to configure your own Microsoft Flow with PnP provisioning, see [Build a complete site design using the PnP provisioning engine](site-design-pnp-provisioning.md). - -## Scoping - -You can configure site designs to only appear for specific groups or people in your organization. This is useful to ensure that people only see the site designs intended for them. For example, you might want the accounting department to only see site designs specifically for them. And the accounting site designs may not make sense to show to anyone else. - -By default, a site design can be viewed by everyone when it is created. Scopes are applied by using the **Grant-SPOSiteDesignRights** cmdlet or the **GrantSiteDesignRights** REST API. You can specify the scope by user or a mail-enabled security group. - -The following example shows how to add Nestor (a user at the fictional Contoso site) view rights on a site design. - -```powershell -Grant-SPOSiteDesignRights ` - -Identity 44252d09-62c4-4913-9eb0-a2a8b8d7f863 ` - -Principals "nestorw@contoso.onmicrosoft.com" ` - -Rights View -``` - - - -For more information about working with scopes, see [Scoping access to site designs](site-design-scoping.md). - -## See also - -- [Get started creating site designs](get-started-create-site-design.md) -- [Apply a scope to your site design](site-design-scoping.md) -- [Site design JSON schema](site-design-json-schema.md) -- [PowerShell cmdlets for SharePoint site designs and site scripts](site-design-powershell.md) -- [Site design and site script REST API](site-design-rest-api.md) -- [Site design examples](https://github.com/SharePoint/sp-dev-site-scripts) +--- +title: SharePoint site template and site script overview +description: Use SharePoint site scripts and site templates to provide custom configurations to apply when new sites are created. +ms.date: 01/22/2025 +ms.localizationpriority: high +--- + +# SharePoint site template and site script overview + +> [!NOTE] +> - Site templates and site scripts are currently only supported by SharePoint Online. +> - In previous versions of SharePoint, site templates were called site designs but will be referred to as site templates moving forward. +> - SharePoint has a new site template experience that will be available to all SharePoint users with permission to create SharePoint sites. [Learn more about the new site template experience](https://support.microsoft.com/office/apply-and-customize-sharepoint-site-templates-39382463-0e45-4d1b-be27-0e96aeec8398?ui=en-US&rs=en-US&ad=US). +> - As of today, the site template experience cannot be disabled. +> - Site templates created by your organization and set as the default template will automatically apply when new sites are created but can be updated by the site owner by selecting **Settings** and then **Apply a site template.** +> - Site template version history is not currently available for the new site template experience but will be included in future iterations. + +Use site templates and site scripts to automate the provisioning of new or existing modern SharePoint sites that use your own custom configurations. + +When people in your organization create new SharePoint sites, you often need to ensure some level of consistency. For example, you may need proper branding and theming applied to each new site. You may also have detailed site provisioning scripts, such as using the PnP provisioning engine, that need to be applied each time a new site is created. + +This article describes how you can use site templates and site scripts to provide custom configurations to apply when new sites are created. + +## How site templates work + +Site templates can be used each time a new site is created to apply a consistent set of actions. They can also be applied to existing modern sites (group-connected Team and Communication sites). Most actions typically affect the site itself, such as setting the theme or creating lists. But a site template can also include other actions, such as recording the new site URL to a log or sending a tweet. + +> [!NOTE] +> - Site templates created using custom site scripts will display in the **From your organization** tab in the site template gallery. +> - Custom site templates made by your organization will be displayed in the site template gallery based on the type of site chosen by the user - either a communication site or a team site. Therefore, it is likely users will not see all site templates from your organization in the site template gallery. Soon, users will have the ability to browse all site templates provided by your organization regardless of which type of site was chosen. + +You create site templates and register them in SharePoint to one of the modern template sites: the Team site or the Communication site. You can see how this works in the following steps. + +1. Go to the SharePoint start page on your developer tenant. +1. Choose **Create site**. + + You'll see the two modern template sites: **Team site** and **Communication site**. + +1. Choose the type of site needed. + + - SharePoint will automatically create a communication site using the **Standard communication** site template. + - Had you chosen the default Team site, SharePoint will create a new site using the **Standard team** template. + + For more information about how you can change the default site templates, see [Customize a default site template](customize-default-site-design.md). + +1. Navigate to the **Settings** icon, and select **Apply site template** to review Microsoft-provided site templates based on the type of site you chose in step three. + +When a site template is selected, SharePoint creates the new site and runs site scripts for the site template. The site scripts provide the details for the template such as creating new lists or applying a theme. These script actions are run in the background. When the scripts are complete the page will refresh to display the site script details. + +> [!NOTE] +> Site templates can now be applied to previously created modern site collections. For more information, see the [REST API](site-design-rest-api.md) and [PowerShell](site-design-powershell.md) articles. + +## Anatomy of a site script + +Site scripts are JSON files that specify an ordered list of actions to run when creating the new site. The actions are run in the order listed. + +The following example is a script that has two top-level actions. First, it applies a theme that was previously created named **Contoso Explorers**. It then creates a **Customer Tracking** list. + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json", + "actions": [ + { + "verb": "applyTheme", + "themeName": "Contoso Explorers" + }, + { + "verb": "createSPList", + "listName": "Customer Tracking", + "templateType": 100, + "subactions": [ + { + "verb": "setDescription", + "description": "List of Customers and Orders" + }, + { + "verb": "addSPField", + "fieldType": "Text", + "displayName": "Customer Name", + "isRequired": false, + "addToDefaultView": true + }, + { + "verb": "addSPField", + "fieldType": "Number", + "displayName": "Requisition Total", + "addToDefaultView": true, + "isRequired": true + }, + { + "verb": "addSPField", + "fieldType": "User", + "displayName": "Contact", + "addToDefaultView": true, + "isRequired": true + }, + { + "verb": "addSPField", + "fieldType": "Note", + "displayName": "Meeting Notes", + "isRequired": false + } + ] + } + ] +} +``` + +Each action in a site script is specified by a **verb** value in the JSON. In the previous script, the first action is specified by the **applyTheme** verb. Next, the **createSPList** verb creates the list. Notice that the **createSPList** verb contains its own set of verbs that run additional actions on only the list. + +**Available actions include:** + +- Creating a new list or library (or modifying the default one created with the site) +- Creating site columns, content types, and configuring other list settings +- Set site branding properties like navigation layout, header layout, and header background +- Applying a theme** +- Setting a site logo +- Adding links to quick launch or hub navigation** +- Triggering a Power Automate flow +- Installing a deployed solution from the app catalog +- Setting regional settings for the site** +- Adding principals (users and groups) to SharePoint roles** +- Setting external sharing capability for the site** + +For a complete list of available actions and their parameters, see the [JSON schema](site-design-json-schema.md). + +> [!NOTE] +> +> - Actions marked with ** are automatically blocked for [channel sites](/sharepoint/teams-connected-sites). +> - For libraries and lists, use the PowerShell command [Get-SPOSiteScriptFromList](/powershell/module/sharepoint-online/Get-SPOSiteScriptFromList) to create the site script syntax from an existing SharePoint list. + +Site scripts can be run again on the same site after provisioning. They are non-destructive, so when they are run again, they ensure that the site matches the configuration in the script. + +For example, if the site already has a list with the same name that the site script is creating, the site script will only add missing fields to the existing list. + +We'd previously capped the limit of site script actions to 30. This remains the limit for scripts applied synchronously using the [Invoke-SPOSiteDesign](/powershell/module/sharepoint-online/Invoke-SPOSiteDesign) command, but based on customer feedback and support for additional actions we have bumped this limit to 300 actions (or 100,000 characters) when the scripts are applied asynchronously (either through the UI or using the [Add-SPOSiteDesignTask](/powershell/module/sharepoint-online/Add-SPOSiteDesignTask) command). + +There is also a limit of 100 site scripts and 100 site templates per tenant. + +## Using PowerShell or REST to work with site templates and site scripts + +You can create site templates and scripts using PowerShell or the REST API. The following example creates a site script and a site template that uses the script. + + + +```powershell +C:\> Get-Content 'c:\scripts\site-script.json' ` + -Raw | ` + Add-SPOSiteScript ` + -Title "Contoso theme and list" + +Id : 2756067f-d818-4933-a514-2a2b2c50fb06 +Title : Contoso theme and list +Description : +Content : +Version : 0 + +C:\> Add-SPOSiteDesign ` + -Title "Contoso customer tracking" ` + -WebTemplate "64" ` + -SiteScripts "2756067f-d818-4933-a514-2a2b2c50fb06" ` + -Description "Creates customer list and applies standard theme" +``` + +In the previous example, the **Add-SPOSiteScript** cmdlet or **CreateSiteScript** REST API returns a site script ID. This is used for the **SiteScripts** parameter in the subsequent call to the **Add-SPOSiteDesign** cmdlet or **CreateSiteDesign** REST API. + +| Parameter | Value | Site template type | +| :------------------- | :------------------- |:----------------| +| WebTemplate | 64 | Team site template | +| WebTemplate | 1 | Team site (with group creation disabled) | +| WebTemplate | 68 | Communication site template | +| WebTemplate | 69 | Channel site template | + +For step-by-step information about creating a site template, see [Get started creating site templates.](get-started-create-site-design.md) + +> [!NOTE] +> +> - A site template can run multiple scripts. The script IDs are passed in an array, and they run in the order listed. +> - The former term for site templates may still appear in certain cmdlet and script labels as "site design." + +## PnP provisioning and customization using Power Automate + +One action provided by site scripts is the ability to trigger a Power Automate flow. This allows you to specify any custom action that you need beyond the actions provided natively in site scripts. + +If you use the PnP provisioning engine to automate site creation, you can use a Power Automate flow to integrate with site templates. You can maintain all your existing provisioning scripts as well as create new custom provisioning scripts by using this technique. + +![Process of triggering a Microsoft Flow](images/process-for-triggering-a-custom-flow.png) + +The process works as follows: + +1. The script instantiates your Power Automate flow using a URL with additional details. +1. The flow sends a message to an Azure storage queue that you have configured. +1. The message triggers a call to an Azure function that you have configured. +1. The Azure function runs your custom script, such as the PnP provisioning engine, to apply your custom configurations. + +For a step-by-step tutorial about how to configure your own Power Automate flow with PnP provisioning, see [Build a complete site template using the PnP provisioning engine](site-design-pnp-provisioning.md). + +## Scoping + +You can configure site templates to only appear for specific groups or people in your organization. This is useful to ensure that people only see the site templates intended for them. For example, you might want the accounting department to only see site templates specifically for them. And the accounting site templates may not make sense to show to anyone else. + +By default, a site template can be viewed by everyone when it is created. Scopes are applied by using the **Grant-SPOSiteDesignRights** cmdlet or the **GrantSiteDesignRights** REST API. You can specify the scope by user or a mail-enabled security group. + +The following example shows how to add Nestor (a user at the fictional Contoso site) view rights on a site template. + +```powershell +Grant-SPOSiteDesignRights ` + -Identity 44252d09-62c4-4913-9eb0-a2a8b8d7f863 ` + -Principals "nestorw@onmicrosoft.com" ` + -Rights View +``` + +For more information about working with scopes, see [Scoping access to site templates](site-design-scoping.md). + +## See also + +- [Get started creating site template](get-started-create-site-design.md) +- [Apply a scope to your site template](site-design-scoping.md) +- [Site template JSON schema](site-design-json-schema.md) +- [PowerShell cmdlets for SharePoint site templates and site scripts](site-design-powershell.md) +- [Site template and site script REST API](site-design-rest-api.md) +- [Site template examples](https://github.com/SharePoint/sp-dev-site-scripts) diff --git a/docs/declarative-customization/site-design-pnp-provisioning.md b/docs/declarative-customization/site-design-pnp-provisioning.md index 24995d873..74a7db6ef 100644 --- a/docs/declarative-customization/site-design-pnp-provisioning.md +++ b/docs/declarative-customization/site-design-pnp-provisioning.md @@ -1,70 +1,55 @@ --- title: Calling the PnP provisioning engine from a site script description: Build a complete SharePoint site design using the PnP provisioning engine -ms.date: 11/27/2018 -localization_priority: Priority +ms.date: 08/31/2023 +ms.localizationpriority: high --- # Calling the PnP provisioning engine from a site script -Site designs offer a great way to standardize the look and feel of your site collections. However, you can't do some things with site designs, like add a footer to every page. You can use the PnP provisioning engine to create a template that you can use to provision an Application Customizer to a site. This Application Customizer can then update your page design, for example to register a footer on every page. +> [!NOTE] +> This article uses the newest version of PnP PowerShell that is released in January 2021. As Azure Functions run PowerShell Core, you'll have to use this version of PnP PowerShell in your Azure Function. For more information about this version of PnP PowerShell see https://pnp.github.io/powershell. + +Site designs offer a great way to standardize the look and feel of your site collections. However, you can't do some things with site designs, like add a footer to every page. You can use the PnP provisioning engine to create a template that you can use to provision an Application Customizer to a site. This Application Customizer can then update your page design, for example, to register a footer on every page. This article describes how to create a site design that applies a PnP provisioning template to a site. The template will add an Application Customizer to render a footer. The steps in this article use the following components: - A site design and a site script -- Microsoft Flow +- Power Automate - Azure Queue storage - Azure Functions - A SharePoint Framework (SPFx) solution -- A PnP provisioning template +- A PnP site template - A PnP PowerShell script -- An app ID and app secret with administrative rights on your tenant +- An Azure AD App Registration You'll use these components to trigger the PnP provisioning code after you create the site and apply the site design. -## Set up app-only access to your tenant - -To set up app-only access, you need to have two different pages on your tenant—one on the regular site, and the other on your SharePoint administration site. - -1. Go to following URL in your tenant: `https://[yourtenant].sharepoint.com/_layouts/15/appregnew.aspx` (you can go to any site, but for now pick the root site). - -2. Next to the **Client Id** and **Client Secret** fields, choose the **Generate** button. - -3. Enter a title for your app, such as **Site Provisioning**. - -4. In the **App Domain** box, enter **localhost**. - -5. In the **Redirect URI** box, enter **https://localhost**. - - ![Create app page, showing the Client Id, Client Secret, Title, App Domain, and Redirect URI fields](images/pnpprovisioning-createapponly.png) +[!INCLUDE [pnp-provisioning-engine](../../includes/snippets/open-source/pnp-provisioning-engine.md)] -6. Choose **Create**. +## Set up app-only access to your tenant -7. Copy the values for **Client Id** and **Client Secret** because you will need them later. +We are going to use authentication with a client id and a certificate in this tutorial. -
+1. Create a new self-signed certificate with PnP PowerShell on your computer: -Next, trust the app, so that it has the appropriate access to your tenant: + ```powershell + Register-PnPAzureADApp -ApplicationName "PnPFlowDemo" -Tenant "contoso.onmicrosoft.com" -DeviceLogin -Out . + ``` -1. Go to `https://[yourtenant]-admin.sharepoint.com/_layouts/appinv.aspx` (notice the `-admin` in the URL). -1. In the **App Id** field, paste the **Client ID** that you copied, and choose **Lookup**. -1. In the **Permission Request XML** field, paste the following XML: + Replace **contoso.onmicrosoft.com** with your tenant. - ```xml - - - - ``` + Follow the steps carefully. -1. Choose **Create**. -1. To confirm that you want to trust this app, choose **Trust It**. + As a result of the command a new Azure AD Application will be registered, permissions will be set correctly, and you will have provided consent to use this application in your tenant. Notice that you require write access to the Azure AD for this. +1. Copy the values the cmdlet returns as you will need the pfx file and the AzureAppId value later. ## Create the Azure Queue storage -In this section, you will use Azure Queue storage to receive messages from Microsoft Flow. Every time a message shows up in the Queue storage, an Azure function is triggered to run a PowerShell script. +In this section, you will use Azure Queue storage to receive messages from Power Automate. Every time a message shows up in the Queue storage, an Azure function is triggered to run a PowerShell script. To set up the Azure Queue storage: @@ -77,14 +62,16 @@ To set up the Azure Queue storage: 1. Enter **pnpprovisioningqueue** for the name, or enter your own value; be sure to follow the naming standard. Make note of the queue name; you will need this value when you create the Azure Function. 1. Go to **Access Keys** and note the **Storage Account Name** and the **key1 Key value**. You will need these values when you create the flow. - ## Create the flow -To put a message in the queue, you need to create a flow. +> [!NOTE] +> The **Request** trigger used below is now **Premium** and will therefore require additional licensing. + +To put a message in the queue, you need to create a flow. -1. Go to the [Microsoft Flow](https://flow.microsoft.com) site, sign in, and choose **Create from Blank** at the top of the page. +1. Go to the [Power Automate](https://flow.microsoft.com) site, sign in, and choose **Create from Blank** at the top of the page. 1. Choose **Search hundreds of connectors and triggers** to select your trigger. -1. Search for **Request**, and select **Request - When a HTTP Request is received**. +1. Search for **Request**, and select **Request - When an HTTP Request is received [Premium]**. 1. Enter the following JSON as your request body: ```json @@ -107,7 +94,7 @@ To put a message in the queue, you need to create a flow. } } } - ``` + ``` 1. Select **+ New Step** and choose **Add an action**. 1. Search for **Azure Queues** and select **Azure Queues - Put a message on a queue**. @@ -121,7 +108,7 @@ To put a message in the queue, you need to create a flow. 1. Choose the first step in your flow ('When an HTTP request is received') and copy the URL. 1. Save your flow. -Your flow should look like the following. +Your flow should look like the following: ![Screenshot of a flow named 'When an HTTP request is received', showing the URL, Request body, Queue name, and Message fields](images/pnpprovisioning-flow-overview.png) @@ -135,7 +122,7 @@ $body = "{webUrl:'somesiteurl'}" Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/json" -Body $body ``` -When you go to the main screen of your flow, you will see a run history. If your flow worked correctly, it will show `Succeeded`. +When you go to the main screen of your flow, you'll see a run history. If your flow worked correctly, it will show `Succeeded`. Now go to the queue you just created in Azure and choose **Refresh**. You should see an entry that shows that you correctly invoked the flow. ## Provision the SPFx solution @@ -169,97 +156,84 @@ Copy the following provisioning template XML to a new file and save the file as 1. Go to the [Azure Portal](https://portal.azure.com). 1. Choose **+ Create a resource**. -1. Search for **Function App** and create a new function app. In the **Storage** field, select **Use existing**, and select the storage account that you created earlier. Set the other values as required. -1. Currently Function apps are created with the V2 runtime which does not support PowerShell functions. Change the runtime of the function app to V1 by navigating selecting **Platform features**, **Function app settings** and change the Runtime version from **~2** to **~1**. -1. Create a new function: **Functions** > **New function**. - - ![Screenshot of the Azure portal with the New function option highlighted](images/pnpprovisioning-create-function.png) - -1. Turn on experimental language support: - - ![Screenshot of the Azure portal with the Experimental Language Support switch highlighted](images/pnpprovisioning-experimental-features.png) - -1. Create a new Queue Triggered function based upon PowerShell: - - ![Screenshot of the Azure portal with the new Queue Triggered function highlighted](images/pnpprovisioning-create-function-queue.png) +1. Search for **Function App** and create a new function app. In the **Storage** field, select **Use existing**, and select the storage account that you created earlier. Set the other values as required, but make sure to select **PowerShell Core** as the **Runtime** and select **7.0** as the **Version** -1. Name the function **ApplyPnPProvisioningTemplate**. -1. Enter the name of the queue you created earlier. -1. Choose **Create**. An editor where you can enter PowerShell cmdlets will open. + ![Screenshot of the Azure portal with the Runtime stack and Version fields hightlighted](images/pnpprovisioning-runtime-stack-selection.png) -Next, you'll upload the PnP PowerShell module so that you can use it in the Azure Function. +1. When created, navigate to your new Function App +1. Select **App Files** -## Upload the PnP PowerShell module for your Azure Function + ![Screenshot of the Function App with the App Files entry highlighted in the menu](images/pnpprovisioning-app-files.menu.png) -You'll need to download the PnP PowerShell module so that you can upload it for your Azure Function. +1. In the dropdown menu, select **requirements.psd1** and add a new entry as follows -1. Create a temporary folder on your computer. -1. Launch PowerShell and enter the following: ```powershell - Save-Module -Name SharePointPnPPowerShellOnline -Path [pathtoyourfolder] + # This file enables modules to be automatically managed by the Functions service. + # See https://aka.ms/functionsmanageddependency for additional information. + # + @{ + # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'. + 'Az' = '5.*' + # For the latest supported version, go to 'https://www.powershellgallery.com/packages/PnP.PowerShell'. + 'PnP.PowerShell' = '1.*' + } ``` -The PowerShell module files will download to a folder within the folder that you created. + Save the file. Notice, that if you do no intent to use the Azure PowerShell Cmdlets you can remove that entry from this file. The requirements.psd1 file makes sure that specific PowerShell modules will be available to all functions. At the first execution of the Azure Function these modules will be downloaded and made available. You can also use wildcard references for the version. [See for more information about this file](/azure/azure-functions/functions-reference-powershell?tabs=portal#dependency-management). -Next, upload the files so that your Azure Function can use the module. +1. Create a new Azure Function **Functions** > **Add**: -1. Go to the main page of your Function App and select **Platform Features**. - - ![Screenshot of the Function App with Platform features highlighted](images/pnpprovisioning-platform-features.png) + ![Screenshot of the Azure portal with the New function option highlighted](images/pnpprovisioning-create-function.png) -1. Select **Advanced tools (Kudu)**. +1. Create a new Azure Store Queue Trigger function: - ![Screenshot of Development Tools with Advanced Tools (Kudu) highlighted](images/pnpprovisioning-select-kudu.png) + ![Screenshot of the Azure portal with the new Queue Triggered function highlighted](images/pnpprovisioning-create-function-queue.png) -1. On the main Kudu page, select **Debug Console** and pick either **CMD** or **PowerShell**. -1. Choose the file explorer on the upper part of the page, and go to **site\wwwroot\\[nameofyourazurefunction]**. -1. Create a new folder named **modules**. - - ![Screenshot with the new folder option highlighted](images/pnpprovisioning-kudu-create-folder.png) +1. Name the function **InvokePnPSiteTemplate**. +1. Enter the name of the queue you created earlier. +1. Choose **Add**. A new page opens where you can modify the function. -1. In the modules folder, create another folder called **SharePointPnPPowerShellOnline** and go to that folder. -1. In File Explorer on your computer, go to the folder where you downloaded the PnP PowerShell module files. Open the -**SharePointPnPPowerShellOnline\2.20.1711.0** folder (notice that the version number might be different). -1. Drag and drop all the files from this folder into the folder in Kudu to upload them. +> [!NOTE] +> The Storage account must be in the same region as of Azure Function App, because the resources that talk to one another should be co-located in the same region. This is a requirement for Azure Functions. - ![Screenshot of the Kudu folder with 40 files added](images/pnpprovisioning-module-files-uploaded.png) ## Finish the Azure Function -1. Go back to your Azure Function and expand the files tab to the right. - - ![Screenshot of the View files tab](images/pnpprovisioning-view-files.png) - -1. Select **Upload** and upload the provisioning template file that you created earlier. +1. Go to the Function App main screen and select **Advanced Tools** in the left menu and click **Go**. A new tab will open. +1. Select **PowerShell** from the **Debug Console** menu at the top. +1. Navigate to **site\wwwroot\InvokePnPSiteTemplate** (or **site\wwwroot\[name of your function]**) +1. Drag and drop the earlier created **FlowDemoTemplate.xml** file onto the page. This will upload the file to the folder. +1. Drag and drop the earlier generated **cert.pfx** file onto the page. This will upload the file to the folder. +1. Navigate back to the function and select **Code + Test** to edit the function. 1. Replace the PowerShell script with the following: ```powershell - $in = Get-Content $triggerInput -Raw - Write-Output "Incoming request for '$in'" - Connect-PnPOnline -AppId $env:SPO_AppId -AppSecret $env:SPO_AppSecret -Url $in + param([string] $QueueItem, $TriggerMetadata) + + # Write out the queue message and insertion time to the information log. + Write-Host "PowerShell queue trigger function processed work item: $QueueItem" + Write-Host "Queue item insertion time: $($TriggerMetadata.InsertionTime)" + Connect-PnPOnline -ClientId [insertyourAzureAppIdhere] -CertificatePath D:\home\site\wwwroot\InvokePnPSiteTemplate\cert.pfx -Tenant 'contoso.onmicrosoft.com' -Url $QueueItem Write-Output "Connected to site" - Apply-PnPProvisioningTemplate -Path D:\home\site\wwwroot\ApplyPnPProvisioningTemplate\FlowDemoTemplate.xml + Invoke-PnPSiteTemplate -Path D:\home\site\wwwroot\InvokePnPSiteTemplate\FlowDemoTemplate.xml ``` -Notice that you're using two environment variables: ```SPO_AppId```and ```SPO_AppSecret```. To set those variables, go to the main Function App page in the Azure Portal (the one with the yellow light bolt icon), select **Configuration** and add two new application settings: + Replace **[insertyourAppIdHere]** with the value that the `Register-PnPAzureApp` cmdlet returned for AzureAppId. -1. ```SPO_AppId``` - Set the value to the Client ID you copied in the first step when you created your app on your tenant. -2. ```SPO_AppSecret``` - Set the value to the Client Secret that you copied in the first step when you created your app on your tenant. + Replace **'contoso.onmicrosoft.com'** with your tenant details. ## Create the site design -Open PowerShell and make sure that you have the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588) installed. - -Connect to your tenant using **Connect-SPOService**. +Open PowerShell and connect to your tenant using **Connect-PnPOnline**. ```powershell -Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com +Connect-PnPOnline -Url https://[yourtenant]-admin.sharepoint.com ``` -Now you can get the existing site designs. +Now you can get the existing site designs. ```powershell -Get-SPOSiteDesign +Get-PnPSiteDesign ``` To create a site design, you first need to create a site script. A site design is a container that refers to one or more site scripts. @@ -292,23 +266,19 @@ To create a site design, you first need to create a site script. A site design i ```powershell $script = Get-Clipboard -Raw - Add-SPOSiteScript -Title "Apply PnP Provisioning Template" -Content $script - Get-SPOSiteScript + Add-PnPSiteScript -Title "Apply PnP Site Template" -Content $script + Get-PnPSiteScript ``` 1. You will see a list of one or more site scripts, including the site script you just created. Select the ID of the site script that you created and copy it to the clipboard. 1. Use the following command to create the site design: ```powershell - Add-SPOSiteDesign -Title "Site with footer" -SiteScripts [Paste the ID of the Site Script here] -WebTemplate "64" + Add-PnPSiteDesign -Title "Site with footer" -SiteScriptIds [Paste the ID of the Site Script here] -WebTemplate TeamSite ``` -The **Add-SPOSiteDesign** cmdlet associates the site design with the team site. If you want to associate the design with a communication site, use the value "68". - ## Verify the results -After you created your Azure Queue storage, you created the app ID for app-only access, the Azure Function, and the site design. You then triggered the Microsoft Flow from the site design. +After you created your Azure Queue storage, you created the app ID for app-only access, the Azure Function, and the site design. You then triggered the Power Automate flow from the site design. To test the results, create a new site. In your SharePoint tenant, select **SharePoint** > **Create Site** > **Team Site**. Your new site design should show up as a design option. Notice that the site design is applied after the site is created. If you configured it correctly, your flow will be triggered. You can check the run history of the flow to verify that it ran correctly. Note that the footer might not show up immediately; if you don't see it, wait a minute and reload your site to check again. - - diff --git a/docs/declarative-customization/site-design-pnppowershell.md b/docs/declarative-customization/site-design-pnppowershell.md new file mode 100644 index 000000000..8faccf981 --- /dev/null +++ b/docs/declarative-customization/site-design-pnppowershell.md @@ -0,0 +1,65 @@ +--- +title: SharePoint site design - PnP PowerShell cmdlets +description: Use PnP PowerShell cmdlets to create, retrieve, and remove site designs and site scripts. +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# SharePoint site design: PnP PowerShell cmdlets + +Use PnP PowerShell cmdlets to create, retrieve, update, and remove site designs and site scripts to new and existing modern site collections. + +[!INCLUDE [pnp-powershell](../../includes/snippets/open-source/pnp-powershell.md)] + +## Getting started + +To run the PnP PowerShell cmdlets, you'll need to do the following: + +1. Download and install the PnP PowerShell Module by running: + + ```PowerShell + Install-Module PnP.PowerShell + ``` + +1. Connect to the SharePoint Online Admin Center of your tenant: + + ```PowerShell + Connect-PnPOnline -Url https://tenant-admin.sharepoint.com -Interactive + ``` + +To verify your setup and connection, try using the `Get-PnPSiteScript` cmdlet to read the current list of site scripts. If the cmdlet runs and returns with no errors, you're ready to proceed. + +## Site design cmdlets + +The following cmdlets are available for managing site designs and site scripts from PnP PowerShell: + +- [Add-PnPSiteDesign](https://pnp.github.io/powershell/cmdlets/Add-PnPSiteDesign.html) +- [Add-PnPSiteDesignTask](https://pnp.github.io/powershell/cmdlets/Add-PnPSiteDesignTask.html) +- [Add-PnPSiteScript](https://pnp.github.io/powershell/cmdlets/Add-PnPSiteScript.html) +- [Add-PnPSiteScriptPackage](https://pnp.github.io/powershell/cmdlets/Add-PnPSiteScriptPackage.html) +- [Get-PnPSiteDesign](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteDesign.html) +- [Get-PnPSiteDesignRights](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteDesignRights.html) +- [Get-PnPSiteDesignRun](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteDesignRun.html) +- [Get-PnPSiteDesignRunStatus](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteDesignRunStatus.html) +- [Get-PnPSiteDesignTask](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteDesignTask.html) +- [Get-PnPSiteScript](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteScript.html) +- [Get-PnPSiteScriptFromList](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteScriptFromList.html) +- [Get-PnPSiteScriptFromWeb](https://pnp.github.io/powershell/cmdlets/Get-PnPSiteScriptFromWeb.html) +- [Grant-PnPSiteDesignRights](https://pnp.github.io/powershell/cmdlets/Grant-PnPSiteDesignRights.html) +- [Invoke-PnPSiteDesign](https://pnp.github.io/powershell/cmdlets/Invoke-PnPSiteDesign.html) +- [Remove-PnPSiteDesign](https://pnp.github.io/powershell/cmdlets/Remove-PnPSiteDesign.html) +- [Remove-PnPSiteDesignTask](https://pnp.github.io/powershell/cmdlets/Remove-PnPSiteDesignTask.html) +- [Remove-PnPSiteScript](https://pnp.github.io/powershell/cmdlets/Remove-PnPSiteScript.html) +- [Revoke-PnPSiteDesignRights](https://pnp.github.io/powershell/cmdlets/Revoke-PnPSiteDesignRights.html) +- [Set-PnPSiteDesign](https://pnp.github.io/powershell/cmdlets/Set-PnPSiteDesign.html) +- [Set-PnPSiteScript](https://pnp.github.io/powershell/cmdlets/Set-PnPSiteScript.html) +- [Set-PnPSiteScriptPackage](https://pnp.github.io/powershell/cmdlets/Set-PnPSiteScriptPackage.html) + +## See also + +- [JSON schema reference](site-design-json-schema.md) +- [REST API](site-design-rest-api.md) +- [Apply a scope to your site design](site-design-scoping.md) +- [SharePoint site design and site script overview](site-design-overview.md) +- [SharePoint site design - SharePoint Online Management Shell PowerShell commands](site-design-powershell.md) +- [SharePoint site design - CLI for Microsoft 365 commands](site-design-o365cli.md) diff --git a/docs/declarative-customization/site-design-powershell.md b/docs/declarative-customization/site-design-powershell.md index 4281ac4ed..085f6ac92 100644 --- a/docs/declarative-customization/site-design-powershell.md +++ b/docs/declarative-customization/site-design-powershell.md @@ -1,15 +1,12 @@ --- title: SharePoint site design - PowerShell cmdlets description: Use PowerShell cmdlets to create, retrieve, and remove site designs and site scripts. -ms.date: 10/23/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint site design: PowerShell cmdlets -> [!NOTE] -> Site designs and site scripts have been released to production and are available for general use. - Use PowerShell cmdlets to create, retrieve, update, and remove site designs and site scripts to new and existing modern site collections. ## Getting started @@ -17,35 +14,33 @@ Use PowerShell cmdlets to create, retrieve, update, and remove site designs and To run the PowerShell cmdlets, you'll need to do the following: 1. Download and install the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588). If you already have a previous version of the shell installed, uninstall it first and then install the latest version. +1. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. -2. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. - -To verify your setup, try using the [Get-SPOSiteScript](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteScript?view=sharepoint-ps) cmdlet to read the current list of site scripts. If the cmdlet runs and returns with no errors, you're ready to proceed. +To verify your setup, try using the [Get-SPOSiteScript](/powershell/module/sharepoint-online/Get-SPOSiteScript) cmdlet to read the current list of site scripts. If the cmdlet runs and returns with no errors, you're ready to proceed. ## Site design cmdlets The following cmdlets are available for managing site designs and site scripts from PowerShell: -- [Add-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Add-SPOSiteDesign?view=sharepoint-ps) -- [Add-SPOSiteDesignTask](https://docs.microsoft.com/powershell/module/sharepoint-online/Add-SPOSiteDesignTask?view=sharepoint-ps) -- [Add-SPOSiteScript](https://docs.microsoft.com/powershell/module/sharepoint-online/Add-SPOSiteScript?view=sharepoint-ps) -- [Get-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteDesign?view=sharepoint-ps) -- [Get-SPOSiteDesignRights](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteDesignRights?view=sharepoint-ps) -- [Get-SPOSiteDesignRun](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteDesignRun?view=sharepoint-ps) -- [Get-SPOSiteDesignRunStatus](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteDesignRunStatus?view=sharepoint-ps) -- [Get-SPOSiteDesignTask](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteDesignTask?view=sharepoint-ps) -- [Get-SPOSiteScript](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteScript?view=sharepoint-ps) -- [Get-SPOSiteScriptFromWeb](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteScriptFromWeb?view=sharepoint-ps) -- [Get-SPOSiteScriptFromList](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOSiteScriptFromList?view=sharepoint-ps) -- [Grant-SPOSiteDesignRights](https://docs.microsoft.com/powershell/module/sharepoint-online/Grant-SPOSiteDesignRights?view=sharepoint-ps) -- [Invoke-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Invoke-SPOSiteDesign?view=sharepoint-ps) -- [Remove-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Remove-SPOSiteDesign?view=sharepoint-ps) -- [Remove-SPOSiteDesignTask](https://docs.microsoft.com/powershell/module/sharepoint-online/Remove-SPOSiteDesignTask?view=sharepoint-ps) -- [Remove-SPOSiteScript](https://docs.microsoft.com/powershell/module/sharepoint-online/Remove-SPOSiteScript?view=sharepoint-ps) -- [Revoke-SPOSiteDesignRights](https://docs.microsoft.com/powershell/module/sharepoint-online/Revoke-SPOSiteDesignRights?view=sharepoint-ps) -- [Set-SPOSiteDesign](https://docs.microsoft.com/powershell/module/sharepoint-online/Set-SPOSiteDesign?view=sharepoint-ps) -- [Set-SPOSiteScript](https://docs.microsoft.com/powershell/module/sharepoint-online/Set-SPOSiteScript?view=sharepoint-ps) - +- [Add-SPOSiteDesign](/powershell/module/sharepoint-online/Add-SPOSiteDesign) +- [Add-SPOSiteDesignTask](/powershell/module/sharepoint-online/Add-SPOSiteDesignTask) +- [Add-SPOSiteScript](/powershell/module/sharepoint-online/Add-SPOSiteScript) +- [Get-SPOSiteDesign](/powershell/module/sharepoint-online/Get-SPOSiteDesign) +- [Get-SPOSiteDesignRights](/powershell/module/sharepoint-online/Get-SPOSiteDesignRights) +- [Get-SPOSiteDesignRun](/powershell/module/sharepoint-online/Get-SPOSiteDesignRun) +- [Get-SPOSiteDesignRunStatus](/powershell/module/sharepoint-online/Get-SPOSiteDesignRunStatus) +- [Get-SPOSiteDesignTask](/powershell/module/sharepoint-online/Get-SPOSiteDesignTask) +- [Get-SPOSiteScript](/powershell/module/sharepoint-online/Get-SPOSiteScript) +- [Get-SPOSiteScriptFromWeb](/powershell/module/sharepoint-online/Get-SPOSiteScriptFromWeb) +- [Get-SPOSiteScriptFromList](/powershell/module/sharepoint-online/Get-SPOSiteScriptFromList) +- [Grant-SPOSiteDesignRights](/powershell/module/sharepoint-online/Grant-SPOSiteDesignRights) +- [Invoke-SPOSiteDesign](/powershell/module/sharepoint-online/Invoke-SPOSiteDesign) +- [Remove-SPOSiteDesign](/powershell/module/sharepoint-online/Remove-SPOSiteDesign) +- [Remove-SPOSiteDesignTask](/powershell/module/sharepoint-online/Remove-SPOSiteDesignTask) +- [Remove-SPOSiteScript](/powershell/module/sharepoint-online/Remove-SPOSiteScript) +- [Revoke-SPOSiteDesignRights](/powershell/module/sharepoint-online/Revoke-SPOSiteDesignRights) +- [Set-SPOSiteDesign](/powershell/module/sharepoint-online/Set-SPOSiteDesign) +- [Set-SPOSiteScript](/powershell/module/sharepoint-online/Set-SPOSiteScript) ## See also @@ -53,4 +48,5 @@ The following cmdlets are available for managing site designs and site scripts f - [REST API](site-design-rest-api.md) - [Apply a scope to your site design](site-design-scoping.md) - [SharePoint site design and site script overview](site-design-overview.md) -- [SharePoint site design - Office 365 CLI commands](site-design-o365cli.md) +- [SharePoint site design - PnP PowerShell commands](site-design-pnppowershell.md) +- [SharePoint site design - CLI for Microsoft 365 commands](site-design-o365cli.md) diff --git a/docs/declarative-customization/site-design-rest-api.md b/docs/declarative-customization/site-design-rest-api.md index 831f58e4f..e017ef341 100644 --- a/docs/declarative-customization/site-design-rest-api.md +++ b/docs/declarative-customization/site-design-rest-api.md @@ -1,8 +1,8 @@ --- title: SharePoint site design REST API description: Work with SharePoint site designs through the SharePoint REST interface to perform basic create, read, update, and delete (CRUD) operations. -ms.date: 04/20/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # Site design and site script REST API @@ -15,7 +15,7 @@ The SharePoint Online (and SharePoint 2016 and later on-premises) REST service s Before you get started, make sure that you're familiar with the following: -- [Get to know the SharePoint REST service](../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) +- [Get to know the SharePoint REST service](../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) - [Complete basic operations using SharePoint REST endpoints](../sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints.md) ## REST commands @@ -81,7 +81,7 @@ Creates a new site script. The following example creates a new site script that applies a custom theme. ```javascript -var site_script = +var site_script = { "$schema": "schema.json", "actions": [ @@ -94,7 +94,7 @@ var site_script = "version": 1 }; -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteScript(Title=@title)?@title='Contoso theme script'", site_script); +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteScript(Title=@title)?@title='Contoso theme script'", site_script); ```
@@ -125,7 +125,7 @@ None. The following example gets the site script information for all site scripts. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScripts"); +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScripts"); ```
@@ -170,18 +170,19 @@ Gets the site script syntax for a specific SharePoint site. | IncludeTheme | (Optional) True if custom theme will be extracted; otherwise false. | | IncludeLinksToExportedItems | (Optional) True if navigation links will be extracted; otherwise false. In order to export navigation links pointing to lists, the list needs to be included in the request as well. | ->**Note:** At least one **include** parameter must be provided when using this API, otherwise request fails. +> [!NOTE] +> At least one **include** parameter must be provided when using this API, otherwise request fails. ### Examples Here is an example of retrieving a site script JSON object from the Contoso site collection. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromWeb", { +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromWeb", { "webUrl":"https://contoso.sharepoint.com/", - "info":{ + "info":{ "IncludeBranding":true, - "IncludedLists":[ + "IncludedLists":[ "Lists/Contoso customer list" ], "IncludeRegionalSettings":true, @@ -195,7 +196,8 @@ RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScri Here is an example of the JSON returned after calling **GetSiteScriptFromWeb**. ->**Note:** The response object shown here might be shortened for readability. +> [!NOTE] +> The response object shown here might be shortened for readability. ```json { @@ -265,7 +267,7 @@ Here is an example of the JSON returned after calling **GetSiteScriptFromWeb**. ## GetSiteScriptFromList -Gets the site script syntax for a specific list +Gets the site script syntax for a specific list. ### Parameters @@ -279,7 +281,7 @@ Gets the site script syntax for a specific list Here's an example of retrieving a site script JSON object from the Contoso customer list. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromList", {listUrl: "https://consoso.sharepoint.com/sites/projectgo/Lists/Contoso%20customer%20list"}); +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromList", {listUrl: "https://consoso.sharepoint.com/sites/projectgo/Lists/Contoso%20customer%20list"}); ```
@@ -327,7 +329,7 @@ Gets information about a specific site script. It also returns the JSON of the s | id | The ID of the site script to get information about. | ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptMetadata", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptMetadata", {id:"07702c07-0485-426f-b710-4704241caad9"}); ``` @@ -365,7 +367,7 @@ Updates a site script with new values. In the REST call, all parameters are opti Here's an example of updating an existing site script with a new JSON script and values. ```javascript -var updated_site_script = +var updated_site_script = { "$schema": "schema.json", "actions": [ @@ -378,12 +380,12 @@ var updated_site_script = "version": 2 }; -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.UpdateSiteScript", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.UpdateSiteScript", {updateInfo:{ Id:"07702c07-0485-426f-b710-4704241caad9", - Title:"New Contoso theme", - Description:"Updated Contoso site script", - Version: 2, + Title:"New Contoso theme", + Description:"Updated Contoso site script", + Version: 2, Content: JSON.stringify(updated_site_script)}}); ``` @@ -417,7 +419,7 @@ Deletes a site script. Here's an example of deleting a site script. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.DeleteSiteScript", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.DeleteSiteScript", {id:"07702c07-0485-426f-b710-4704241caad9"}); ``` @@ -432,10 +434,10 @@ Creates a new site design available to users when they create a new site from th | id | The ID of the site design to apply. | |Title | The display name of the site design. | |WebTemplate | Identifies which base template to add the design to. Use the value **64** for the Team site template, and the value **68** for the Communication site template. | -|SiteScripts | An array of one or more site scripts. Each is identified by an ID. The scripts will run in the order listed. | +|SiteScriptIds | An array of one or more site scripts. Each is identified by an ID. The scripts will run in the order listed. | |Description | (Optional) The display description of site design. | |PreviewImageUrl | (Optional) The URL of a preview image. If none is specified, SharePoint uses a generic image. | -|PreviewImageAltText | (Optional) The alt text description of the image for accessibility. | +|PreviewImageAltText | (Optional) The alt text description of the preview image for accessibility. | |IsDefault | (Optional) **True** if the site design is applied as the default site design; otherwise, **false**. For more information see [Customize a default site design](customize-default-site-design.md). | ### Examples @@ -443,7 +445,7 @@ Creates a new site design available to users when they create a new site from th Here's an example of creating a new site design. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteDesign",{ +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.CreateSiteDesign",{ info:{ Title:"Contoso customer tracking", Description:"Creates customer list and applies standard theme", @@ -489,7 +491,7 @@ Applies a site design to an existing site collection. Here's an example of applying a site design to the ProjectGo site collection. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ApplySiteDesign", {siteDesignId: "614f9b28-3e85-4ec9-a961-5971ea086cca", "webUrl":"https://contoso.sharepoint.com/sites/projectgo"}); +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ApplySiteDesign", {"siteDesignId": "614f9b28-3e85-4ec9-a961-5971ea086cca", "webUrl":"https://contoso.sharepoint.com/sites/projectgo"}); ``` ## AddSiteDesignTaskToCurrentWeb @@ -508,7 +510,7 @@ Adds a site design task on the current web to be invoked asynchronously. Here's an example of adding a site design task to the ProjectGo site collection. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.AddSiteDesignTaskToCurrentWeb", {siteDesignId: "614f9b28-3e85-4ec9-a961-5971ea086cca"}); +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.AddSiteDesignTaskToCurrentWeb", {siteDesignId: "614f9b28-3e85-4ec9-a961-5971ea086cca"}); ```
@@ -518,14 +520,14 @@ Gets a list of information about existing site designs. ### Parameters -None +None. ### Examples Here's an example of getting all the site designs. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns"); +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns"); ```
@@ -577,7 +579,7 @@ Gets information about a specific site design. Here's an example of getting information about a specific site design by ID. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignMetadata", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignMetadata", {id:"614f9b28-3e85-4ec9-a961-5971ea086cca"}); ``` @@ -603,10 +605,10 @@ Here is an example of the JSON returned after calling **GetSiteDesignMetadata**. ## UpdateSiteDesign -Updates a site design with new values. In the REST call, all parameters are optional except the site script Id. +Updates a site design with new values. In the REST call, all parameters are optional except the site script Id. -> [!NOTE] -> If you had previously set the IsDefault parameter to **TRUE** and wish it to remain true, you must pass in this parameter again (otherwise it will be reset to **FALSE**). +> [!NOTE] +> If you had previously set the IsDefault parameter to **TRUE** and wish it to remain true, you must pass in this parameter again (otherwise it will be reset to **FALSE**). ### Parameters @@ -618,7 +620,7 @@ Updates a site design with new values. In the REST call, all parameters are opti |SiteScripts | (Optional) A new array of one or more site scripts. Each is identified by an ID. The scripts run in the order listed. | |Description | (Optional) The new display description of the updated site design. | |PreviewImageUrl | (Optional) The new URL of a preview image. | -|PreviewImageAltText | (Optional) The new alt text description of the image for accessibility. | +|PreviewImageAltText | (Optional) The new alt text description of the preview image for accessibility. | |IsDefault | (Optional) **True** if the site design is applied as the default site design; otherwise, **false**. For more information see [Customize a default site design](customize-default-site-design.md). | ### Examples @@ -626,16 +628,16 @@ Updates a site design with new values. In the REST call, all parameters are opti Here's an example that updates every value on an existing site design. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.UpdateSiteDesign", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.UpdateSiteDesign", {updateInfo:{ - Id:"614f9b28-3e85-4ec9-a961-5971ea086cca", - Title:"Contoso customer site", - Description:"Creates site with customer theme and list", - SiteScriptIds:["6b2b79e4-5da3-4352-8565-42a896fabd57","2b997981-258b-4e1e-81ff-f6fbf7235a1f"], + Id:"614f9b28-3e85-4ec9-a961-5971ea086cca", + Title:"Contoso customer site", + Description:"Creates site with customer theme and list", + SiteScriptIds:["6b2b79e4-5da3-4352-8565-42a896fabd57","2b997981-258b-4e1e-81ff-f6fbf7235a1f"], PreviewImageUrl:"https://contoso.sharepoint.com/SiteAssets/customer_site.png", - PreviewImageAltText:"Customer site with list and theme", - WebTemplate:"68", - Version: 7, + PreviewImageAltText:"Customer site with list and theme", + WebTemplate:"68", + Version: 7, IsDefault: false}}); ``` @@ -673,7 +675,7 @@ Deletes a site design. Here's an example of deleting a site design. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.DeleteSiteDesign", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.DeleteSiteDesign", {id:"f9e76746-5076-4bd2-bad3-e611c488fa85"}); ``` @@ -693,7 +695,7 @@ Gets a list of principals that have access to a site design. Here's an example of getting view rights for a specific site design. ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignRights", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignRights", {id:"dc076f7b-6c15-4d76-8f85-948a17f5dd18"}); ``` @@ -739,10 +741,10 @@ Grants access to a site design for one or more principals. ### Examples -Here's an example of granting view rights to a site design for Nestor and Patti (fictional users at Contoso.) +Here's an example of granting view rights to a site design for Nestor and Patti (fictional users at Contoso). ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GrantSiteDesignRights", { +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GrantSiteDesignRights", { "id": "dc076f7b-6c15-4d76-8f85-948a17f5dd18", "principalNames": [ "NestorW@contoso.onmicrosoft.com", "PattiF@contoso.onmicrosoft.com" ], "grantedRights": 1 @@ -762,12 +764,12 @@ Revokes access from a site design for one or more principals. ### Examples -Here's an example of revoking view rights from a site design for Patti (fictional user at Contoso.) +Here's an example of revoking view rights from a site design for Patti (fictional user at Contoso). ```javascript -RestRequest("/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.RevokeSiteDesignRights", +RestRequest("/_api/Microsoft.SharePoint.Utilities.WebTemplateExtensions.SiteScriptUtility.RevokeSiteDesignRights", {id:"5d4756e9-e1f5-42f7-afa7-5fa5aac170aa", - principalNames:["debrab@Contoso.sharepoint.com"] }); + principalNames:["PattiF@contoso.onmicrosoft.com"] }); ``` ## See also diff --git a/docs/declarative-customization/site-design-scoping.md b/docs/declarative-customization/site-design-scoping.md index 1dcfd78c5..3d697e7d1 100644 --- a/docs/declarative-customization/site-design-scoping.md +++ b/docs/declarative-customization/site-design-scoping.md @@ -1,26 +1,29 @@ --- -title: Scoping access to SharePoint site designs -description: Set scope on SharePoint site designs to control who can view and access them. -ms.date: 04/20/2018 -localization_priority: Priority +title: Select audiences for SharePoint site templates +description: Determine which audiences can access certain site templates. +ms.date: 06/28/2022 +ms.localizationpriority: high --- -# Scoping access to site designs +# Scoping access to site templates -Site designs are available to everyone by default. You can also scope site designs so that they are only available to specific users or groups. For example, the accounting department may have specific site designs they use, but it may not make sense to share those site designs with everyone. +Site templates are available to everyone by default. You can also scope site templates so that they are only available to specific users or groups. For example, the accounting department may have specific site designs they use, but it may not make sense to share those site templates with everyone. -This article explains how you can control which users and groups can see specific site designs. +This article explains how you can control which users and groups can see specific site templates. -## Grant rights to a site design +> [!NOTE] +> Users with the SharePoint Admin role assigned will see all site templates, regardless of scoping. + +## Grant rights to a site template -When a site design is first created, it is available to everyone. You can grant **View** rights to the site design. After rights are granted, only the users or groups (principals) specified have access. You can continue granting rights to more principals with subsequent API calls. +When a site template is first created, it is available to everyone. You can grant **View** rights to the site template. After rights are granted, only the users or groups (principals) specified have access. You can continue granting rights to more principals with subsequent API calls. > [!NOTE] -> Scoping is currently only available for mail-enabled security groups and users. We are planning to provide support for Office 365 Groups in the future. +> Scoping is currently only available for mail-enabled security groups and users. We are planning to provide support for Microsoft 365 groups in the future. ## Grant rights to security groups -The following example shows how to scope an existing site design so that only the mail-enabled security group **accounting** can view and use the site design. +The following example shows how to scope an existing site template so that only the mail-enabled security group **accounting** can view and use the site template. ```powershell Grant-SPOSiteDesignRights ` @@ -31,7 +34,7 @@ Grant-SPOSiteDesignRights `
-You might want to create a new site design and grant rights at the same time, as shown in the next example. +You might want to create a new site template and grant rights at the same time, as shown in the next example. ```powershell Add-SPOSiteDesign ` @@ -47,7 +50,7 @@ Add-SPOSiteDesign ` ## Grant rights to users -The following example shows how to grant view rights on a site design to Nestor (a user at the fictional Contoso site). +The following example shows how to grant view rights on a site template to Nestor (a user at the fictional Contoso site). ```powershell PS C:\> Grant-SPOSiteDesignRights ` @@ -56,7 +59,7 @@ PS C:\> Grant-SPOSiteDesignRights ` -Rights View ``` -## View rights assigned to a site design +## View rights assigned to a site template To view rights, use the **Get-SPOSiteDesignRights** cmdlet. The following example shows how to use this cmdlet and a response in the case where only Nestor has view rights. @@ -70,16 +73,16 @@ DisplayName PrincipalName Rights Nestor Wilke i:0#.f|membership|nestorw@contoso.onmicrosoft.com View ``` -## Revoke rights from a site design +## Revoke rights from a site template -You can revoke rights for any principal. If you revoke view rights for all principles, the site design will again be available to everyone. +You can revoke rights for any principal. If you revoke view rights for all principles, the site template will again be available to everyone. The following example revokes access for the accounting mail-enabled security group and Nestor. ```powershell Revoke-SPOSiteDesignRights ` -Identity db752673-18fd-44db-865a-aa3e0b28698e ` - -Principals ("accounting@contoso.sharepoint.com","nestorw@spdfcontosodemo2.onmicrosoft.com") ` + -Principals ("accounting@contoso.sharepoint.com","nestorw@contoso.onmicrosoft.com") ` ``` ## See also diff --git a/docs/declarative-customization/site-design-trigger-flow-tutorial.md b/docs/declarative-customization/site-design-trigger-flow-tutorial.md index 74e10899a..285da5ad0 100644 --- a/docs/declarative-customization/site-design-trigger-flow-tutorial.md +++ b/docs/declarative-customization/site-design-trigger-flow-tutorial.md @@ -1,167 +1,151 @@ --- title: Using site designs and Power Automate to track site creation requests description: Invoke a Power Automate flow using the site script triggerFlow action to capture the site creation event and build a site directory. This tutorial is intended to illustrate a simple example of using site designs and Power Automate. -ms.date: 11/25/2019 -localization_priority: Priority +ms.date: 06/05/2024 +ms.localizationpriority: high --- # Calling Power Automate from a site script Site designs are a powerful extensibility mechanism for customizing - and standardizing - the look and feel of your site collections. One of the script actions - **triggerFlow** - can be used to call custom solutions to apply configurations we don't support natively. Power Automate flows can also be used for business automation - in this case, used with site designs to track the creation of sites! -This article describes how to build a simple site directory using a site design and Power Automate. Whenever a site is created using this site design, details of the site are captured and written to a SharePoint list. +This article describes how to build a simple site directory using a site design and Power Automate. Whenever a site is created using this site design, details of the site are captured and written to a SharePoint list. The steps in this article illustrate the following components: -- A SharePoint list +- A SharePoint list - A site design and a site script - Power Automate -You'll first create the SharePoint list and then it will be referenced in your Power Automate flow - which will be triggered by the site design applied after the site is created. +You'll first create the SharePoint list and then it will be referenced in your Power Automate flow - which will be triggered by the site design applied after the site is created. ## Create your site directory list -You need to first set up the list that will be used to record all the sites created using this site design. +You need to first set up the list that will be used to record all the sites created using this site design. -1. Select a site collection to host your list. - -2. Create a new list named "Site Directory" - -3. Configure the following fields: - -- webUrl (Hyperlink or Picture) -- webDescription (Single line of text) -- creatorName (Single line of text) -- creatorEmail (Single line of text) -- createdTimeUTC (Single line of text) +1. Select a site collection to host your list. +1. Create a new list named "Site Directory" +1. Configure the following fields: + - webUrl (Hyperlink or Picture) + - webDescription (Single line of text) + - creatorName (Single line of text) + - creatorEmail (Single line of text) + - createdTimeUTC (Single line of text) ## Create the flow -In order to capture the site creation event and create the corresponding list item, you need to create a flow - which can then be referenced in your site design's site script: +In order to capture the site creation event and create the corresponding list item, you need to create a flow - which can then be referenced in your site design's site script: 1. Go to the [Power Automate](https://flow.microsoft.com) site, sign in, and choose **+ Automated—from blank* at the top of the page. +1. Click **Skip** on the next screen +1. Choose **Search connectors and triggers** to select your trigger +1. Search for **Request**, and then choose **Request - When a HTTP Request is received [PREMIUM]**. **NOTE**: The **Request** trigger is now **PREMIUM** and will therefore require additional licensing. +1. Enter the following JSON as your request body: -2. Click **Skip** on the next screen - -2. Choose **Search connectors and triggers** to select your trigger - -3. Search for **Request**, and then choose **Request - When a HTTP Request is received [PREMIUM]**. **NOTE**: The **Request** trigger is now **PREMIUM** and will therefore require additional licensing. - -4. Enter the following JSON as your request body: - - ``` - { - "type": "object", - "properties": { - "webUrl": { + ```json + { + "type": "object", + "properties": { + "webUrl": { "type": "string" - }, - "parameters": { + }, + "parameters": { "type": "object", "properties": { - "event": { - "type": "string" - }, - "product": { - "type": "string" - } + "event": { + "type": "string" + }, + "product": { + "type": "string" + } } - }, - "webDescription": { - "type": "string" - }, - "creatorName": { + }, + "webDescription": { "type": "string" - }, - "creatorEmail": { + }, + "creatorName": { "type": "string" - }, - "createdTimeUTC": { + }, + "creatorEmail": { + "type": ["string", "null"] + }, + "createdTimeUTC": { "type": "string" + } } - } -} -``` - -5. Select **+ New Step**. - -6. Search for **Create item**, and select **SharePoint - Create item**. - -7. Enter the site address where the list above was created. - -8. Select the "Site Directory" list you created in the previous step. + } + ``` -9. Enter a value for the **Title** field - this will be the same value for each list item. For example: "Contoso Travel: New Project Site Created". +1. Select **+ New Step**. +1. Search for **Create item**, and select **SharePoint - Create item**. +1. Enter the site address where the list above was created. +1. Select the "Site Directory" list you created in the previous step. +1. Enter a value for the **Title** field - this will be the same value for each list item. For example: "Contoso Travel: New Project Site Created". +1. For each field in your list form, add the corresponding element from the Dynamic Content picker. When you are done your action should look something like this: -10. For each field in your list form, add the corresponding element from the Dynamic Content picker. When you are done your action should look something like this: + ![Screenshot of a flow named 'When an HTTP request is received', showing the URL, Request body, Queue name, and Message fields](images/site-directory-flow-configuration.png) -![Screenshot of a flow named 'When an HTTP request is received', showing the URL, Request body, Queue name, and Message fields](images/site-directory-flow-configuration.png) - -11. Choose **Save**. This generates the HTTP Post URL that you will need to copy for your site script `triggerFlow` action. - -14. Choose the first step in your flow ('When an HTTP request is received') and copy the URL. - -15. Save your flow. +1. Choose **Save**. This generates the HTTP Post URL that you will need to copy for your site script `triggerFlow` action. +1. Choose the first step in your flow ('When an HTTP request is received') and copy the URL. +1. Save your flow. ## Create the site design 1. Open PowerShell and make sure that you have the latest [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588) installed. +1. Connect to your tenant using **Connect-SPOService**. -2. Connect to your tenant using **Connect-SPOService**. - - ```powershell + ```powershell Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com - ``` + ``` -3. Now you can get the existing site designs. +1. Now you can get the existing site designs. - ```powershell + ```powershell Get-SPOSiteDesign - ``` - -
+ ``` -To create a site design, you first need to create a site script. A site design is a container that refers to one or more site scripts. + To create a site design, you first need to create a site script. A site design is a container that refers to one or more site scripts. -1. Copy the following JSON code to your clipboard and modify it. Set the `url` property to the value that you copied when you created the flow. The URL looks similar to the following: +1. Copy the following JSON code to your clipboard and modify it. Set the **url** property to the value that you copied when you created the flow. The URL looks similar to the following: - `https://prod-27.westus.logic.azure.com:443/workflows/ef7434cf0d704dd48ef5fb6...oke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun` + ```http + https://prod-27.westus.logic.azure.com:443/workflows/ef7434cf0d704dd48ef5fb6...oke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun + ``` - ```json + ```json { - "$schema": "schema.json", - "actions": [ + "$schema": "schema.json", + "actions": [ { - "verb": "triggerFlow", - "url": "[paste the workflow trigger URL here]", - "name": "Record site creation event", - "parameters": { - "event":"site creation", - "product":"SharePoint Online" - } + "verb": "triggerFlow", + "url": "[paste the workflow trigger URL here]", + "name": "Record site creation event", + "parameters": { + "event": "site creation", + "product": "SharePoint Online" + } } - ] + ] } - ``` + ``` -2. Select the JSON again and copy it again to your clipboard. +1. Select the JSON again and copy it again to your clipboard. +1. Open PowerShell and enter the following to copy the script into a variable and create the site script: -3. Open PowerShell and enter the following to copy the script into a variable and create the site script: - - ```powershell + ```powershell $script = Get-Clipboard -Raw Add-SPOSiteScript -Title "Site Script to record site creation event" -Content $script Get-SPOSiteScript - ``` - -4. You will see a list of one or more site scripts, including the site script you just created. Select the ID of the site script that you created, and copy it to the clipboard. + ``` -5. Use the following command to create the site design: +1. You will see a list of one or more site scripts, including the site script you just created. Select the ID of the site script that you created, and copy it to the clipboard. +1. Use the following command to create the site design: - ```powershell + ```powershell Add-SPOSiteDesign -Title "Record site creation" -Description "The creation of this site will be recorded in the site directory list" -SiteScripts [Paste the ID of the Site Script here] -WebTemplate "64" - ``` + ``` + > [!NOTE] > The **Add-SPOSiteDesign** cmdlet associates the site design with the Team site. If you want to associate the design with a Communication site, use `-WebTemplate "68"`. @@ -171,9 +155,7 @@ To test the results, create a new site. In your SharePoint tenant, select **Shar Your new site design should show up as a design option. Notice that the site design is applied after the site is created. If you configured it correctly, your flow will be triggered. You can check the run history of the flow to verify that it ran correctly. - ## See also - [SharePoint site design and site script overview](site-design-overview.md) - [Calling the PnP provisioning engine from a site script](site-design-pnp-provisioning.md) - diff --git a/docs/declarative-customization/site-theming/sharepoint-site-theming-csom.md b/docs/declarative-customization/site-theming/sharepoint-site-theming-csom.md index 6daee60ec..a15b25f9c 100644 --- a/docs/declarative-customization/site-theming/sharepoint-site-theming-csom.md +++ b/docs/declarative-customization/site-theming/sharepoint-site-theming-csom.md @@ -1,13 +1,13 @@ --- title: SharePoint site theming - CSOM development -description: The SharePoint client-side object model (CSOM) provides access to the SharePoint object model from code that is running locally or on a different server than SharePoint. -ms.date: 04/19/2018 -localization_priority: Priority +description: The SharePoint client-side object model (CSOM) provides access to the SharePoint object model from code that is running locally or on a different server than SharePoint. +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint site theming: CSOM development -The SharePoint client-side object model (CSOM) provides access to the SharePoint object model from code that is running locally or on a different server than SharePoint. +The SharePoint client-side object model (CSOM) provides access to the SharePoint object model from code that is running locally or on a different server than SharePoint. ## Prerequisites @@ -20,7 +20,7 @@ You also need to reference the [Microsoft.SharePointOnline.CSOM](https://www.nug ## CSOM code example -The following example shows how to create a __Microsoft.Online.SharePoint.TenantAdministration.Tenant__ object and call the __GetAllTenantThemes__ method to return a list of themes. +The following example shows how to create a __Microsoft.Online.SharePoint.TenantAdministration.Tenant__ object and call the __GetAllTenantThemes__ method to return a list of themes. > [!NOTE] > * The URL used to create the context object includes the _-admin_ suffix because **TenantAdministration** methods work with the admin site. @@ -80,7 +80,7 @@ public class SPOTheme  ## Applying a theme -There's currently no supported CSOM API to programmatically apply a theme to a specific site. For information on applying custom themes to individual site collections see [SharePoint site design and site script overview](https://docs.microsoft.com/sharepoint/dev/declarative-customization/site-design-overview) +There's currently no supported CSOM API to programmatically apply a theme to a specific site. For information on applying custom themes to individual site collections see [SharePoint site design and site script overview](/sharepoint/dev/declarative-customization/site-design-overview) ## Methods/properties of the Microsoft.Online.SharePoint.TenantAdministration.Tenant class @@ -92,7 +92,7 @@ Add a theme to the tenant. __Namespace:__ Microsoft.Online.SharePoint.TenantAdministration.Tenant
__Parameters:__ string name, string themeJson
-__Return type:__ ClientResult +__Return type:__ ClientResult\ ### DeleteTenantTheme public method @@ -108,7 +108,7 @@ Retrieve all the themes that are currently available in the tenant, including an __Namespace:__ Microsoft.Online.SharePoint.TenantAdministration.Tenant
__Parameters:__ none
-__Return type:__ ClientObjectList +__Return type:__ ClientObjectList\ ### GetTenantTheme public method @@ -131,7 +131,7 @@ Update the settings for an existing theme. __Namespace:__ Microsoft.Online.SharePoint.TenantAdministration.Tenant
__Parameters:__ string name, string themeJson
-__Return type:__ ClientResult +__Return type:__ ClientResult\ ## Methods of the Microsoft.Online.SharePoint.TenantManagement.Tenant class @@ -143,7 +143,7 @@ Add a theme to the tenant. __Namespace:__ Microsoft.Online.SharePoint.TenantManagement.Tenant
__Parameters:__ string name, string themeJson
-__Return type:__ ClientResult +__Return type:__ ClientResult\ ### GetAllTenantThemes public method @@ -151,7 +151,7 @@ Retrieve all the themes that are currently available in the tenant, including an __Namespace:__ Microsoft.Online.SharePoint.TenantManagement.Tenant
__Parameters:__ none
-__Return type:__ ClientObjectList +__Return type:__ ClientObjectList\ ### GetHideDefaultThemes public method @@ -159,7 +159,7 @@ Read the current setting for whether to hide default themes in the theme picker __Namespace:__ Microsoft.Online.SharePoint.TenantManagement.Tenant
__Parameters:__ none
-__Return type:__ ClientResult +__Return type:__ ClientResult\ ### GetTenantTheme public method @@ -183,7 +183,7 @@ Update the settings for an existing theme. __Namespace:__ Microsoft.Online.SharePoint.TenantManagement.Tenant
__Parameters:__ string name, string themeJson
-__Return type:__ ClientResult +__Return type:__ ClientResult\ ## See also @@ -191,4 +191,3 @@ __Return type:__ ClientResult * [SharePoint site theming: JSON schema](sharepoint-site-theming-json-schema.md) * [SharePoint site theming: PowerShell cmdlets](sharepoint-site-theming-powershell.md) * [SharePoint site theming: REST API](sharepoint-site-theming-rest-api.md) - diff --git a/docs/declarative-customization/site-theming/sharepoint-site-theming-json-schema.md b/docs/declarative-customization/site-theming/sharepoint-site-theming-json-schema.md index f99145e6a..db182d93b 100644 --- a/docs/declarative-customization/site-theming/sharepoint-site-theming-json-schema.md +++ b/docs/declarative-customization/site-theming/sharepoint-site-theming-json-schema.md @@ -1,811 +1,633 @@ --- title: SharePoint site theming - JSON schema description: The new SharePoint site theming features use a JSON schema to store color settings and other information about each theme. -ms.date: 04/20/2018 -localization_priority: Priority +ms.date: 08/08/2024 +ms.localizationpriority: high --- # SharePoint site theming: JSON schema The new [SharePoint site theming](sharepoint-site-theming-overview.md) features use a JSON schema to store color settings and other information about each theme. Theme settings are stored in a JSON object that contains the following keys: -* __name__ – The name of the theme, which appears in the theme picker UI and is also used by administrators and developers to refer to the theme in PowerShell cmdlets or calls to the SharePoint REST API. - -* __isInverted__ – This value should be false for light themes and true for dark themes; it controls whether SharePoint uses dark or light theme colors to render text on colored backgrounds. - -* __backgroundImageUri__ – The URI of an optional background image for the theme (value can be blank if no background image). - -* __theme__ – The RGB color settings for the theme, stored as a nested JSON object with the following keys: - - * themePrimary - * themeLighterAlt - * themeLighter - * themeLight - * themeTertiary - * themeSecondary - * themeDarkAlt - * themeDark - * themeDarker - * neutralLighterAlt - * neutralLighter - * neutralLight - * neutralQuaternaryAlt - * neutralQuaternary - * neutralTertiaryAlt - * neutralTertiary - * neutralSecondaryAlt - * neutralSecondary - * neutralPrimaryAlt - * neutralPrimary - * neutralDark - * black - * white - * primaryBackground - * primaryText - * bodyBackground - * bodyText - * disabledBackground - * disabledText - * error - * accent - -The colors in the **theme** element are specified as 6-digit or 3-digit hexadecimal RGB string values. +- **name**: The name of the theme, which appears in the theme picker UI and is also used by administrators and developers to refer to the theme in PowerShell cmdlets or calls to the SharePoint REST API. +- **isInverted**: This value should be false for light themes and true for dark themes; it controls whether SharePoint uses dark or light theme colors to render text on colored backgrounds. +- **backgroundImageUri**: The URI of an optional background image for the theme (value can be blank if no background image). +- **palette**: The RGB color settings for the theme, stored as a nested JSON object with the following keys: + - themePrimary + - themeLighterAlt + - themeLighter + - themeLight + - themeTertiary + - themeSecondary + - themeDarkAlt + - themeDark + - themeDarker + - neutralLighterAlt + - neutralLighter + - neutralLight + - neutralQuaternaryAlt + - neutralQuaternary + - neutralTertiaryAlt + - neutralTertiary + - neutralSecondaryAlt + - neutralSecondary + - neutralPrimaryAlt + - neutralPrimary + - neutralDark + - black + - white + - primaryBackground + - primaryText + - bodyBackground + - bodyText + - disabledBackground + - disabledText + - error + - accent + +The colors in the `palette` element are specified as 6-digit or 3-digit hexadecimal RGB string values. The following is an example of a JSON object that defines a theme. ```json -{  -    name: 'Blue',  -    isInverted: true,  -    backgroundImageUri: '',  -    theme: {  -        themePrimary: "#00bcf2",  -        themeLighterAlt: "#00090c",  -        themeLighter: "#001318",  -        themeLight: "#002630",  -        themeTertiary: "#005066",  -        themeSecondary: "#00abda",  -        themeDarkAlt: "#0ecbff",  -        themeDark: "#44d6ff",  -        themeDarker: "#6cdfff",  -        neutralLighterAlt: "#2e3340",  -        neutralLighter: "#353a49",  -        neutralLight: "#404759",  -        neutralQuaternaryAlt: "#474e62",  -        neutralQuaternary: "#4c546a",  -        neutralTertiaryAlt: "#646e8a",  -        neutralTertiary: "#c8c8c8",  -        neutralSecondaryAlt: "#d0d0d0",  -        neutralSecondary: "#dadada",  -        neutralPrimaryAlt: "#eaeaea",  -        neutralPrimary: "#ffffff",  -        neutralDark: "#f4f4f4",  -        black: "#f8f8f8",  -        white: "#262a35",  -        primaryBackground: "#262a35",  -        primaryText: "#ffffff",  - bodyBackground: "#ffffff"; - bodyText: "#333333"; - disabledBackground: "#f4f4f4"; - disabledText: "#c8c8c8"; - error: "#ff5f5f"; - accent: "#ffb900"; - }  -}  +{ + "name": "Blue", + "isInverted": true, + "backgroundImageUri": "", + "palette": { + "themePrimary": "#00bcf2", + "themeLighterAlt": "#00090c", + "themeLighter": "#001318", + "themeLight": "#002630", + "themeTertiary": "#005066", + "themeSecondary": "#00abda", + "themeDarkAlt": "#0ecbff", + "themeDark": "#44d6ff", + "themeDarker": "#6cdfff", + "neutralLighterAlt": "#2e3340", + "neutralLighter": "#353a49", + "neutralLight": "#404759", + "neutralQuaternaryAlt": "#474e62", + "neutralQuaternary": "#4c546a", + "neutralTertiaryAlt": "#646e8a", + "neutralTertiary": "#c8c8c8", + "neutralSecondaryAlt": "#d0d0d0", + "neutralSecondary": "#dadada", + "neutralPrimaryAlt": "#eaeaea", + "neutralPrimary": "#ffffff", + "neutralDark": "#f4f4f4", + "black": "#f8f8f8", + "white": "#262a35", + "primaryBackground": "#262a35", + "primaryText": "#ffffff", + "bodyBackground": "#ffffff", + "bodyText": "#333333", + "disabledBackground": "#f4f4f4", + "disabledText": "#c8c8c8", + "error": "#ff5f5f", + "accent": "#ffb900" + } +} ``` -
- The SharePoint Framework includes eight built-in themes: six on light backgrounds, and two on dark backgrounds. You might find it useful to create a custom theme by starting from one of the built-in themes and adjusting it to suit your needs. Another option is to use the [Theme Generator tool](https://aka.ms/themedesigner) to build a custom theme. It provides an interactive UI for selecting theme colors, and automatically generates the JSON, SASS, and PowerShell definitions for your custom theme. > [!NOTE] -> The theme generator definitions do not currently include the "error" or "accent" color slots. These can be manually added to your generated definition before uploading to the tenant. +> The theme generator definitions do not currently include the following color slots and key/value pairs: +> +> - "primaryBackground" +> - "primaryText" +> - "bodyBackground" +> - "bodyText" +> - "disabledBackground" +> - "disabledText" +> - "error" +> - "accent" +> +> These can be manually added to your generated definition before uploading to the tenant. ![Theme Generator tool](../../images/theme-generator-tool.png) The following is a summary of the built-in themes, including JSON definitions for the theme colors that you can use as a starting point for customization. +## Teal theme + +The following table shows the color palette used by the Teal theme. + +| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #014446 | black: #000000 | +| themeDark: #025c5f | neutralDark: #212121 | +| themeDarkAlt: #026d70 | neutralPrimary: #333 | +| themePrimary: #03787c | neutralPrimaryAlt: #3c3c3c | +| | neutralSecondary: #666666 | +| | neutralTertiary: #a6a6a6 | +| themeSecondary: #13898d | neutralTertiaryAlt: #c8c8c8 | +| themeTertiary: #49aeb1 | neutralLight: #eaeaea | +| themeLight: #98d6d8 | neutralLighter: #f4f4f4 | +| themeLighter: #c5e9ea | neutralLighterAlt: #f8f8f8 | +| themeLighterAlt: #f0f9fa | white: #fff | + +The following code shows how to define a dictionary in PowerShell for the Teal theme's color palette. + +```powershell +{  + themeDarker: '#014446',  + themeDark: '#025c5f',  + themeDarkAlt: '#026d70',  + themePrimary: '#03787c',  + themeSecondary: '#13898d',  + themeTertiary: '#49aeb1',  + themeLight: '#98d6d8',  + themeLighter: '#c5e9ea',  + themeLighterAlt: '#f0f9fa',  + black: '#000000',  + neutralDark: '#212121',  + neutralPrimary: '#333',  + neutralPrimaryAlt: '#3c3c3c',  + neutralSecondary: '#666666',  + neutralTertiary: '#a6a6a6',  + neutralTertiaryAlt: '#c8c8c8',  + neutralLight: '#eaeaea',  + neutralLighter: '#f4f4f4',  + neutralLighterAlt: '#f8f8f8',  + white: '#fff',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralSecondaryAlt: '#767676',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#4f6bed' +} +``` + ## Red theme The following table shows the color palette used by the Red theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #751b1eblack: #000000
themeDark: #952226neutralDark: #212121
themeDarkAlt: #c02b30neutralPrimary: #333
themePrimary: #d13438neutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
themeSecondary: #d6494dneutralTertiaryAlt: #c8c8c8
themeTertiary: #ecaaacneutralLight: #eaeaea
themeLight: #f6d6d8neutralLighter: #f4f4f4
themeLighter: #faebebneutralLighterAlt: #f8f8f8
themeLighterAlt: #fdf5f5white: #fff
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #751b1e | black: #000000 | +| themeDark: #952226 | neutralDark: #212121 | +| themeDarkAlt: #c02b30 | neutralPrimary: #333 | +| themePrimary: #d13438 | neutralPrimaryAlt: #3c3c3c | +| | neutralSecondary: #666666 | +| | neutralTertiary: #a6a6a6 | +| themeSecondary: #d6494d | neutralTertiaryAlt: #c8c8c8 | +| themeTertiary: #ecaaac | neutralLight: #eaeaea | +| themeLight: #f6d6d8 | neutralLighter:#f4f4f4 | +| themeLighter: #faebeb | neutralLighterAlt: #f8f8f8 | +| themeLighterAlt: #fdf5f5 | white: #fff | The following code shows how to define a dictionary in PowerShell for the Red theme's color palette. + ```powershell {  -    themeDarker: '#751b1e',  -    themeDark: '#952226',  -    themeDarkAlt: '#c02b30',  -    themePrimary: '#d13438',  -    themeSecondary: '#d6494d',  -    themeTertiary: '#ecaaac',  -    themeLight: '#f6d6d8',  -    themeLighter: '#faebeb',  -    themeLighterAlt: '#fdf5f5',  -    black: '#000000',  -    neutralDark: '#212121',  -    neutralPrimary: '#333',  -    neutralPrimaryAlt: '#3c3c3c',  -    neutralSecondary: '#666666',  -    neutralTertiary: '#a6a6a6',  -    neutralTertiaryAlt: '#c8c8c8',  -    neutralLight: '#eaeaea',  -    neutralLighter: '#f4f4f4',  -    neutralLighterAlt: '#f8f8f8',  -    white: '#fff',  -    neutralQuaternaryAlt: '#dadada',  -    neutralQuaternary: '#d0d0d0',  -    neutralSecondaryAlt: '#767676',  -    primaryBackground: '#fff',  -    primaryText: '#333'  + themeDarker: '#751b1e',  + themeDark: '#952226',  + themeDarkAlt: '#c02b30',  + themePrimary: '#d13438',  + themeSecondary: '#d6494d',  + themeTertiary: '#ecaaac',  + themeLight: '#f6d6d8',  + themeLighter: '#faebeb',  + themeLighterAlt: '#fdf5f5',  + black: '#000000',  + neutralDark: '#212121',  + neutralPrimary: '#333',  + neutralPrimaryAlt: '#3c3c3c',  +  neutralSecondary: '#666666',  + neutralTertiary: '#a6a6a6',  + neutralTertiaryAlt: '#c8c8c8',  + neutralLight: '#eaeaea',  + neutralLighter: '#f4f4f4',  + neutralLighterAlt: '#f8f8f8',  + white: '#fff',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralSecondaryAlt: '#767676',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#ca5010' } ``` -
- ## Orange theme The following table shows the color palette used by the Orange theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #6f2d09black: #000000
themeDark: #8d390bneutralDark: #212121
themeDarkAlt: #b5490fneutralPrimary: #333
themePrimary: #ca5010neutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
themeSecondary: #e55c12neutralTertiaryAlt: #c8c8c8
themeTertiary: #f6b28dneutralLight: #eaeaea
themeLight: #fbdac9neutralLighter: #f4f4f4
themeLighter: #fdede4neutralLighterAlt: #f8f8f8
themeLighterAlt: #fef6f1white: #fff
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #6f2d09 | black: #000000 | +| themeDark: #8d390b | neutralDark: #212121 | +| themeDarkAlt: #b5490f | neutralPrimary: #333 | +| themePrimary: #ca5010 | neutralPrimaryAlt: #3c3c3c | +| | neutralSecondary: #666666 | +| | neutralTertiary: #a6a6a6 | +| themeSecondary: #e55c12 | neutralTertiaryAlt: #c8c8c8 | +| themeTertiary: #f6b28d | neutralLight: #eaeaea | +| themeLight: #fbdac9 | neutralLighter: #f4f4f4 | +| themeLighter: #fdede4 | neutralLighterAlt: #f8f8f8 | +| themeLighterAlt: #fef6f1 | white: #fff | The following code shows how to define a dictionary in PowerShell for the Orange theme's color palette. ```powershell {  -    themeDarker: '#6f2d09',  -    themeDark: '#8d390b',  -    themeDarkAlt: '#b5490f',  -    themePrimary: '#ca5010',  -    themeSecondary: '#e55c12',  -    themeTertiary: '#f6b28d',  -    themeLight: '#fbdac9',  -    themeLighter: '#fdede4',  -    themeLighterAlt: '#fef6f1',  -    black: '#000000',  -    neutralDark: '#212121',  -    neutralPrimary: '#333',  -    neutralPrimaryAlt: '#3c3c3c',  -    neutralSecondary: '#666666',  -    neutralTertiary: '#a6a6a6',  -    neutralTertiaryAlt: '#c8c8c8',  -    neutralLight: '#eaeaea',  -    neutralLighter: '#f4f4f4',  -    neutralLighterAlt: '#f8f8f8',  -    white: '#fff',  -    neutralQuaternaryAlt: '#dadada',  -    neutralQuaternary: '#d0d0d0',  -    neutralSecondaryAlt: '#767676',  -    primaryBackground: '#fff',  -    primaryText: '#333'  + themeDarker: '#6f2d09',  + themeDark: '#8d390b',  + themeDarkAlt: '#b5490f',  + themePrimary: '#ca5010',  + themeSecondary: '#e55c12',  + themeTertiary: '#f6b28d',  + themeLight: '#fbdac9',  + themeLighter: '#fdede4',  + themeLighterAlt: '#fef6f1',  + black: '#000000',  + neutralDark: '#212121',  + neutralPrimary: '#333',  + neutralPrimaryAlt: '#3c3c3c',  + neutralSecondary: '#666666',  + neutralTertiary: '#a6a6a6',  + neutralTertiaryAlt: '#c8c8c8',  + neutralLight: '#eaeaea',  + neutralLighter: '#f4f4f4',  + neutralLighterAlt: '#f8f8f8',  + white: '#fff',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralSecondaryAlt: '#767676',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#986f0b' } ``` -
- ## Green theme The following table shows the color palette used by the Green theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #094c23black: #000000
themeDark: #0c602cneutralDark: #212121
themeDarkAlt: #0f7c39neutralPrimary: #333
themePrimary: #10893eneutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
themeSecondary: #14a94eneutralTertiaryAlt: #c8c8c8
themeTertiary: #7aefa7neutralLight: #eaeaea
themeLight: #bff7d5neutralLighter: #f4f4f4
themeLighter: #dffbeaneutralLighterAlt: #f8f8f8
themeLighterAlt: #effdf4white: #fff
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #294903 | black: #000000 | +| themeDark: #386304 | neutralDark: #201f1e | +| themeDarkAlt: #427505 | neutralPrimary: #323130 | +| themePrimary: #498205 | neutralPrimaryAlt: #3b3a39 | +| | neutralSecondary: #605e5c | +| | neutralTertiary: #a19f9d | +| themeSecondary: #5a9117 | neutralTertiaryAlt: #c8c6c4 | +| themeTertiary: #85b44c | neutralLight: #edebe9 | +| themeLight: #bdda9b | neutralLighter: #f3f2f1 | +| themeLighter: #dbebc7 | neutralLighterAlt: #faf9f8 | +| themeLighterAlt: #f6faf0 | white: #fff | The following code shows how to define a dictionary in PowerShell for the Green theme's color palette. ```powershell {  -    themePrimary: '#10893e',  -    themeLighterAlt: '#effdf4',  -    themeLighter: '#dffbea',  -    themeLight: '#bff7d5',  -    themeTertiary: '#7aefa7',  -    themeSecondary: '#14a94e',  -    themeDarkAlt: '#0f7c39',  -    themeDark: '#0c602c',  -    themeDarker: '#094c23',  -    neutralLighterAlt: '#f8f8f8',  -    neutralLighter: '#f4f4f4',  -    neutralLight: '#eaeaea',  -    neutralQuaternaryAlt: '#dadada',  -    neutralQuaternary: '#d0d0d0',  -    neutralTertiaryAlt: '#c8c8c8',  -    neutralTertiary: '#a6a6a6',  -    neutralSecondaryAlt: '#767676',  -    neutralSecondary: '#666666',  -    neutralPrimary: '#333',  -    neutralPrimaryAlt: '#3c3c3c',  -    neutralDark: '#212121',  -    black: '#000000',  -    white: '#fff',  -    primaryBackground: '#fff',  -    primaryText: '#333'  + themePrimary: '#498205',  + themeLighterAlt: '#f6faf0',  + themeLighter: '#dbebc7',  + themeLight: '#bdda9b',  + themeTertiary: '#85b44c',  + themeSecondary: '#5a9117',  + themeDarkAlt: '#427505',  + themeDark: '#386304',  + themeDarker: '#294903',  + neutralLighterAlt: '#faf9f8',  + neutralLighter: '#f3f2f1',  + neutralLight: '#edebe9',  + neutralQuaternaryAlt: '#e1dfdd',  + neutralQuaternary: '#d2d0ce',  + neutralTertiaryAlt: '#c8c6c4',  + neutralTertiary: '#a19f9d',  + neutralSecondaryAlt: '#8a8886',  + neutralSecondary: '#605e5c',  + neutralPrimary: '#323130',  + neutralPrimaryAlt: '#3b3a39',  + neutralDark: '#201f1e',  + black: '#000000',  + white: '#fff',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#03787c' } ``` -
- ## Blue theme The following table shows the color palette used by the Blue theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #004578black: #000000
themeDark: #005a9eneutralDark: #212121
themeDarkAlt: #106ebeneutralPrimary: #333
themePrimary: #0078d7neutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
themeSecondary: #2b88d8neutralTertiaryAlt: #c8c8c8
themeTertiary: #71afe5neutralLight: #eaeaea
themeLight: #c7e0f4neutralLighter: #f4f4f4
themeLighter: #deecf9neutralLighterAlt: #f8f8f8
themeLighterAlt: #eff6fcwhite: #fff
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #004578 | black: #000000 | +| themeDark: #005a9e | neutralDark: #212121 | +| themeDarkAlt: #106ebe | neutralPrimary: #333 | +| themePrimary: #0078d7 | neutralPrimaryAlt: #3c3c3c | +| | neutralSecondary: #666666 | +| | neutralTertiary: #a6a6a6 | +| themeSecondary: #2b88d8 | neutralTertiaryAlt: #c8c8c8 | +| themeTertiary: #71afe5 | neutralLight: #eaeaea | +| themeLight: #c7e0f4 | neutralLighter: #f4f4f4 | +| themeLighter: #deecf9 | neutralLighterAlt: #f8f8f8 | +| themeLighterAlt: #eff6fc | white: #fff | The following code shows how to define a dictionary in PowerShell for the Blue theme's color palette. ```powershell {  -    themePrimary: '#0078d7',  -    themeLighterAlt: '#eff6fc',  -    themeLighter: '#deecf9',  -    themeLight: '#c7e0f4',  -    themeTertiary: '#71afe5',  -    themeSecondary: '#2b88d8',  -    themeDarkAlt: '#106ebe',  -    themeDark: '#005a9e',  -    themeDarker: '#004578',  -    neutralLighterAlt: '#f8f8f8',  -    neutralLighter: '#f4f4f4',  -    neutralLight: '#eaeaea',  -    neutralQuaternaryAlt: '#dadada',  -    neutralQuaternary: '#d0d0d0',  -    neutralTertiaryAlt: '#c8c8c8',  -    neutralTertiary: '#a6a6a6',  -    neutralSecondaryAlt: '#767676',  -    neutralSecondary: '#666666',  -    neutralPrimary: '#333',  -    neutralPrimaryAlt: '#3c3c3c',  -    neutralDark: '#212121',  -    black: '#000000',  -    white: '#fff',  -    primaryBackground: '#fff',  -    primaryText: '#333'  + themePrimary: '#0078d7',  + themeLighterAlt: '#eff6fc',  + themeLighter: '#deecf9',  + themeLight: '#c7e0f4',  + themeTertiary: '#71afe5',  + themeSecondary: '#2b88d8',  + themeDarkAlt: '#106ebe',  + themeDark: '#005a9e',  + themeDarker: '#004578',  + neutralLighterAlt: '#f8f8f8',  + neutralLighter: '#f4f4f4',  + neutralLight: '#eaeaea',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralTertiaryAlt: '#c8c8c8',  + neutralTertiary: '#a6a6a6',  + neutralSecondaryAlt: '#767676',  + neutralSecondary: '#666666',  + neutralPrimary: '#333',  + neutralPrimaryAlt: '#3c3c3c',  + neutralDark: '#212121',  + black: '#000000',  + white: '#fff',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#8764b8' } ``` -
- ## Purple theme The following table shows the color palette used by the Purple theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #27268ablack: #000000
themeDark: #3230b0neutralDark: #212121
themeDarkAlt: #5250cfneutralPrimary: #333
themePrimary: #6b69d6neutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
themeSecondary: #7a78daneutralTertiaryAlt: #c8c8c8
themeTertiary: #c1c0eeneutralLight: #eaeaea
themeLight: #e1e1f7neutralLighter: #f4f4f4
themeLighter: #f0f0fbneutralLighterAlt: #f8f8f8
themeLighterAlt: #f8f7fdwhite: #fff
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #27268a | black: #000000 | +| themeDark: #3230b0 | neutralDark: #212121 | +| themeDarkAlt: #5250cf | neutralPrimary: #333 | +| themePrimary: #6b69d6 | neutralPrimaryAlt: #3c3c3c | +| | neutralSecondary: #666666 | +| | neutralTertiary: #a6a6a6 | +| themeSecondary: #7a78da | neutralTertiaryAlt: #c8c8c8 | +| themeTertiary: #c1c0ee | neutralLight: #eaeaea | +| themeLight: #e1e1f7 | neutralLighter: #f4f4f4 | +| themeLighter: #f0f0fb | neutralLighterAlt: #f8f8f8 | +| themeLighterAlt: #f8f7fd | white: #fff | The following code shows how to define a dictionary in PowerShell for the Purple theme's color palette. ```powershell {  -    themePrimary: '#6b69d6',  -    themeLighterAlt: '#f8f7fd',  -    themeLighter: '#f0f0fb',  -    themeLight: '#e1e1f7',  -    themeTertiary: '#c1c0ee',  -    themeSecondary: '#7a78da',  -    themeDarkAlt: '#5250cf',  -    themeDark: '#3230b0',  -    themeDarker: '#27268a',  -    neutralLighterAlt: '#f8f8f8',  -    neutralLighter: '#f4f4f4',  -    neutralLight: '#eaeaea',  -    neutralQuaternaryAlt: '#dadada',  -    neutralQuaternary: '#d0d0d0',  -    neutralTertiaryAlt: '#c8c8c8',  -    neutralTertiary: '#a6a6a6',  -    neutralSecondaryAlt: '#767676',  -    neutralSecondary: '#666666',  -    neutralPrimary: '#333',  -    neutralPrimaryAlt: '#3c3c3c',  -    neutralDark: '#212121',  -    black: '#000000',  -    white: '#fff',  -    primaryBackground: '#fff',  -    primaryText: '#333'  + themePrimary: '#6b69d6',  + themeLighterAlt: '#f8f7fd',  + themeLighter: '#f0f0fb',  + themeLight: '#e1e1f7',  + themeTertiary: '#c1c0ee',  + themeSecondary: '#7a78da',  + themeDarkAlt: '#5250cf',  + themeDark: '#3230b0',  + themeDarker: '#27268a',  + neutralLighterAlt: '#f8f8f8',  + neutralLighter: '#f4f4f4',  + neutralLight: '#eaeaea',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralTertiaryAlt: '#c8c8c8',  + neutralTertiary: '#a6a6a6',  + neutralSecondaryAlt: '#767676',  + neutralSecondary: '#666666',  + neutralPrimary: '#333',  + neutralPrimaryAlt: '#3c3c3c',  + neutralDark: '#212121',  + black: '#000000',  + white: '#fff',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#038387' } ``` -
- ## Gray theme The following table shows the color palette used by the Gray theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #323130black: #000000
themeDark: #403e3dneutralDark: #212121
themeDarkAlt: #53504eneutralPrimary: #333
themePrimary: #5d5a58neutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
themeSecondary: #6d6a67neutralTertiaryAlt: #c8c8c8
themeTertiary: #bbb9b8neutralLight: #eaeaea
themeLight: #dfdeddneutralLighter: #f4f4f4
themeLighter: #efeeeeneutralLighterAlt: #f8f8f8
themeLighterAlt: #f7f7f7white: #fff
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #323130 | black: #000000 | +| themeDark: #403e3d | neutralDark: #212121 | +| themeDarkAlt: #53504e | neutralPrimary: #333 | +| themePrimary: #5d5a58 | neutralPrimaryAlt: #3c3c3c | +| | neutralSecondary: #666666 | +| | neutralTertiary: #a6a6a6 | +| themeSecondary: #6d6a67 | neutralTertiaryAlt: #c8c8c8 | +| themeTertiary: #bbb9b8 | neutralLight: #eaeaea | +| themeLight: #dfdedd | neutralLighter: #f4f4f4 | +| themeLighter: #efeeee | neutralLighterAlt: #f8f8f8 | +| themeLighterAlt: #f7f7f7 | white: #fff | The following code shows how to define a dictionary in PowerShell for the Gray theme's color palette. ```powershell {  -    themePrimary: '#5d5a58',  -    themeLighterAlt: '#f7f7f7',  -    themeLighter: '#efeeee',  -    themeLight: '#dfdedd',  -    themeTertiary: '#bbb9b8',  -    themeSecondary: '#6d6a67',  -    themeDarkAlt: '#53504e',  -    themeDark: '#403e3d',  -    themeDarker: '#323130',  -    neutralLighterAlt: '#f8f8f8',  -    neutralLighter: '#f4f4f4',  -    neutralLight: '#eaeaea',  -    neutralQuaternaryAlt: '#dadada',  -    neutralQuaternary: '#d0d0d0',  -    neutralTertiaryAlt: '#c8c8c8',  -    neutralTertiary: '#a6a6a6',  -    neutralSecondaryAlt: '#767676',  -    neutralSecondary: '#666666',  -    neutralPrimary: '#333',  -    neutralPrimaryAlt: '#3c3c3c',  -    neutralDark: '#212121',  -    black: '#000000',  -    white: '#fff',  -    primaryBackground: '#fff',  -    primaryText: '#333'  + themePrimary: '#5d5a58',  + themeLighterAlt: '#f7f7f7',  + themeLighter: '#efeeee',  + themeLight: '#dfdedd',  + themeTertiary: '#bbb9b8',  + themeSecondary: '#6d6a67',  + themeDarkAlt: '#53504e',  + themeDark: '#403e3d',  + themeDarker: '#323130',  + neutralLighterAlt: '#f8f8f8',  + neutralLighter: '#f4f4f4',  + neutralLight: '#eaeaea',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralTertiaryAlt: '#c8c8c8',  + neutralTertiary: '#a6a6a6',  + neutralSecondaryAlt: '#767676',  + neutralSecondary: '#666666',  + neutralPrimary: '#333',  + neutralPrimaryAlt: '#3c3c3c',  + neutralDark: '#212121',  + black: '#000000',  + white: '#fff',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#0078d4' +} +``` + +## Periwinkle theme + +The following table shows the color palette used by the Periwinkle theme. + +| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #383966 | black: #000000 | +| themeDark: #3D3E78 | neutralDark: #201f1e | +| themeDarkAlt: #444791 | neutralPrimary: #323130 | +| themePrimary: #5B5FC7 | neutralPrimaryAlt: #3b3a39 | +| | neutralSecondary: #605e5c | +| | neutralTertiary: #a19f9d | +| themeSecondary: #7579EB | neutralTertiaryAlt: #c8c6c4 | +| themeTertiary: #7F85F5 | neutralLight: #edebe9 | +| themeLight: #AAB1FA | neutralLighter: #f3f2f1 | +| themeLighter: #B6BCFA | neutralLighterAlt: #faf9f8 | +| themeLighterAlt: #C5CBFA | white: #fff | + +The following code shows how to define a dictionary in PowerShell for the Periwinkle theme's color palette. + +```powershell +{  + themeDarker: '#383966',  + themeDark: '#3D3E78',  + themeDarkAlt: '#444791',  + themePrimary: '#5B5FC7',  + themeSecondary: '#7579EB',  + themeTertiary: '#7F85F5',  + themeLight: '#AAB1FA',  + themeLighter: '#B6BCFA',  + themeLighterAlt: '#C5CBFA',  + black: '#000000',  + neutralDark: '#201f1e',  + neutralPrimary: '#323130',  + neutralPrimaryAlt: '#3b3a39',  + neutralSecondary: '#605e5c',  + neutralTertiary: '#a19f9d',  + neutralTertiaryAlt: '#c8c6c4',  + neutralLight: '#edebe9',  + neutralLighter: '#f3f2f1',  + neutralLighterAlt: '#faf9f8',  + white: '#fff',  + neutralQuaternaryAlt: '#dadada',  + neutralQuaternary: '#d0d0d0',  + neutralSecondaryAlt: '#767676',  + primaryBackground: '#fff',  + primaryText: '#333', + accent: '#5B5FC7' } ``` -
## Dark Yellow theme The following table shows the color palette used by the Dark Yellow theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #fff171black: #f8f8f8
themeDark: #ffed4bneutralDark: #f4f4f4
themeDarkAlt: #ffe817neutralPrimary: #ffffff
themePrimary: #fce100neutralPrimaryAlt: #eaeaea
neutralSecondary: #dadada
neutralTertiary: #c8c8c8
themeSecondary: #e3cc00neutralTertiaryAlt: #6d6d6d
themeTertiary: #6a5f00neutralLight: #3f3f3f
themeLight: #322d00neutralLighter: #313131
themeLighter: #191700neutralLighterAlt: #282828
themeLighterAlt: #0d0b00white: #1f1f1f
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #fff171 | black: #f8f8f8 | +| themeDark: #ffed4b | neutralDark: #f4f4f4 | +| themeDarkAlt: #ffe817 | neutralPrimary: #ffffff | +| themePrimary: #fce100 | neutralPrimaryAlt: #eaeaea | +| | neutralSecondary: #dadada | +| | neutralTertiary: #c8c8c8 | +| themeSecondary: #e3cc00 | neutralTertiaryAlt: #6d6d6d | +| themeTertiary: #6a5f00 | neutralLight: #3f3f3f | +| themeLight: #322d00 | neutralLighter: #313131 | +| themeLighter: #191700 | neutralLighterAlt: #282828 | +| themeLighterAlt: #0d0b00 | white: #1f1f1f | The following code shows how to define a dictionary in PowerShell for the Dark Yellow theme's color palette. ```powershell {  -    themePrimary: '#fce100',  -    themeLighterAlt: '#0d0b00',  -    themeLighter: '#191700',  -    themeLight: '#322d00',  -    themeTertiary: '#6a5f00',  -    themeSecondary: '#e3cc00',  -    themeDarkAlt: '#ffe817',  -    themeDark: '#ffed4b',  -    themeDarker: '#fff171',  -    neutralLighterAlt: '#282828',  -    neutralLighter: '#313131',  -    neutralLight: '#3f3f3f',  -    neutralQuaternaryAlt: '#484848',  -    neutralQuaternary: '#4f4f4f',  -    neutralTertiaryAlt: '#6d6d6d',  -    neutralTertiary: '#c8c8c8',  -    neutralSecondaryAlt: '#d0d0d0',  -    neutralSecondary: '#dadada',  -    neutralPrimaryAlt: '#eaeaea',  -    neutralPrimary: '#ffffff',  -    neutralDark: '#f4f4f4',  -    black: '#f8f8f8',  -    white: '#1f1f1f',  -    primaryBackground: '#1f1f1f',  -    primaryText: '#ffffff',  -    error: '#ff5f5f'  + themePrimary: '#fce100',  + themeLighterAlt: '#0d0b00',  + themeLighter: '#191700',  + themeLight: '#322d00',  + themeTertiary: '#6a5f00',  + themeSecondary: '#e3cc00',  + themeDarkAlt: '#ffe817',  + themeDark: '#ffed4b',  + themeDarker: '#fff171',  + neutralLighterAlt: '#282828',  + neutralLighter: '#313131',  + neutralLight: '#3f3f3f',  + neutralQuaternaryAlt: '#484848',  + neutralQuaternary: '#4f4f4f',  + neutralTertiaryAlt: '#6d6d6d',  + neutralTertiary: '#c8c8c8',  + neutralSecondaryAlt: '#d0d0d0',  + neutralSecondary: '#dadada',  + neutralPrimaryAlt: '#eaeaea',  + neutralPrimary: '#ffffff',  + neutralDark: '#f4f4f4',  + black: '#f8f8f8',  + white: '#1f1f1f',  + primaryBackground: '#1f1f1f',  + primaryText: '#ffffff',  + error: '#ff5f5f', + accent: '#ffc83d' } ``` -
- ## Dark Blue theme The following table shows the color palette used by the Dark Blue theme. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
themeDarker: #6cdfffblack: #f8f8f8
themeDark: #44d6ffneutralDark: #f4f4f4
themeDarkAlt: #0ecbffneutralPrimary: #ffffff
themePrimary: #00bcf2neutralPrimaryAlt: #eaeaea
neutralSecondary: #dadada
neutralTertiary: #c8c8c8
themeSecondary: #00abdaneutralTertiaryAlt: #646e8a
themeTertiary: #005066neutralLight: #404759
themeLight: #002630neutralLighter: #353a49
themeLighter: #001318neutralLighterAlt: #2e3340
themeLighterAlt: #00090cwhite: #262a35
- -
+| Theme colors | Neutral colors | +| ------------------------ | --------------------------- | +| themeDarker: #6cdfff | black: #f8f8f8 | +| themeDark: #44d6ff | neutralDark: #f4f4f4 | +| themeDarkAlt: #0ecbff | neutralPrimary: #ffffff | +| themePrimary: #00bcf2 | neutralPrimaryAlt: #eaeaea | +| | neutralSecondary: #dadada | +| | neutralTertiary: #c8c8c8 | +| themeSecondary: #00abda | neutralTertiaryAlt: #646e8a | +| themeTertiary: #005066 | neutralLight: #404759 | +| themeLight: #002630 | neutralLighter: #353a49 | +| themeLighter: #001318 | neutralLighterAlt: #2e3340 | +| themeLighterAlt: #00090c | white: #262a35 | The following code shows how to define a dictionary in PowerShell for the Dark Blue theme's color palette. ```powershell {  -    themePrimary: '#00bcf2',  -    themeLighterAlt: '#00090c',  -    themeLighter: '#001318',  -    themeLight: '#002630',  -    themeTertiary: '#005066',  -    themeSecondary: '#00abda',  -    themeDarkAlt: '#0ecbff',  -    themeDark: '#44d6ff',  -    themeDarker: '#6cdfff',  -    neutralLighterAlt: '#2e3340',  -    neutralLighter: '#353a49',  -    neutralLight: '#404759',  -    neutralQuaternaryAlt: '#474e62',  -    neutralQuaternary: '#4c546a',  -    neutralTertiaryAlt: '#646e8a',  -    neutralTertiary: '#c8c8c8',  -    neutralSecondaryAlt: '#d0d0d0',  -    neutralSecondary: '#dadada',  -    neutralPrimaryAlt: '#eaeaea',  -    neutralPrimary: '#ffffff',  -    neutralDark: '#f4f4f4',  -    black: '#f8f8f8',  -    white: '#262a35',  -    primaryBackground: '#262a35',  -    primaryText: '#ffffff',  -    error: '#ff5f5f'  + themePrimary: '#00bcf2',  + themeLighterAlt: '#00090c',  + themeLighter: '#001318',  + themeLight: '#002630',  + themeTertiary: '#005066',  + themeSecondary: '#00abda',  + themeDarkAlt: '#0ecbff',  + themeDark: '#44d6ff',  + themeDarker: '#6cdfff',  + neutralLighterAlt: '#2e3340',  + neutralLighter: '#353a49',  + neutralLight: '#404759',  + neutralQuaternaryAlt: '#474e62',  + neutralQuaternary: '#4c546a',  + neutralTertiaryAlt: '#646e8a',  + neutralTertiary: '#c8c8c8',  + neutralSecondaryAlt: '#d0d0d0',  + neutralSecondary: '#dadada',  + neutralPrimaryAlt: '#eaeaea',  + neutralPrimary: '#ffffff',  + neutralDark: '#f4f4f4',  + black: '#f8f8f8',  + white: '#262a35',  + primaryBackground: '#262a35',  + primaryText: '#ffffff', + error: '#ff5f5f', + accent: '#3a96dd' } ``` -
- ## See also -* [SharePoint site theming overview](sharepoint-site-theming-overview.md) -* [SharePoint site theming: PowerShell cmdlets](sharepoint-site-theming-powershell.md) -* [SharePoint site theming: CSOM API](sharepoint-site-theming-csom.md) -* [SharePoint site theming: REST API](sharepoint-site-theming-rest-api.md) +- [SharePoint site theming overview](sharepoint-site-theming-overview.md) +- [SharePoint site theming: PowerShell cmdlets](sharepoint-site-theming-powershell.md) +- [SharePoint site theming: CSOM API](sharepoint-site-theming-csom.md) +- [SharePoint site theming: REST API](sharepoint-site-theming-rest-api.md) diff --git a/docs/declarative-customization/site-theming/sharepoint-site-theming-overview.md b/docs/declarative-customization/site-theming/sharepoint-site-theming-overview.md index 0df0bb929..5762ad676 100644 --- a/docs/declarative-customization/site-theming/sharepoint-site-theming-overview.md +++ b/docs/declarative-customization/site-theming/sharepoint-site-theming-overview.md @@ -1,13 +1,13 @@ --- title: SharePoint site theming description: New options for applying custom styles and colors to sites that make it easier to define and manage themes across site collections. -ms.date: 04/19/2018 -localization_priority: Priority +ms.date: 04/23/2025 +ms.localizationpriority: high --- # SharePoint site theming -SharePoint site owners have new options for applying custom styles and colors to sites that make it easier to define and manage themes across site collections. +SharePoint site owners have new options for applying custom styles and colors to sites that make it easier to define and manage themes across site collections. These new features include: @@ -17,7 +17,7 @@ These new features include: * An updated color palette, with 12 light colors and 6 dark colors, as well as 16 supplementary themes. * Control over which themes are available for use on pages within your sites. For example, you can define custom themes based on your organization's branding or identity, and make those the only available themes within your sites. -These capabilities are available to administrators via [PowerShell cmdlets](sharepoint-site-theming-powershell.md), and to developers via the [SharePoint client-side object model (CSOM)](sharepoint-site-theming-csom.md) or the [SharePoint REST API](sharepoint-site-theming-rest-api.md). For information on applying custom themes to individual site collections see [SharePoint site design and site script overview](https://docs.microsoft.com/sharepoint/dev/declarative-customization/site-design-overview) +These capabilities are available to administrators via [PowerShell cmdlets](sharepoint-site-theming-powershell.md), and to developers via the [SharePoint client-side object model (CSOM)](sharepoint-site-theming-csom.md) or the [SharePoint REST API](sharepoint-site-theming-rest-api.md). For information on applying custom themes to individual site collections see [SharePoint site design and site script overview](../site-design-overview.md). For general information about working with themes to customize the look of your sites, see [Change the look of your SharePoint site](https://support.office.com/article/Change-the-look-of-your-SharePoint-site-06bbadc3-6b04-4a60-9d14-894f6a170818). @@ -25,12 +25,14 @@ For general information about working with themes to customize the look of your The following predefined themes are available by default: +* __Teal__ * __Blue__ * __Orange__ * __Red__ * __Purple__ * __Green__ * __Gray__ +* __Periwinkle__ * __Dark Yellow__ (inverted theme) * __Dark Blue__ (inverted theme) @@ -45,7 +47,7 @@ In addition to the default themes, you can select from supplementary themes. The -To select from the available themes for a SharePoint site, choose the __gear icon (⚙️)__ in the top right corner of the screen, and then select __Change the look__. You'll be presented with a list of themes to choose from, which might include default themes and/or custom themes depending on how your site has been configured. +To select from the available themes for a SharePoint site, choose the __gear icon (⚙️)__ in the top right corner of the screen, select __Change the look__, then select __theme__. You'll be presented with a list of themes to choose from, which might include default themes and/or custom themes depending on how your site has been configured. The following image shows how the default themes are presented in the theme picker dialog box. @@ -53,44 +55,47 @@ The following image shows how the default themes are presented in the theme pick When you choose a theme in the list, those color settings are instantly applied to the page so that you can see what the selected theme will look like. -After you've found a theme that you want to use, choose **Apply** to save your selection, or choose **Cancel** to revert to your current theme. +After you've found a theme that you want to use, choose **Save** to save your selection, or choose **Cancel** to revert to your current theme. ## Work with classic themes -You can still use the classic themes by choosing the link to **Classic change the look options** under the modern themes listed under **Change the look**. Because the modern SharePoint UI differs from the classic UI, however, some limitations apply when you use classic themes with modern pages. +You can still use the classic themes by choosing the link to **Classic change the look options** at the bottom of the **Change the look** panel. Because the modern SharePoint UI differs from the classic UI, however, some limitations apply when you use classic themes with modern pages. When you select a classic theme, a modern theme is generated from the settings in the classic theme, including the **isInverted** flag, the background image, and the color settings for **ContentAccent1**, **PageBackground**, and **BackgroundOverlay**. If **isInverted** is set to **True**, neutral colors such as **NeutralDark** and **NeutralLight** will be reversed. For the simplest experience, we recommend that you use modern themes with modern pages. If you need to use classic themes with modern pages, test your site carefully to verify that your content is readable and accessible. -## Troubleshoot custom theme issues +## Troubleshoot custom theme issues The modern site theming experience has been rolled out to classic site templates, too. While the new client-side theming architecture is more performant, if you have customizations on classic sites that aren’t rendering properly after you change the site’s theme, you can opt the site out of the new theming experience by disabling the feature. Please note, this opt-out only applies to classic sites where you have custom theme references that aren't rendering properly. By enabling this site-level opt-out you will disable the modern theming - and also lose the fast theming benefits it provides. -To do this, you must use a Windows PowerShell script with a CSOM (client-side object model) wrapper. We recommend using the PnP enable feature command: +To do this, you must use a Windows PowerShell script with a CSOM (client-side object model) wrapper. We recommend using the PnP PowerShell enable feature command: -1. Verify that you meet the following minimum requirements: - * You are a global administrator. - * You have read about [Execution Policies](https://technet.microsoft.com/library/dd347641.aspx). +1. Verify that you meet the following minimum requirements: -2. Download the latest PnP PowerShell from https://github.com/SharePoint/PnP-PowerShell/releases. + * You are at least a site collection owner on the site where you want to disable modern site themes + * You have read about [Execution Policies](https://technet.microsoft.com/library/dd347641.aspx) -3. Enter `Connect-PnPOnline -Url -Credentials getCredentials` (replacing `` with the url of the site you wish to opt out of). +1. Download the latest [PnP PowerShell](https://github.com/pnp/powershell). -4. Enter your credentials when prompted. + [!INCLUDE [pnp-powershell](../../../includes/snippets/open-source/pnp-powershell.md)] -5. To opt out of the site, you need to enable a feature: +1. Enter `Connect-PnPOnline -Url -Interactive -ClientId ` (replacing `` with the URL of the site you wish to connect to, and `` with the Client ID of your [registered Entra ID (Azure AD)](https://pnp.github.io/powershell/articles/registerapplication.html) application). +1. Enter your credentials when prompted. +1. To opt out of the site, you need to enable a feature: - * Enter `“Get-PnPFeature -Scope Site -Identity 5138468E-3D76-4F72-9DE4-E029F1245A7B”` - * Verify that nothing is returned from the previous command (this confirms the feature isn’t enabled yet) - * Enter `“Enable-PnPFeature -Scope Site -Identity 5138468E-3D76-4F72-9DE4-E029F1245A7B”` - * Enter `“Get-PnPFeature -Scope Site -Identity 5138468E-3D76-4F72-9DE4-E029F1245A7B”` + * Enter `Get-PnPFeature -Scope Site -Identity 5138468E-3D76-4F72-9DE4-E029F1245A7B` + * Verify that nothing is returned from the previous command (this confirms the feature isn’t enabled yet) + * Enter `Enable-PnPFeature -Scope Site -Identity 5138468E-3D76-4F72-9DE4-E029F1245A7B` + * Enter `Get-PnPFeature -Scope Site -Identity 5138468E-3D76-4F72-9DE4-E029F1245A7B` -6. Verify that the following is returned: +1. Verify that the following is returned: - `ClientSideThemingOptOut - 5138468e-3d76-4f72-9de4-e029f1245a7b` + ```powershell + ClientSideThemingOptOut - 5138468e-3d76-4f72-9de4-e029f1245a7b + ``` -7. For more information about Windows PowerShell, see [PowerShell](https://docs.microsoft.com/powershell/scripting/powershell-scripting?view=powershell-6). +For more information about Windows PowerShell, see [PowerShell](/powershell/scripting/overview). ## See also @@ -98,5 +103,3 @@ To do this, you must use a Windows PowerShell script with a CSOM (client-side ob * [SharePoint site theming: PowerShell cmdlets](sharepoint-site-theming-powershell.md) * [SharePoint site theming: CSOM API](sharepoint-site-theming-csom.md) * [SharePoint site theming: REST API](sharepoint-site-theming-rest-api.md) - - diff --git a/docs/declarative-customization/site-theming/sharepoint-site-theming-powershell.md b/docs/declarative-customization/site-theming/sharepoint-site-theming-powershell.md index 49f3329aa..37dc811ec 100644 --- a/docs/declarative-customization/site-theming/sharepoint-site-theming-powershell.md +++ b/docs/declarative-customization/site-theming/sharepoint-site-theming-powershell.md @@ -1,13 +1,13 @@ --- title: SharePoint site theming - PowerShell cmdlets description: SharePoint tenant administrators can use PowerShell cmdlets to create, retrieve, and remove site themes. Developers can use the SharePoint REST API to handle theme management tasks. -ms.date: 03/22/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint site theming: PowerShell cmdlets -SharePoint tenant administrators can use PowerShell cmdlets to create, retrieve, and remove site themes. +SharePoint tenant administrators can use PowerShell cmdlets to create, retrieve, and remove site themes. Developers can use the SharePoint [REST API](sharepoint-site-theming-rest-api.md) to handle theme management tasks. @@ -18,26 +18,21 @@ For information about how themes are defined and stored, see [JSON schema refere To run the PowerShell cmdlets for theme management, you must do the following: 1. Download and install the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588). If you already have a previous version of the shell installed, uninstall it first and then install the latest version. +1. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. -2. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. - -To verify your setup, try using the [Get-SPOHideDefaultThemes](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOHideDefaultThemes?view=sharepoint-ps) cmdlet to read the SPOHideDefaultThemes setting. If the cmdlet runs and returns False with no errors, as shown in the following example, you're ready to proceed. +To verify your setup, try using the [Get-SPOHideDefaultThemes](/powershell/module/sharepoint-online/Get-SPOHideDefaultThemes) cmdlet to read the SPOHideDefaultThemes setting. If the cmdlet runs and returns False with no errors, as shown in the following example, you're ready to proceed. ## Site theme cmdlets The following cmdlets are available for managing site themes from PowerShell: -* [Add-SPOTheme](https://docs.microsoft.com/powershell/module/sharepoint-online/Add-SPOTheme?view=sharepoint-ps) – Creates a new custom theme, or overwrites an existing theme to modify its settings. -* [Get-SPOTheme](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOTheme?view=sharepoint-ps) – Retrieves settings for an existing theme. -* [Remove-SPOTheme](https://docs.microsoft.com/powershell/module/sharepoint-online/Remove-SPOTheme?view=sharepoint-ps) – Removes a theme from the theme gallery. -* [Set-SPOHideDefaultThemes](https://docs.microsoft.com/powershell/module/sharepoint-online/Set-SPOHideDefaultThemes?view=sharepoint-ps) – Specifies whether the default themes should be available. -* [Get-SPOHideDefaultThemes](https://docs.microsoft.com/powershell/module/sharepoint-online/Get-SPOHideDefaultThemes?view=sharepoint-ps) – Queries the current SPOHideDefaultThemes setting. - +* [Add-SPOTheme](/powershell/module/sharepoint-online/Add-SPOTheme) – Creates a new custom theme, or overwrites an existing theme to modify its settings. +* [Get-SPOTheme](/powershell/module/sharepoint-online/Get-SPOTheme) – Retrieves settings for an existing theme. +* [Remove-SPOTheme](/powershell/module/sharepoint-online/Remove-SPOTheme) – Removes a theme from the theme gallery. +* [Set-SPOHideDefaultThemes](/powershell/module/sharepoint-online/Set-SPOHideDefaultThemes) – Specifies whether the default themes should be available. +* [Get-SPOHideDefaultThemes](/powershell/module/sharepoint-online/Get-SPOHideDefaultThemes) – Queries the current SPOHideDefaultThemes setting. ## See also * [SharePoint site theming overview](sharepoint-site-theming-overview.md) * [SharePoint site theming: CSOM](sharepoint-site-theming-csom.md) - - - diff --git a/docs/declarative-customization/site-theming/sharepoint-site-theming-rest-api.md b/docs/declarative-customization/site-theming/sharepoint-site-theming-rest-api.md index 45260171c..de3d44434 100644 --- a/docs/declarative-customization/site-theming/sharepoint-site-theming-rest-api.md +++ b/docs/declarative-customization/site-theming/sharepoint-site-theming-rest-api.md @@ -1,8 +1,8 @@ --- title: SharePoint site theming - REST API description: Use the the SharePoint REST interface to perform basic create, read, update, and delete (CRUD) operations on site themes. -ms.date: 10/29/2019 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint site theming: REST API @@ -15,7 +15,7 @@ The SharePoint Online (and SharePoint 2016 and later on-premises) REST service s Before you get started, make sure that you're familiar with the following: -- [Get to know the SharePoint REST service](../../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) +- [Get to know the SharePoint REST service](../../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) - [Complete basic operations using SharePoint REST endpoints](../../sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints.md) ## REST commands for site themes @@ -119,7 +119,7 @@ function RestRequest(url,params) { req.send(params ? JSON.stringify(params) : void 0); } - + RestRequest("/_api/thememanager/DeleteTenantTheme", { name:"Sounders Rave Green" }); ``` @@ -147,7 +147,7 @@ function RestRequest(url,params) { req.setRequestHeader("ODATA-VERSION","4.0"); req.send(params ? JSON.stringify(params) : void 0); } - + RestRequest("/_api/thememanager/GetTenantThemingOptions"); ``` diff --git a/docs/declarative-customization/view-board-formatting.md b/docs/declarative-customization/view-board-formatting.md new file mode 100644 index 000000000..16c6f2643 --- /dev/null +++ b/docs/declarative-customization/view-board-formatting.md @@ -0,0 +1,31 @@ +--- +title: Format board view to customize SharePoint +description: Customize how board views in SharePoint lists and libraries are displayed by constructing a JSON object that describes the elements and the styles to be applied to those elements. +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# Board view customizations + +## Build custom cards + +You can use Board **`formatter`** to define a totally custom layout of field values inside a card using the same syntax used in [Column Formatting](column-formatting.md). + +## Detailed syntax reference + +### hideSelection + +Optional element. Specifies whether the ability to select cards in the view is disabled or not. `false` is the default behavior inside a board view (meaning selection is visible and enabled). `true` means that users will not be able to select list items. + +### formatter + +JSON object that defines the layout of cards. The schema of this JSON object is identical to the schema of a column format (and that of rowFormatter). For details on this schema and its capabilities, see the [Formatting syntax reference](./formatting-syntax-reference.md). + +### commandBarProps + +Groups the command bar customization options. For details on `commandBarProps`, see [Command bar customization syntax reference](./view-commandbar-formatting.md) + +## See also +- [Command bar customization syntax reference](./view-commandbar-formatting.md) +- [Advanced formatting concepts](./formatting-advanced.md) +- [Formatting syntax reference](./formatting-syntax-reference.md) diff --git a/docs/declarative-customization/view-calendar-formatting.md b/docs/declarative-customization/view-calendar-formatting.md new file mode 100644 index 000000000..a09948812 --- /dev/null +++ b/docs/declarative-customization/view-calendar-formatting.md @@ -0,0 +1,54 @@ +--- +title: Format calendar view to customize SharePoint +description: Customize calendar views in SharePoint lists and libraries +ms.date: 02/09/2023 +ms.localizationpriority: high +--- + +# Calendar view customizations + +## Detailed syntax reference + +### commandBarProps + +Groups the command bar customization options. For details on `commandBarProps`, see [Command bar customization syntax reference](./view-commandbar-formatting.md) + +## See also +- [Command bar customization syntax reference](./view-commandbar-formatting.md) + +> ![IMPORTANT] +> **Pre-requisite : List setup before creating a calendar view and applying a JSON formatting** +> +> - Before creating a new calendar view, a list should include all the required columns to be used in any JSON formatting. +> - After creating a calendar view, if more columns are required, go to the [List Settings page](https://support.microsoft.com/office/edit-list-settings-4d35793b-246e-42a3-990c-563a83795b7f) to create and add them to a calendar view. + +### Conditional view formatting based on a specific column + +The following image shows an example of conditional formatting applied to a calendar view, based on a single choice column named **PROJECT**: + +![SharePoint list calendar formatting](../images/calendar-view-formatting.png) + +> ![NOTE] +> Before creating a new calendar view, make sure the PROJECT column is already existing to apply the JSON code illustrated below. Alternatively, go the [List Settings page](https://support.microsoft.com/office/edit-list-settings-4d35793b-246e-42a3-990c-563a83795b7f) to create and add the single choice PROJECT column to a calendar view. + +In this example, **PROJECT** column has the following options: + +- Project A +- Project B +- Project C +- Project D +- Project E + +The JSON code below makes use of SharePoint Online Modern UI classes to apply colors, borders and a hover effect through the [Excel-style expression syntax](./formatting-syntax-reference.md#excel-style-expressions): + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/calendar-formatting.schema.json", + "additionalEventClass": "=if([$PROJECT] =='Project A' && @isSelected == false, 'sp-css-backgroundColor-successBackground50 sp-css-color-BlackText sp-css-borderColor-GreenText ms-bgColor-sharedGreenCyan10--hover ms-fontColor-white--hover', if([$PROJECT] =='Project A' && @isSelected == true, 'ms-bgColor-green sp-css-color-WhiteText', if([$PROJECT] =='Project B' && @isSelected == false, 'sp-css-backgroundColor-BgPeach sp-css-color-BlackText sp-css-borderColor-RedText ms-bgColor-sharedRed10--hover ms-fontColor-white--hover', if([$PROJECT] =='Project B' && @isSelected == true, 'sp-css-backgroundColor-redDark sp-css-color-WhiteText', if([$PROJECT] =='Project C' && @isSelected == false, 'sp-css-backgroundColor-BgGold sp-css-color-BlackText sp-css-borderColor-BrownText ms-bgColor-yellow--hover ms-fontColor-white--hover', if([$PROJECT] =='Project C' && @isSelected == true, 'ms-bgColor-sharedOrange10 sp-css-color-BlackText', if([$PROJECT] =='Project D' && @isSelected == false, 'ms-bgColor-communicationTint20 sp-css-color-BlackText sp-css-borderColor-BlueText ms-bgColor-sharedCyanBlue10--hover ms-fontColor-white--hover', if([$PROJECT] =='Project D' && @isSelected == true, 'sp-css-backgroundColor-BlueText sp-css-color-WhiteText', if([$PROJECT] =='Project E' && @isSelected == false, 'sp-css-backgroundColor-BgLilac sp-css-color-BlackText sp-css-borderColor-DarkPurpleText ms-bgColor-sharedBlueMagenta20--hover ms-fontColor-white--hover', if([$PROJECT] =='Project E' && @isSelected == true, 'sp-css-backgroundColor-BgPurple sp-css-color-WhiteText', if(@isSelected == false, 'sp-css-backgroundColor-neutralBackground20 sp-css-color-BlackText ms-bgColor-neutralTertiaryAlt--hover ms-fontColor-black--hover', 'sp-css-backgroundColor-neutralTertiary sp-css-color-WhiteText')))))))))))" +} +``` + +The gif image below shows the final result: + +![SharePoint list calendar formatting result](../images/calendar-view-formatting-result.gif) + diff --git a/docs/declarative-customization/view-commandbar-formatting.md b/docs/declarative-customization/view-commandbar-formatting.md new file mode 100644 index 000000000..f7f56e8e3 --- /dev/null +++ b/docs/declarative-customization/view-commandbar-formatting.md @@ -0,0 +1,248 @@ +--- +title: Command bar customization syntax reference +description: Command bar customization syntax reference +ms.date: 05/21/2025 +ms.localizationpriority: high +--- + +# Command bar customization syntax reference + +Command bar customization helps personalize a list to suit specific requirements. The JSON-based feature allows basic changes to the command bar, including modification of icon and/or text, hiding existing options, or repositioning commands. + +## commandBarProps + +Properties for Command bar customization. Valid in all types of layouts. + +## commands + +An array of JSON objects is used to specify the commands for customization. + +## key + +Mandatory property to uniquely identify a command in the Command bar. Valid keys include: + +```javascript +'new' +'newFolder' +'newWordDocument' +'newExcelWorkbook' +'newPowerPointPresentation' +'newOneNoteNotebook' +'newFormsForExcel' +'newVisioDrawing' +'upload' +'uploadFile' +'uploadFolder' +'open' +'share' +'copyLink' +'download' +'rename' +'copyTo' +'moveTo' +'delete' +'edit' +'comment' +'editNewMenu' +'powerBI' +'powerBIVisualizeList' +'automate' +'automateCreateRule' +'automateManageRules' +'powerAutomate' +'powerAutomateCreateFlow' +'powerAutomateSeeFlows' +'powerAutomateConfigureFlows' +'aiBuilderCreate' +'aiBuilderGoto' +'aiBuilder' +'alertMe' +'newLink' +'integrate' +'manageAlert' +'powerApps' +'powerAppsCreateApp' +'powerAppsSeeAllApps' +'powerAppsCustomizeForms' +'viewDocumentUnderstandingModels' +'versionHistory' +'openInImmersiveReader' +'classifyAndExtract' +'checkOut' +'checkIn' +'undoCheckOut' +'properties' +'pinItem' +'exportExcel' +'exportCSV' +'export' +'editInGridView' +'exitGridView' +'sync' +'uploadTemplate' +'addTemplate' +'openInOfficeOnline' +'openInOfficeClient' +'addShortcut' +'pinToQuickAccess' +'unpinFromQuickAccess' +'manageForms' +'favoriteCommand' +'createCopilot' +``` + +## ⚠️ Recent updates to `commandBarCustomization` Keys + +> Some keys in the commandBarCustomization schema have been updated. To ensure your custom formatter functions correctly, please update your existing JSON to reflect these new keys. +> +> | Original Key | New Key | +> |--------------|-------------| +> | `new` | `newComposite` (Document Library)| +> | `upload` | `UploadCommand` | +> | `sync` | `syncCommand` | +> | `addShortcut`| `addShortcutToOneDriveCommand` | +> | `pinToQuickAccess` | `PinToQuickAccessCommand` | +> | `pinItem` | `pinItemCommand` | +> | `properties` | `propertiesCommand` | +> | `versionHistory` | `versionHistoryCommand` (currently not working) | +> +> Additionally, the following new command keys are now available: +> > +> - `stasherContextMenuCommand` (Add shortcut) +> - `stasherCommand.myFiles` (Add shortcut --> my Files) +> - `stasherCommand.otherLocations` (Add shortcut --> Other locations) +> - `PublishCommand` +> - `complianceDetails` (right click context menu --> More --> Compliance details) +> - `more` (right click context menu --> More) +> - `previewFileCommand` (right click context menu --> Preview) +> +> Please note that the JSON schema at https://developer.microsoft.com/json-schemas/sp/v2/command-bar-formatting.schema.json has not yet been updated to reflect these new command keys. + +> [!IMPORTANT] +> Command bar customizations also affect the item context menu (right-click menu). If a command is hidden in the command bar, it will also be hidden in the context menu. + +## hide + +An optional property that specifies the condition to hide a particular command. The value of this property can either be a boolean, string or an Expression object. `false` is the default behavior (meaning the command is visible). `true` means that the command will be hidden. + +## text + +An optional property that specifies the text to be displayed as the name of the command. The value of this property can either be a string or an Expression object. If the value is not provided, then the default name of the command will be shown. + +## title + +An optional property that specifies the tooltip text to be displayed in the command. The value of this property can either be a string or an Expression object. If the value is not provided, then the default tooltip of the command will be shown. + +## iconName + +An optional property that specifies the [Fluent UI](https://developer.microsoft.com/fluentui#/) icon to be displayed in the command. The value of this property can either be a string or an Expression object. If the value is not provided, then the default icon of the command will be shown. + +## primary + +An optional property that specifies the condition to apply primary button styling to a command. The value of this property can either be a boolean, string or an Expression object. `false` is the default behavior (meaning the default style will be applied). `true` means the primary button styling will be applied to the command only if the command is placed at the 0th position in the command bar. + +The following example shows a sample Command bar formatting JSON to do the following: + +- Hide the 'New' command. +- Update the text and icon of 'Edit in grid view' command and add primary button styling to it. +- Remove the icon from 'Share' command and update the tooltip text of it. + +```JSON +{ + "commandBarProps" : { + "commands": [ + { + "key": "new", + "hide": true + }, + { + "key": "editInGridView", + "text": "Quick edit", + "iconName": "EditTable", + "primary": true + }, + { + "key": "share", + "iconName": "", + "title": "Share this List" + } + ] + } +} +``` + +## position + +An optional property that specifies the position where the command will be placed in the command bar. The value of this property can either be a number, a string, or an Expression object. If the value is not provided then the command will be placed in it's default position. This property follows zero-based indexing. + +## sectionType + +An optional property that specifies the section where the customized command will be placed in the command bar. The following strings are valid values for this property: + +- Primary +- Overflow + +The following example shows a sample Command bar formatting JSON to do the following: + +- Puts the 'New' command at the third position in the primary section of the Command bar. +- Puts the 'Share' command in the second position in the overflow menu of the Command bar. +- Puts the 'Alert me' command at the fourth position in the primary section of the Command bar. + +```JSON +{ + "commandBarProps" : { + "commands": [ + { + "key": "new", + "position": 2 + }, + { + "key": "share", + "position": 1, + "sectionType": "Overflow" + }, + { + "key": "alertMe", + "position": 3, + "sectionType": "Primary" + } + ] + } +} +``` + +## selectionModes + +An optional property that specifies the selection modes in which the command customization will be applied. If the value is not provided, then the customization will be applied in all the selection modes in which the command is available. The value of this property can be an array of strings where the following strings are allowed: + +- NoSelection +- SingleSelection +- MultiSelection + +The following example shows a sample Command bar formatting JSON to do the following: + +- Update the text of 'Share' command if the selected item has 'NumberField' column value 3 +- Update the text of 'Delete' command only if multiple items are selected. + +```JSON +{ + "commandBarProps": { + "commands": [ + { + "key": "share", + "selectionModes": [ + "SingleSelection" + ], + "text": "=if([$NumberField] == 3, 'Share item 3', 'Share')" + }, + { + "key": "delete", + "selectionModes": [ + "MultiSelection" + ], + "text": "Delete multiple items" + } + ] + } +} +``` diff --git a/docs/declarative-customization/view-formatting.md b/docs/declarative-customization/view-formatting.md index c260e218b..24b6ff6fe 100644 --- a/docs/declarative-customization/view-formatting.md +++ b/docs/declarative-customization/view-formatting.md @@ -1,314 +1,51 @@ --- title: Use view formatting to customize SharePoint description: Customize how views in SharePoint lists and libraries are displayed by constructing a JSON object that describes the elements that are displayed in a list view, and the styles to be applied to those elements. -ms.date: 08/23/2019 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # Use view formatting to customize SharePoint -You can use view formatting to customize how views in SharePoint lists and libraries are displayed. To do this, you construct a JSON object that describes the elements that are displayed when a row is loaded in a list view and any styles to be applied to those elements. View formatting does not change the data in list items; it only changes how they're displayed to users who browse the list. Anyone who can create and manage views in a list can use view formatting to configure how views are displayed. +You can use view formatting to customize how items in SharePoint lists and libraries are displayed. To do this, you construct a JSON object that describes the elements that are displayed when an item is loaded in a view and any styles to be applied to those elements. View formatting does not change the data in list items; it only changes how they're displayed to users who browse the list. Anyone who can create and manage views in a list can use view formatting to configure how views are displayed. > [!TIP] > Samples demonstrated in this article and numerous other community samples are available from a GitHub repository dedicated for open-sourced list formatting definitions. You can find these samples in the [sp-dev-list-formatting](https://github.com/SharePoint/sp-dev-list-formatting) repository within the [SharePoint](https://github.com/SharePoint) GitHub organization. ->[!NOTE] -> View formatting is currently supported only in SharePoint Online. +> [!NOTE] +> View formatting is currently supported only in SharePoint Online. ## Get started with view formatting -To open the view formatting pane, open the view dropdown and choose **Format current view**. View dropdown menu +To open the view formatting pane, open the view dropdown and choose **Format current view**. ->[!NOTE] -> To enable the 'Tile' layout, include `tileProps` property inside the JSON. +![View dropdown menu](../images/view-dropdown-menu.png) -To format rows in 'List' or 'Compact List' layout, use the `rowFormatter` or `additionalRowClass` properties. To format entries in 'Tile' layout, use the `formatter` within `tileProps` property. +The pane will look like the following depending on the current layout: +![List layout formatting pane](../images/sp-viewformatting-panel-listlayout.png) ![Gallery layout formatting pane](../images/sp-viewformatting-panel-tileslayout.png) -The easiest way to use view formatting is to start from an example and edit it to apply to your specific view. The following sections contain examples that you can copy, paste, and customize for your specific needs. There are also several samples available in the [SharePoint/sp-dev-list-formatting repository](https://github.com/SharePoint/sp-dev-list-formatting). - -## Apply conditional classes - -You can use view formatting to apply one or more classes to the entire list view row depending on the value of one or more fields in the row. These examples leave the content and structure of list view rows intact. - -For a list of recommended classes to use inside view formats, please see the [Style Guidelines section](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting#style-guidelines) in the [Column Formatting reference document](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting). - -> [!TIP] -> Using the `additionalRowClass` property to apply classes to list view rows will leave the formatting of individual columns in place. This allows you to combine view formats with column formatting for some powerful visualizations. - -### Conditional classes based on a date field - -The following image shows a list view with a class applied based on the value of a date column: -![SharePoint list with view formatted with conditional formatting](../images/listformatting-additionalrowclass.png) - -This example applies the class `sp-field-severity--severeWarning` to a list view row when the item's DueDate is before the current date/time: - -```JSON -{ - "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", - "additionalRowClass": "=if([$DueDate] <= @now, 'sp-field-severity--severeWarning', '')" -} -``` - -### Conditional classes based on the value in a text or choice field - -This example was adopted from a column formatting example, [Conditional formatting based on the value in a text or choice field](https://github.com/SharePoint/sp-dev-list-formatting/tree/master/column-samples/text-conditional-format), with some important differences to apply the concept to list view rows. The column formatting example applies both an icon and a class to a column based on the value of `@currentField`. The `additionalRowClass` attribute in view formatting, however, only allows you to specify a class and not an icon. Additionally, since `@currentField` always resolves to the value of the `Title` field when referenced inside a view format, this sample refers to the `Status` field directly (by using the [$Field] syntax inside the additionalRowClass property to determine which class to apply to the row). - -```JSON -{ - "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", - "additionalRowClass": "=if([$Status] == 'Done', 'sp-field-severity--good', if([$Status] == 'In progress', 'sp-field-severity--low' ,if([$Status] == 'In review','sp-field-severity--warning', if([$Status] == 'Has issues','sp-field-severity--blocked', ''))))" -} -``` - -You can find this sample with additional details here: [Conditional formatting based on choice field](https://github.com/SharePoint/sp-dev-list-formatting/tree/master/view-samples/text-conditional-format) - -## Build custom row layouts - -You can use view formatting to define a totally custom layout of field values inside a row using the same syntax used in Column Formatting. - -### Multi-line view style - -The following image shows a list with a custom multi-line view style applied: -![SharePoint list with multi-line view customization](../images/listformatting-rowformatter.png) - -This example uses the `rowFormatter` element, which totally overrides the rendering of a list view row. The `rowFormatter` in this example creates a bounding `
` box for every list view row. Inside this bounding box, the `$Title` and `$Feedback` fields are displayed on separate lines. Under those fields, a `button` element is displayed that, when clicked, does the same thing as clicking the list row in an uncustomized view, which is opening the property form for the item. This `button` is displayed conditionally, when the value of the `$Assigned_x0020_To` field (assumed to be a person/group field) matches the current signed-in user: - -```JSON -{ - "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", - "hideSelection": true, - "hideColumnHeader": true, - "rowFormatter": { - "elmType": "div", - "attributes": { - "class": "sp-row-card" - }, - "children": [ - { - "elmType": "div", - "style": { - "text-align": "left" - }, - "children": [ - { - "elmType": "div", - "attributes": { - "class": "sp-row-title" - }, - "txtContent": "[$Title]" - }, - { - "elmType": "div", - "attributes": { - "class": "sp-row-listPadding" - }, - "txtContent": "[$Feedback]" - }, - { - "elmType": "button", - "customRowAction": { - "action": "defaultClick" - }, - "txtContent": "Give feedback", - "attributes": { - "class": "sp-row-button" - }, - "style": { - "display": { - "operator": "?", - "operands": [ - { - "operator": "==", - "operands": [ - "@me", - "[$Assigned_x0020_To.email]" - ] - }, - "", - "none" - ] - } - } - } - ] - } - ] - } -} -``` -You can find this sample with additional details here: [Multi-line view rendering](https://github.com/SharePoint/sp-dev-list-formatting/tree/master/view-samples/multi-line-view) - - -Similarly, to get the below format in ‘Tile’ layout for the Feedback list, define the formatter within `tileProps`: -![Feedback list formatted in Tile layout](../images/feedback-tile-layout.png) - -```JSON -{ - "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", - "tileProps": { - "height": "250", - "width": "350", - "hideSelection": true, - "formatter": { - "elmType": "div", - "style": { - "display": "flex", - "align-items": "stretch", - "margin-bottom": "16px", - "min-width": "150px", - "flex-grow": "1", - "justify-content": "space-around", - "padding": "5px" - }, - "children": [ - { - "elmType": "div", - "style": { - "width": "95%", - "height": "92%", - "box-shadow": "0px 1.6px 3.6px 0 #00000024, 0px 0.3px 0.9px 0 #00000024", - "overflow": "hidden", - "border-radius": "2px", - "padding-left": "16px", - "padding-top": "16px" - }, - "attributes": { - "class": "ms-bgColor-neutralLighterAlt" - }, - "children": [ - { - "elmType": "div", - "style": { - "text-align": "left" - }, - "children": [ - { - "elmType": "div", - "style": { - "color":"#333333", - "font-size": "16px", - "font-weight":"600", - "margin-bottom":"5px" - }, - "txtContent": "[$Title]" - }, - { - "elmType": "div", - "style": { - "color":"#333333", - "font-size": "14px", - "line-height":"1.8" - }, - "attributes": { - "class": "sp-row-listPadding" - }, - "txtContent": "[$Feedback]" - }, - { - "elmType": "button", - "customRowAction": { - "action": "defaultClick" - }, - "txtContent": "Give feedback", - "attributes": { - "class": "sp-row-button" - }, - "style": { - "display": { - "operator": "?", - "operands": [ - { - "operator": "==", - "operands": [ - "@me", - "[$Assigned_x0020_To.email]" - ] - }, - "", - "none" - ] - } - } - } - ] - } - ] - } - ] - } - } -} -``` - -### Alternate Row Formatting based on Modulus +> [!NOTE] +> We have simplified the View formatting pane experience to separate out layout specific formatting JSON. With this change, you do not need to add layout specific props like `tileProps` anymore. -This example applies `% (Mod)` to a list view row with alternate coloring the rows: +To format rows in 'List' or 'Compact List' layout, select 'List' in 'Choose layout' dropdown in the formatting pane and use the `rowFormatter` or `additionalRowClass` properties. To format cards in 'Gallery' layout, select 'Gallery' in 'Choose layout' dropdown in the formatting pane and use the `formatter` property. To format cards in 'Board' view just use the `formatter` property. -```JSON -{ - "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", - "additionalRowClass": "=if(@rowIndex%2==0,'ms-bgColor-themeLight','')" -} -``` +The easiest way to use view formatting is to start from an example and edit it to apply to your specific view. The following sections contain examples that you can copy, paste, and customize for your specific needs. There are also several samples available in the [SharePoint/sp-dev-list-formatting repository](https://github.com/SharePoint/sp-dev-list-formatting). ## Creating custom JSON -Creating custom view formatting JSON from scratch is simple if you understand the schema. To create your own custom column formatting: - -1. [Download Visual Studio Code](https://code.visualstudio.com/Download). It's free and fast to download. - -2. In Visual Studio Code, create a new file, and save the empty file with a .json file extension. - -3. Paste the following lines of code into your empty file. - - ```JSON - { - "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json" - } - ``` - -You now have validation and autocomplete to create your JSON. You can start adding your JSON after the first line that defines the schema location. +Creating custom view formatting JSON from scratch is simple if user understands the schema, Monaco Editor is integrated in the formatting pane with pre-filled JSON schema reference to assist in creation of view formatting, Monaco editor has validation and autocomplete to help in crafting right JSON. User can start adding JSON after the first line that defines the schema location. > [!TIP] -> At any point, select **Ctrl**+**Space** to have Visual Studio Code offer suggestions for properties and values. For more information, see [Editing JSON with Visual Studio Code](https://code.visualstudio.com/Docs/languages/json). - -## Detailed syntax reference - -### rowFormatter - -Optional element. Specifies a JSON object that describes a list view row format. The schema of this JSON object is identical to the schema of a column format. For details on this schema and its capabilities, see the [Column Format detailed syntax reference](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting#detailed-syntax-reference). Only valid for 'List' and 'Compact List' layouts. - ->[!NOTE] -> Using the `rowFormatter` property will override anything specified in the `additionalRowClass` property. They are mutually exclusive. - -#### Differences in behavior between the rowFormatter element and column formatting - -Despite sharing the same schema, there are some differences in behavior between elements inside a `rowFormatter` element and those same elements in a column formatting object. - - * `@currentField` always resolves to the value of the `Title` field inside a `rowFormatter`. - -### additionalRowClass - -Optional element. Specifies a CSS class(es) that is applied to the entire row. Supports expressions. Only valid for 'List' and 'Compact List' layouts. - -`additionalRowClass` only takes effect when there is no `rowFormatter` element specified. If a `rowFormatter` is specified, then `additionalRowClass` is ignored. - -### hideSelection - -Optional element. Specifies whether the ability to select rows in the view is disabled or not. *false* is the default behavior inside a list view (meaning selection is visible and enabled). *true* means that users will not be able to select list items. - -For list & compact list layout, `hideSelection` only takes effect when there's a `rowFormatter` element specified. If no `rowFormatter` is specified, then `hideSelection` is ignored. For 'Tile' layout, `hideSelection` will only take effect if defined inside `tileProps` properties. - -### hideColumnHeader - -Optional element. Specifies whether the column headers in the view are hidden or not. *false* is the default behavior inside a list view (meaning column headers will be visible). *true* means that the view will not display column headers. - -### tileProps - -Optional element. Specifies a JSON object that describes a 'Tile' view format. Elements of this property include: -- height – defines the height of the card in pixels. -- width – defines the width of the card in pixels. Can go from height/2 to 3 x height. -- hideSelection – as defined above -- formatter – JSON object that defines the layout of tiles. The schema of this JSON object is identical to the schema of a column format (and that of rowFormatter). For details on this schema and its capabilities, see the [Column Format detailed syntax reference](https://docs.microsoft.com/sharepoint/dev/declarative-customization/column-formatting#detailed-syntax-reference). +> At any point, select **Ctrl**+**Space** for property/value suggestions. +> [!TIP] +> You can start from a HTML using [**formatter helper tool**](https://pnp.github.io/List-Formatting/tools/), which can convert HTML and CSS into formatter JSON with inline styles. + +## See also +- [List layout customization](./view-list-formatting.md) +- [Gallery layout customization](./view-gallery-formatting.md) +- [Board view customization](./view-gallery-formatting.md) +- [Group customization syntax reference](./view-group-formatting.md) +- [Advanced formatting concepts](./formatting-advanced.md) +- [Formatting syntax reference](./formatting-syntax-reference.md) diff --git a/docs/declarative-customization/view-gallery-formatting.md b/docs/declarative-customization/view-gallery-formatting.md new file mode 100644 index 000000000..7eb60a1f5 --- /dev/null +++ b/docs/declarative-customization/view-gallery-formatting.md @@ -0,0 +1,366 @@ +--- +title: Format gallery view to customize SharePoint +description: Customize how gallery views in SharePoint lists and libraries are displayed by constructing a JSON object that describes the elements and the styles to be applied to those elements. +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# Gallery layout customizations + +## Build custom cards + +You can use Gallery **`formatter`** to define a totally custom layout of field values inside a card using the same syntax used in [Column Formatting](column-formatting.md). + +### Example: Multi line custom card + +The following image shows a customized card in Gallery layout: + +![Feedback list formatted in Gallery layout](../images/feedback-tile-layout.png) + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json", + "height": "250", + "width": "350", + "hideSelection": true, + "formatter": { + "elmType": "div", + "style": { + "display": "flex", + "align-items": "stretch", + "margin-bottom": "16px", + "min-width": "150px", + "flex-grow": "1", + "justify-content": "space-around", + "padding": "5px" + }, + "children": [ + { + "elmType": "div", + "style": { + "width": "95%", + "height": "92%", + "box-shadow": "0px 1.6px 3.6px 0 #00000024, 0px 0.3px 0.9px 0 #00000024", + "overflow": "hidden", + "border-radius": "2px", + "padding-left": "16px", + "padding-top": "16px" + }, + "attributes": { + "class": "ms-bgColor-neutralLighterAlt" + }, + "children": [ + { + "elmType": "div", + "style": { + "text-align": "left" + }, + "children": [ + { + "elmType": "div", + "style": { + "color":"#333333", + "font-size": "16px", + "font-weight":"600", + "margin-bottom":"5px" + }, + "txtContent": "[$Title]" + }, + { + "elmType": "div", + "style": { + "color":"#333333", + "font-size": "14px", + "line-height":"1.8" + }, + "attributes": { + "class": "sp-row-listPadding" + }, + "txtContent": "[$Feedback]" + }, + { + "elmType": "button", + "customRowAction": { + "action": "defaultClick" + }, + "txtContent": "Give feedback", + "attributes": { + "class": "sp-row-button" + }, + "style": { + "display": { + "operator": "?", + "operands": [ + { + "operator": "==", + "operands": [ + "@me", + "[$Assigned_x0020_To.email]" + ] + }, + "", + "none" + ] + } + } + } + ] + } + ] + } + ] + } + +} +``` + +## Build custom group headers + +You can use `groupProps` to format group headers with flexibility to add grouped column's data, display name and item count. You can also add group aggregates in the group headers. + +### Example: Color coded group header + +In the example below we have gallery view with formatted group headers as per column metadata. + +![Employee gallery grouped by City with formatted group header](../images/employee-formatted-group-header-gallery-layout.png) + +> [!NOTE] +> Gallery card formatter is skipped in the below JSON for simplicity. +> The example below also contains line breaks. These have been added to improve the readability of the code. + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json", + "height": 277, + "width": 254, + "hideSelection": false, + "groupProps": { + "headerFormatter": { + "elmType": "div", + "children": [ + { + "elmType": "div", + "style": { + "flex-wrap": "wrap", + "display": "flex", + "box-sizing": "border-box", + "padding": "4px 8px 5px 8px", + "border-radius": "6px", + "align-items": "center", + "white-space": "nowrap", + "overflow": "hidden", + "margin": "1px 4px 4px 1px" + }, + "attributes": { + "class": "=if(@group.fieldData == 'California', 'sp-css-backgroundColor-blueBackground37', + if(@group.fieldData == 'Chicago', 'sp-css-backgroundColor-successBackground50', + if(@group.fieldData == 'New York', 'sp-css-backgroundColor-warningBackground50', + if(@group.fieldData == 'Seattle', 'sp-css-backgroundColor-blockingBackground50', + if(@group.fieldData == 'Washington DC', 'sp-css-backgroundColor-errorBackground50', + 'sp-field-borderAllRegular sp-field-borderAllSolid sp-css-borderColor-neutralSecondary'))))" + }, + "children": [ + { + "elmType": "img", + "attributes": { + "src": "=if(@group.fieldData == 'California', 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_California.svg/1920px-Flag_of_California.svg.png', + if(@group.fieldData == 'Chicago', 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Flag_of_Chicago%2C_Illinois.svg/1920px-Flag_of_Chicago%2C_Illinois.svg.png', + if(@group.fieldData == 'New York', 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_New_York_City.svg/2560px-Flag_of_New_York_City.svg.png', + if(@group.fieldData == 'Seattle', 'https://upload.wikimedia.org/wikipedia/en/thumb/6/6d/Flag_of_Seattle.svg/1920px-Flag_of_Seattle.svg.png', + if(@group.fieldData == 'Washington DC', 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Flag_of_the_District_of_Columbia.svg/2560px-Flag_of_the_District_of_Columbia.svg.png', '')))))" + }, + "style": { + "max-width": "24px", + "max-height": "24px", + "margin-top": "2px", + "border-radius": "2px" + } + }, + { + "elmType": "div", + "children": [ + { + "elmType": "span", + "style": { + "padding": "5px 5px 5px 5px", + "font-weight": "500" + }, + "txtContent": { + "operator": "+", + "operands": [ + "", + "@group.fieldData.displayValue" + ] + } + } + ] + }, + { + "elmType": "div", + "children": [ + { + "elmType": "div", + "style": { + "display": "flex", + "flex-direction": "row", + "justify-content": "center" + }, + "children": [ + { + "elmType": "div", + "txtContent": "='has ' + @group.count + if(@group.count > '1', ' employees', ' employee')", + "style": { + "font-weight": "500" + } + } + ] + } + ] + } + ] + } + ] + } + } +} +``` + +### Example: Color coded group header with aggregate + +In the example below we have list with formatted group headers and group aggregates. + +![Employee gallery grouped by City with formatted group header with Aggregates summary](../images/employee-formatted-group-header-aggregate-gallery-layout.png) + +In this example the `@aggregates` array is used to display a summary in the group header using `headerFormatter` in `groupProps`. + +> [!NOTE] +> Gallery card formatter is skipped in the below JSON for simplicity. +> The example below also contains line breaks. These have been added to improve the readability of the code. + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json", + "height": 277, + "width": 254, + "hideSelection": false, + "fillHorizontally": true, + "groupProps": { + "headerFormatter": { + "debugMode": true, + "elmType": "div", + "children": [ + { + "elmType": "div", + "style": { + "flex-wrap": "wrap", + "display": "flex", + "box-sizing": "border-box", + "padding": "4px 8px 5px 8px", + "border-radius": "6px", + "align-items": "center", + "white-space": "nowrap", + "overflow": "hidden", + "margin": "1px 4px 4px 1px" + }, + "attributes": { + "class": "=if(@group.fieldData == 'California', 'sp-css-backgroundColor-blueBackground37', + if(@group.fieldData == 'Chicago', 'sp-css-backgroundColor-successBackground50', + if(@group.fieldData == 'New York', 'sp-css-backgroundColor-warningBackground50', + if(@group.fieldData == 'Seattle', 'sp-css-backgroundColor-blockingBackground50', + if(@group.fieldData == 'Washington DC', 'sp-css-backgroundColor-errorBackground50', 'sp-field-borderAllRegular sp-field-borderAllSolid sp-css-borderColor-neutralSecondary')))))" + }, + "children": [ + { + "elmType": "img", + "attributes": { + "src": "=if(@group.fieldData == 'California', 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_California.svg/1920px-Flag_of_California.svg.png', + if(@group.fieldData == 'Chicago', 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Flag_of_Chicago%2C_Illinois.svg/1920px-Flag_of_Chicago%2C_Illinois.svg.png', + if(@group.fieldData == 'New York', 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_New_York_City.svg/2560px-Flag_of_New_York_City.svg.png', + if(@group.fieldData == 'Seattle', 'https://upload.wikimedia.org/wikipedia/en/thumb/6/6d/Flag_of_Seattle.svg/1920px-Flag_of_Seattle.svg.png', + if(@group.fieldData == 'Washington DC', 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Flag_of_the_District_of_Columbia.svg/2560px-Flag_of_the_District_of_Columbia.svg.png', '')))))" + }, + "style": { + "max-width": "24px", + "max-height": "24px", + "margin-top": "2px", + "border-radius": "2px" + } + }, + { + "elmType": "div", + "children": [ + { + "elmType": "span", + "style": { + "padding": "5px 5px 5px 5px", + "font-weight": "500" + }, + "txtContent": "@group.fieldData.displayValue" + } + ] + }, + { + "elmType": "div", + "forEach": "aggregate in @aggregates", + "children": [ + { + "elmType": "div", + "style": { + "display": "=if([$aggregate.columnDisplayName] == 'Approved' && Number([$aggregate.value]) < @group.count, 'flex', 'none')", + "flex-direction": "row", + "justify-content": "center" + }, + "children": [ + { + "elmType": "div", + "txtContent": "='has approval pending for ' + Number(@group.count - Number([$aggregate.value])) + if(@group.count - Number([$aggregate.value]) > 1 , ' employees', ' employee')", + "style": { + "font-weight": "500" + } + } + ] + } + ] + } + ] + } + ] + } + } +} +``` + +## Detailed syntax reference + +### hideSelection + +Optional element. Specifies whether the ability to select cards in the view is disabled or not. `false` is the default behavior inside a gallery view (meaning selection is visible and enabled). `true` means that users will not be able to select list items. +### fillHorizontally + +Optional element. Specifies whether the cards in the row should be stretched horizontally to fill the row. `false` is the default behavior (meaning cards in a row are stacked without resizing until they overflow). `true` means cards in the row are stretched horizontally only if necessary to fill the row. + +### height + +Optional element. Defines the height of the card in pixels. + +### width + +Optional element. Defines the width of the card in pixels. Can go from height/2 to 3 x height. + +### formatter + +JSON object that defines the layout of cards. The schema of this JSON object is identical to the schema of a column format (and that of rowFormatter). For details on this schema and its capabilities, see the [Formatting syntax reference](./formatting-syntax-reference.md). + +### groupProps + +Groups the group related customization options. For details on `groupProps`, see [Group Customization syntax reference](./view-group-formatting.md) + +### commandBarProps + +Groups the command bar customization options. For details on `commandBarProps`, see [Command bar customization syntax reference](./view-commandbar-formatting.md) + +## See also +- [Group customization syntax reference](./view-group-formatting.md) +- [Command bar customization syntax reference](./view-commandbar-formatting.md) +- [Advanced formatting concepts](./formatting-advanced.md) +- [Formatting syntax reference](./formatting-syntax-reference.md) diff --git a/docs/declarative-customization/view-group-formatting.md b/docs/declarative-customization/view-group-formatting.md new file mode 100644 index 000000000..32798d847 --- /dev/null +++ b/docs/declarative-customization/view-group-formatting.md @@ -0,0 +1,102 @@ +--- +title: Group customization syntax reference +description: Group customization syntax reference +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# Group customization syntax reference + +## groupProps + +Groups the group related customization options. Valid in 'List', 'Compact List' and 'Gallery' layouts. + +## headerFormatter + +JSON object that defines the format for group header. The schema of this JSON object is identical to the schema of a column format. For details on this schema and its capabilities, see the [Formatting syntax reference](./formatting-syntax-reference.md). Valid in 'List', 'Compact List' and 'Gallery' layouts. + +## footerFormatter + +JSON object that defines the format for group and list footer. The schema of this JSON object is identical to the schema of a column format (and that of rowFormatter). For details on this schema and its capabilities, see the [Formatting syntax reference](./formatting-syntax-reference.md). Valid in 'List' and 'Compact List' layouts. + +## hideFooter + +Optional element. Specifies whether the list footers or the group footers in the view are hidden or not. `false` is the default behavior (meaning footer is visible). `true` means that view will not display footers. Valid in 'List' and 'Compact List' layouts. + +For list & compact list layout, `hideFooter` overrides the `footerFormatter`, if present. + +## Special string values + +The values for `txtContent`, styles, and attributes can be either strings or expression objects. A few special string patterns for retrieving values from group and aggregate are supported. + +### "@group" + +Provides access to the grouped column's data, display name and item count. Valid in 'List', 'Compact List' and 'Gallery' layouts. Available only inside `groupProps`. + +The `@group` object has the following properties (with example values): + +```JSON +{ + "fieldData": "California", + "columnDisplayName": "City", + "count": 3 +} +``` + +You can also access sub properties for fields with rich data, e.g. People field, as mentioned under [Formatting Special string values](./formatting-syntax-reference.md#special-string-values). + +```JSON +{ + "fieldData": { + "id": "122", + "title": "Kalya Tucker", + "email": "kaylat@contoso.com", + "sip": "kaylat@contoso.com", + "picture": "https://contoso.sharepoint.com/kaylat_contoso_com_MThumb.jpg?t=63576928822", + "department": "Human Resources", + "jobTitle": "HR Manager" + }, + "columnDisplayName": "Author", + "count": 5 +} +``` + +### "@columnAggregate" + +Provides access to the aggregated column's value, display name and aggregate type. Valid in 'List' and 'Compact List' layouts. Available only inside `footerFormatter`. + +The `@columnAggregate` object has the following properties (with example values): + +```JSON +{ + "value": "3", + "columnDisplayName": "Approved", + "type": "Count" +} +``` + +### "@aggregates" + +Provides access to array of aggregated column's value, display name and aggregate type. Valid in 'List', 'Compact List' and 'Gallery' layouts. Available only inside `groupProps`. + +The `@aggregates` object has the following properties (with example value), and can be iterated on using for [Formatting forEach](./formatting-syntax-reference.md#foreach) property. + +```JSON +[ + { + "value": "3", + "columnDisplayName": "Approved", + "type": "Count" + }, + { + "value": "1.2", + "columnDisplayName": "Growth", + "type": "Average" + }, + { + "value": "0.33%", + "columnDisplayName": "Rate of change", + "type": "Variance" + } +] +``` diff --git a/docs/declarative-customization/view-list-formatting.md b/docs/declarative-customization/view-list-formatting.md new file mode 100644 index 000000000..42bc48c36 --- /dev/null +++ b/docs/declarative-customization/view-list-formatting.md @@ -0,0 +1,474 @@ +--- +title: Format list view to customize SharePoint +description: Customize how list views in SharePoint lists and libraries are displayed by constructing a JSON object that describes the elements and the styles to be applied to those elements. +ms.date: 08/10/2022 +ms.localizationpriority: high +--- + +# List layout customizations + +## Apply conditional classes on rows + +You can use **`additionalRowClass`** to apply one or more classes to the entire list row depending on the value of one or more fields in the row. These examples leave the content and structure of list rows intact. + +For a list of recommended classes to use inside view formats, please see the [Style guidelines](./column-formatting.md#style-guidelines) in the [Use column formatting to customize SharePoint](column-formatting.md). + +> [!TIP] +> Using the `additionalRowClass` property to apply classes to list rows will leave the formatting of individual columns in place. This allows you to combine view formats with column formatting for some powerful visualizations. + +### Example: Conditional classes based on a date field + +The following image shows a list layout with a class applied based on the value of a date column: + +![SharePoint list with view formatted with conditional formatting](../images/listformatting-additionalrowclass.png) + +This example applies the class `sp-field-severity--severeWarning` to a list row when the item's DueDate is before the current date/time: + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", + "additionalRowClass": "=if([$DueDate] <= @now, 'sp-field-severity--severeWarning', '')" +} +``` + +### Example: Conditional classes based on the value in a text or choice field + +This example was adopted from a column formatting example, [Conditional formatting based on the value in a text or choice field](https://github.com/SharePoint/sp-dev-list-formatting/tree/master/column-samples/text-conditional-format), with some important differences to apply the concept to list rows. The column formatting example applies both an icon and a class to a column based on the value of `@currentField`. The `additionalRowClass` attribute in view formatting, however, only allows you to specify a class and not an icon. Additionally, since `@currentField` always resolves to the value of the `Title` field when referenced inside a view format, this sample refers to the `Status` field directly (by using the [$Field] syntax inside the additionalRowClass property to determine which class to apply to the row). + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", + "additionalRowClass": "=if([$Status] == 'Done', 'sp-field-severity--good', if([$Status] == 'In progress', 'sp-field-severity--low' ,if([$Status] == 'In review','sp-field-severity--warning', if([$Status] == 'Has issues','sp-field-severity--blocked', ''))))" +} +``` + +You can find this sample with additional details here: [Conditional formatting based on choice field](https://github.com/pnp/list-formatting/tree/master/view-samples/status-rowclass) + +### Example: Alternate Row Formatting based on Modulus + +This example applies `% (Mod)` to a list row with alternate coloring the rows: + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", + "additionalRowClass": "=if(@rowIndex%2==0,'ms-bgColor-themeLight','')" +} +``` + +## Build custom list rows + +You can use **`rowFormatter`** to define a totally custom layout of field values inside a row using the same syntax used in [Column Formatting](column-formatting.md). + +### Example: Multi-line view style + +The following image shows a list with a custom multi-line view style applied: + +![SharePoint list with multi-line view customization](../images/listformatting-rowformatter.png) + +This example uses the `rowFormatter` element, which totally overrides the rendering of a list row. The `rowFormatter` in this example creates a bounding `
` box for every list row. Inside this bounding box, the `$Title` and `$Feedback` fields are displayed on separate lines. Under those fields, a `button` element is displayed that, when clicked, does the same thing as clicking the list row in an uncustomized view, which is opening the property form for the item. This `button` is displayed conditionally, when the value of the `$Assigned_x0020_To` field (assumed to be a person/group field) matches the current signed-in user: + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json", + "hideSelection": true, + "hideColumnHeader": true, + "rowFormatter": { + "elmType": "div", + "attributes": { + "class": "sp-row-card" + }, + "children": [ + { + "elmType": "div", + "style": { + "text-align": "left" + }, + "children": [ + { + "elmType": "div", + "attributes": { + "class": "sp-row-title" + }, + "txtContent": "[$Title]" + }, + { + "elmType": "div", + "attributes": { + "class": "sp-row-listPadding" + }, + "txtContent": "[$Feedback]" + }, + { + "elmType": "button", + "customRowAction": { + "action": "defaultClick" + }, + "txtContent": "Give feedback", + "attributes": { + "class": "sp-row-button" + }, + "style": { + "display": { + "operator": "?", + "operands": [ + { + "operator": "==", + "operands": [ + "@me", + "[$Assigned_x0020_To.email]" + ] + }, + "", + "none" + ] + } + } + } + ] + } + ] + } +} +``` + +You can find this sample with additional details here: [Multi-line view rendering](https://github.com/SharePoint/sp-dev-list-formatting/tree/master/view-samples/multi-line-view) + +## Build custom group headers and footers + +You can use `groupProps` to format group headers with flexibility to add grouped column's data, display name and item count. You can also add group aggregates in the group headers or format it directly in the group footers. + +### Example: Color coded group header + +In the example below we have list with group headers formatted according to column metadata. + +![Employee list grouped by City with formatted group header](../images/employee-formatted-group-header-list-layout.png) + +In this example below, the `headerFormatter` for `groupProps` is used to format the group header and the `@group` is used to access group info. + +> [!NOTE] +> The JSON below contains line breaks. These have been added to improve the readability of the code. + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json", + "groupProps": { + "headerFormatter": { + "elmType": "div", + "style": { + "flex-wrap": "wrap", + "display": "flex", + "box-sizing": "border-box", + "padding": "4px 8px 5px 8px", + "border-radius": "6px", + "align-items": "center", + "white-space": "nowrap", + "overflow": "hidden", + "margin": "1px 4px 4px 1px" + }, + "attributes": { + "class": "=if(@group.fieldData == 'California', 'sp-css-backgroundColor-blueBackground37', + if(@group.fieldData == 'Chicago', 'sp-css-backgroundColor-successBackground50', + if(@group.fieldData == 'New York', 'sp-css-backgroundColor-warningBackground50', + if(@group.fieldData == 'Seattle', 'sp-css-backgroundColor-blockingBackground50', + if(@group.fieldData == 'Washington DC', 'sp-css-backgroundColor-errorBackground50', + 'sp-field-borderAllRegular sp-field-borderAllSolid sp-css-borderColor-neutralSecondary')))))" + }, + "children": [ + { + "elmType": "img", + "attributes": { + "src": "=if(@group.fieldData == 'California', 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_California.svg/1920px-Flag_of_California.svg.png', + if(@group.fieldData == 'Chicago', 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Flag_of_Chicago%2C_Illinois.svg/1920px-Flag_of_Chicago%2C_Illinois.svg.png', + if(@group.fieldData == 'New York', 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_New_York_City.svg/2560px-Flag_of_New_York_City.svg.png', + if(@group.fieldData == 'Seattle', 'https://upload.wikimedia.org/wikipedia/en/thumb/6/6d/Flag_of_Seattle.svg/1920px-Flag_of_Seattle.svg.png', + if(@group.fieldData == 'Washington DC', 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Flag_of_the_District_of_Columbia.svg/2560px-Flag_of_the_District_of_Columbia.svg.png', '')))))" + }, + "style": { + "max-width": "24px", + "max-height": "24px", + "margin-top": "2px", + "border-radius": "2px" + } + }, + { + "elmType": "div", + "children": [ + { + "elmType": "span", + "style": { + "padding": "5px 5px 5px 5px", + "font-weight": "500" + }, + "txtContent": "@group.fieldData.displayValue" + } + ] + }, + { + "elmType": "div", + "children": [ + { + "elmType": "div", + "style": { + "display": "flex", + "flex-direction": "row", + "justify-content": "center" + }, + "children": [ + { + "elmType": "div", + "txtContent": "='has ' + @group.count + if(@group.count > '1', ' employees', ' employee')", + "style": { + "font-weight": "500" + } + } + ] + } + ] + } + ] + } + } +} +``` + +### Example: Color coded group header with aggregate + +In the example below we have list with group headers formatted with group aggregates. + +![Employee list grouped by City with formatted group header with Aggregates summary](../images/employee-formatted-group-header-aggregate-list-layout.png) + +In this example the `hideFooter` for `groupProps` is set to `true` - to hide the group footer and the `@aggregates` array is used to display a summary in the group header. + +> [!NOTE] +> The JSON below contains line breaks. These have been added to improve the readability of the code. + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json", + "groupProps": { + "hideFooter": true, + "headerFormatter": { + "elmType": "div", + "style": { + "flex-wrap": "wrap", + "display": "flex", + "box-sizing": "border-box", + "padding": "4px 8px 5px 8px", + "border-radius": "6px", + "align-items": "center", + "white-space": "nowrap", + "overflow": "hidden", + "margin": "1px 4px 4px 1px" + }, + "attributes": { + "class": "=if(@group.fieldData == 'California', 'sp-css-backgroundColor-blueBackground37', + if(@group.fieldData == 'Chicago', 'sp-css-backgroundColor-successBackground50', + if(@group.fieldData == 'New York', 'sp-css-backgroundColor-warningBackground50', + if(@group.fieldData == 'Seattle', 'sp-css-backgroundColor-blockingBackground50', + if(@group.fieldData == 'Washington DC', 'sp-css-backgroundColor-errorBackground50', + 'sp-field-borderAllRegular sp-field-borderAllSolid sp-css-borderColor-neutralSecondary')))))" + }, + "children": [ + { + "elmType": "img", + "attributes": { + "src": "=if(@group.fieldData == 'California', 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Flag_of_California.svg/1920px-Flag_of_California.svg.png', + if(@group.fieldData == 'Chicago', 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Flag_of_Chicago%2C_Illinois.svg/1920px-Flag_of_Chicago%2C_Illinois.svg.png', + if(@group.fieldData == 'New York', 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Flag_of_New_York_City.svg/2560px-Flag_of_New_York_City.svg.png', + if(@group.fieldData == 'Seattle', 'https://upload.wikimedia.org/wikipedia/en/thumb/6/6d/Flag_of_Seattle.svg/1920px-Flag_of_Seattle.svg.png', + if(@group.fieldData == 'Washington DC', 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d4/Flag_of_the_District_of_Columbia.svg/2560px-Flag_of_the_District_of_Columbia.svg.png', '')))))" + }, + "style": { + "max-width": "24px", + "max-height": "24px", + "margin-top": "2px", + "border-radius": "2px" + } + }, + { + "elmType": "div", + "children": [ + { + "elmType": "span", + "style": { + "padding": "5px 5px 5px 5px", + "font-weight": "500" + }, + "txtContent": "@group.fieldData.displayValue" + } + ] + }, + { + "elmType": "div", + "forEach": "aggregate in @aggregates", + "children": [ + { + "elmType": "div", + "style": { + "display": "=if([$aggregate.columnDisplayName] == 'Approved' && Number([$aggregate.value]) < @group.count, 'flex', 'none')", + "flex-direction": "row", + "justify-content": "center" + }, + "children": [ + { + "elmType": "div", + "txtContent": "='has approval pending for ' + Number(@group.count - Number([$aggregate.value])) + if(@group.count - Number([$aggregate.value]) > 1 , ' employees', ' employee')", + "style": { + "font-weight": "500" + } + } + ] + } + ] + } + ] + } + } +} + +``` + +### Example: Custom group footer + +In the example below we have list with group footer formatted according to aggregate value. + +![Employee list grouped by City with formatted group footer](../images/group-footer-list-layout.png) + +In this example the `footerFormatter` for `groupProps` are used to format the group footer and the `@columnAggregate` is used to access column aggregate. + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json", + "groupProps": { + "hideFooter": false, + "footerFormatter": { + "elmType": "div", + "children": [ + { + "elmType": "div", + "attributes": { + "iconName": "=if(@columnAggregate.type == 'Average' && @columnAggregate.value < 10, 'SortDown', 'SortUp')" + }, + "style": { + "color": "=if(@columnAggregate.type == 'Average' && @columnAggregate.value < 10, '#d13438', '#107c10')", + "font-weight": "600", + "margin-top": "10px" + } + }, + { + "elmType": "div", + "style": { + "color": "=if(@columnAggregate.type == 'Average' && @columnAggregate.value < 10, '#d13438', '#107c10')", + "font-weight": "600", + "margin-top": "10px", + "font-family": "Segoe UI" + }, + "txtContent": "=@columnAggregate.type + ': ' + @columnAggregate.value" + } + ] + } + } +} +``` + +## Build custom list footers + +You can use `footerFormatter` to format list footer with access to column aggregates. + +### Example: Custom list footer + +In the example below we have list with formatted footer as per the aggregate value. + +![Employee list grouped by City with formatted list footer](../images/list-footer-list-layout.png) + +In this example the `footerFormatter` is set to format the list footer and the `@columnAggregate` is used to access column aggregate. + +```JSON +{ + "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/row-formatting.schema.json", + "hideFooter": false, + "footerFormatter": { + "elmType": "div", + "attributes": { + "class": "ms-fontColor-themePrimary" + }, + "customCardProps": { + "formatter": { + "elmType": "div", + "children": [ + { + "elmType": "div", + "style": { + "display": "flex" + }, + "txtContent": "=@columnAggregate.type + ' of ' + @columnAggregate.columnDisplayName + ' is ' + @columnAggregate.value" + } + ], + "style": { + "height": "10px", + "width": "auto", + "cursor": "pointer", + "font-size": "14px", + "padding": "14px" + } + }, + "openOnEvent": "hover", + "directionalHint": "bottomCenter", + "isBeakVisible": true, + "beakStyle": { + "backgroundColor": "white" + } + }, + "txtContent": "View details", + "style": { + "text-decoration": "none", + "cursor": "pointer", + "font-size": "16px", + "margin-top": "10px" + } + } +} +``` + +## Detailed syntax reference + +### rowFormatter + +Optional element. Specifies a JSON object that describes a list row format. The schema of this JSON object is identical to the schema of a column format. For details on this schema and its capabilities, see [Formatting syntax reference](./formatting-syntax-reference.md). + +> [!NOTE] +> Using the `rowFormatter` property will override anything specified in the `additionalRowClass` property. They are mutually exclusive. + +#### Differences in behavior between the rowFormatter element and column formatting + +Despite sharing the same schema, there are some differences in behavior between elements inside a `rowFormatter` element and those same elements in a column formatting object. + +- `@currentField` always resolves to the value of the `Title` field inside a `rowFormatter`. + +### additionalRowClass + +Optional element. Specifies a CSS class(es) that is applied to the entire row. Supports expressions. + +`additionalRowClass` only takes effect when there is no `rowFormatter` element specified. If a `rowFormatter` is specified, then `additionalRowClass` is ignored. + +### hideSelection + +Optional element. Specifies whether the ability to select rows in the view is disabled or not. `false` is the default behavior inside a list view (meaning selection is visible and enabled). `true` means that users will not be able to select list items. + +### hideColumnHeader + +Optional element. Specifies whether the column headers in the view are hidden or not. `false` is the default behavior inside a list view (meaning column headers will be visible). `true` means that the view will not display column headers. + +### groupProps + +Groups the group related customization options. For details on `groupProps`, see [Group Customization syntax reference](./view-group-formatting.md) + +### commandBarProps + +Groups the command bar customization options. For details on `commandBarProps`, see [Command bar customization syntax reference](./view-commandbar-formatting.md) + +## See also +- [Group customization syntax reference](./view-group-formatting.md) +- [Command bar customization syntax reference](./view-commandbar-formatting.md) +- [Advanced formatting concepts](./formatting-advanced.md) +- [Formatting syntax reference](./formatting-syntax-reference.md) diff --git a/docs/design/accessibility.md b/docs/design/accessibility.md index 217609c09..393091803 100644 --- a/docs/design/accessibility.md +++ b/docs/design/accessibility.md @@ -1,10 +1,9 @@ --- title: Accessibility in SharePoint web part design description: Guidelines for adding accessibility to your web part. -ms.date: 03/22/2018 -localization_priority: Normal +ms.date: 06/13/2022 +ms.localizationpriority: medium --- - # Accessibility in SharePoint web part design Developing an experience that meets all users' unique visual, hearing, dexterity, cognitive, and speech needs is an important component of SharePoint web part design. Accessible design applies not only to people with disabilities, but also to potential situational impairments. Accessible design is good design. @@ -15,7 +14,7 @@ All Microsoft products must meet the requirements listed in the [Microsoft Acces ## Making web parts accessible -The SharePoint Framework provides a structure to help make all web parts accessible. The web part container provides keyboard navigation defaults for the web part toolbar to edit, move, and delete the web part, a method to select the web part, and a keyboard short cut (Ctrl+P) to open the property pane. However, you still need to specify additional keyboard and screen reader navigation for the other aspects of the UI in the web part and in the property pane. +The SharePoint Framework provides a structure to help make all web parts accessible. The web part container provides keyboard navigation defaults for the web part toolbar to edit, move, and delete the web part, a method to select the web part, and a keyboard short cut (Ctrl+P) to open the property pane. However, you still need to specify additional keyboard and screen reader navigation for the other aspects of the UI in the web part and in the property pane. In addition, many [Office UI Fabric components](https://developer.microsoft.com/fabric#/components) have built-in support for accessibility options, to make it quick to configure keyboard and screen reader navigation when you use the components in a web part. @@ -27,9 +26,9 @@ The following image shows keyboard navigation on a web part. Test your web part first with [Narrator](https://support.microsoft.com/help/22798/windows-10-narrator-get-started) and Microsoft Edge, and then verify the accessibility experience with [JAWS](http://www.freedomscientific.com/Products/Blindness/JAWS). -Narrator and Microsoft Edge are standards compliant. When you test with that combination, you are more likely to find issues, and you can validate that your site meets accessibility standards. +Narrator and Microsoft Edge are standards compliant. When you test with that combination, you are more likely to find issues, and you can validate that your site meets accessibility standards. -JAWS is the market leader in screen readers. JAWS includes features that can improve the accessibility of some websites that aren't as accessible in other screen readers. Therefore, testing in JAWS might not ensure that your site meets all accessibility requirements. +JAWS is the market leader in screen readers. JAWS includes features that can improve the accessibility of some websites that aren't as accessible in other screen readers. Therefore, testing in JAWS might not ensure that your site meets all accessibility requirements.   You might also want to test for whatever combination of browser and screen reader has the greatest market share for your website. @@ -45,13 +44,6 @@ Each control is a tab stop. Within a control, the following rules apply: - For modal surfaces, the last tab stop should be the commit actions. - For lists, the first tab stop should be the first item in the list, the next should be the commands, and then the navigation, settings, and so on. - ![Image that shows the tab stops on a SharePoint page](../images/accessibility-illustration-04.png) ### Navigation within a control @@ -92,7 +84,7 @@ Users who have vision impairments rely on screen readers to navigate the site UI ## Alt text and transcripts -Use alt text to provide descriptions of images that can be consumed by screen readers. This is useful for vision-impaired users who cannot consume information visually. Make sure that your alt text is descriptive, keeping in mind that some readers are relying on a screen reader to access the information conveyed in the image. +Use alt text to provide descriptions of images that can be consumed by screen readers. This is useful for users who have visual impairments who cannot consume information visually. Make sure that your alt text is descriptive, keeping in mind that some readers are relying on a screen reader to access the information conveyed in the image. Don't rely only on color to convey meaning; rely on both color and shape. @@ -100,9 +92,9 @@ To be fully compliant with accessibility standards, include alt text and a compl ## Minimum readable contrast -A minimum level of contrast is essential to help users with vision impairments consume the content on the page. It is also important to aid readability in low light and glare situations. +A minimum level of contrast is essential to help users who have visual impairments consume the content on the page. It is also important to aid readability in low light and glare situations. -The following image shows theme colors on the left and neutral colors on the right. +The following image shows theme colors on the left and neutral colors on the right. ![Neutral and Theme colors for minimum readable contrast](../images/themes-colors-blue-neutral-theme-2.png) @@ -162,19 +154,14 @@ The following image shows theme colors on the left and neutral colors on the rig
- ## High contrast Use high contrast colors as a guide for color choices for components and states on the web. Windows computers only have the ability to detect whether a PC is running high contrast or high contrast white. For this reason, use the default high contrast black setting for any high contrast, non-white theme. ![High contrast black and high contrast white settings](../images/accessibility-illustration-14.png) - ## See also - [SharePoint themes and colors](themes-colors.md) - [Design a web part](design-a-web-part.md) - [Designing great SharePoint experiences](design-guidance-overview.md) - - - diff --git a/docs/design/authoring-pages.md b/docs/design/authoring-pages.md index 6264e6fe5..49002ad83 100644 --- a/docs/design/authoring-pages.md +++ b/docs/design/authoring-pages.md @@ -1,62 +1,48 @@ --- title: Authoring pages in a SharePoint site description: Author pages using Edit mode, Published mode, and consider the mobile view. -ms.date: 1/23/2018 -localization_priority: Priority +ms.date: 03/08/2023 +ms.localizationpriority: high --- # Authoring pages in a SharePoint site -Authoring pages in SharePoint is a simple process, but it does require some familiarity with the SharePoint environment, as well as an understanding of what and who you are designing the page for. A few basic principles, such as remembering to "Start simple" and "Build on what's working," are valuable things to consider as you start authoring. It's also a good idea to consistently remind yourself of your audience and the goals that you are trying to help them achieve. +Authoring pages in SharePoint is a simple process, but it does require some familiarity with the SharePoint environment, and an understanding of what and who you are designing the page for. A few basic principles, such as remembering to "Start simple" and "Build on what's working," are valuable things to consider as you start authoring. It's also a good idea to consistently remind yourself of your audience and the goals that you're trying to help them achieve. - - -The SharePoint page authoring experience has two modes: +The SharePoint page authoring experience has two modes: - **Edit**. Allows page authors to add and configure web parts to add content to a page. -- **Published**. Allows your team or audience to view content and interact with web parts. +- **Published**. Allows your team or audience to view content and interact with web parts. ## Edit mode -When creating a new page, users have access to the authoring UI to add content to and customize the page content. - -Edit control - -
+When creating a new page, users have access to the authoring UI to add content to and customize the page content. -Edit control with cursor showing highlight +![Edit control](../images/design-authoring-edit-01.png) -
+![Edit control with cursor showing highlight](../images/design-authoring-edit-02.png) ### Add hint and Toolbox The add hint is a horizontal line with a plus icon that is visible when a web part is selected and on hover to indicate where page authors can add new web parts to their page. The Toolbox opens when a user selects the plus icon. The Toolbox contains all the web parts that can be added to a page. -Hint and toolbox showing tools - -
+![Hint and toolbox showing tools](../images/design-authoring-add-hint.png) ### Toolbar -A vertical toolbar and bounding box is part of the framework for every web part and is provided by the page. Each web part has an edit and delete action in the toolbar. - -Expanded toolbar +A vertical toolbar and bounding box is part of the framework for every web part and is provided by the page. Each web part has an edit and delete action in the toolbar. -
+![Expanded toolbar](../images/design-authoring-toolbar.png) ### Active and hover states On hover/active, the hint bars are primary blue or the primary theme color for the site. -Hover and active state - -
+![Hover and active state](../images/design-authoring-active-hover-01.png) The bounding box for a web part is gray by default, but picks up the primary blue or primary theme color for the site on hover or when the web part is selected. -Bounding box on and off - -
+![Bounding box on and off](../images/design-authoring-active-hover-02.png) ### Contextual edits @@ -64,35 +50,27 @@ Design a WYSIWYG experience for web parts so that users can fill in information ![Contextual edits form element](../images/design-authoring-contextual-edits.png) -
- ### Item-level edits UI can change within the web part; for example, text can become a text field, or you can display UI to reorder items or to check off tasks in a web part. You can enable interactive functionality for web parts in edit mode, in read mode, or in both, depending on your design intent. ![Item level editing with selected state](../images/design-authoring-item-level.png) -
- ### Property panes -Property panes are invoked via the **Edit** icon on the toolbar. Property panes should primarily contain configuration settings that enable or disable features that either show on the page, or make a call to a service to display content. +Property panes are invoked via the **Edit** icon on the toolbar. Property panes should primarily contain configuration settings that enable or disable features that either show on the page, or make a call to a service to display content. ![Expanded pane](../images/design-authoring-panes.png) -
- ## Published mode After the page is published, all editing UI is disabled for the viewer or reader of the page. To continue editing the page, the user selects the **Edit** button on the top right corner of the command bar. ![Publish button highlighted](../images/design-authoring-published.png) -
- ## Mobile view -All SharePoint pages are [responsive](grid-and-responsive-design.md) to allow the content of the page to be viewed on mobile devices. While designing a web part, it is important to understand how the new SharePoint site pages render across different devices. +All SharePoint pages are [responsive](grid-and-responsive-design.md) to allow the content of the page to be viewed on mobile devices. While designing a web part, it's important to understand how the new SharePoint site pages render across different devices. ![Mobile view of site](../images/design-authoring-mobile.png) diff --git a/docs/design/design-a-web-part.md b/docs/design/design-a-web-part.md index a7671229f..72c3a4bc6 100644 --- a/docs/design/design-a-web-part.md +++ b/docs/design/design-a-web-part.md @@ -1,8 +1,8 @@ --- title: Designing a SharePoint web part description: Use three types of property panes to design and develop web parts that fit your business or customer needs. -ms.date: 01/23/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # Designing a SharePoint web part @@ -57,7 +57,7 @@ Use accordion panes when you need to apply categorization for a complex web part ### Steps pane -Use a steps pane to group properties in multiple steps or pages when you need the web part to be configured in a linear order, or when choices in the first step affect the options that display in the second or third step. +Use a steps pane to group properties in multiple steps or pages when you need the web part to be configured in a linear order, or when choices in the first step affect the options that display in the second or third step. **Step 1 of the steps pane** @@ -67,7 +67,7 @@ In step 1, the back button is disabled and the next button is enabled.
-**Step 2 of the steps pane** +**Step 2 of the steps pane** In step 2, the back and next buttons are enabled. @@ -75,7 +75,7 @@ In step 2, the back and next buttons are enabled.
-**Step 3 of the steps pane** +**Step 3 of the steps pane** In step 3, the next button is disabled and the back button is enabled. @@ -85,5 +85,3 @@ In step 3, the next button is disabled and the back button is enabled. ## See also - [Designing great SharePoint experiences](design-guidance-overview.md) - - diff --git a/docs/design/design-guidance-overview.md b/docs/design/design-guidance-overview.md index 9ff8c935b..1566fe91e 100644 --- a/docs/design/design-guidance-overview.md +++ b/docs/design/design-guidance-overview.md @@ -1,8 +1,8 @@ --- title: Designing great SharePoint experiences description: Create compelling SharePoint experiences and effectively communicate your brand and message to your audience. -ms.date: 1/23/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # Designing great SharePoint experiences @@ -14,7 +14,7 @@ SharePoint is a platform that delivers content to more than 200,000 organization ![SharePoint communication site on multiple devices](../images/design-guidance-overview.png) -## SharePoint design principles +## SharePoint design principles SharePoint builds on the design principles that shape the Office and Microsoft product families. These principles help the design stay true to our product goals and user needs. @@ -38,7 +38,45 @@ We search for what’s possible beyond today’s way of getting things done. We Accessibility is developing an equal experience for all users that enables individuals to adjust their user experience to meet their unique visual, hearing, dexterity, cognitive, and speech needs. SharePoint believes strongly in providing accessible experiences for everyone, everywhere, and in optimizing our experiences to reflect the needs of all of our customers. - + + +## SharePoint Web UI Kit in Figma + +![Screenshot 2024-10-02 134843](https://github.com/user-attachments/assets/c6f4eb87-abf2-48ca-b5f2-f35ee98883c1) + +The SharePoint Web UI Kit empowers you to design communication and team sites for desktop, tablet and mobile in Figma. ​This kit delivers a set of web parts, style options, templates, and detailed guidance so you can quickly design engaging sites and pages in Figma. Figma is a subscription-based application that is the industry standard tool for web design, and provides an alternative to designing sites and pages outside of SharePoint. + +[Access the kit in Figma Community](https://aka.ms/SPWebUIkit) + +[Watch a live demo on YouTube with the product team](https://youtu.be/2UPchEYhuxI?si=x8ZWEBe3YZQL3Dkp) + +### Design without organizational limitations + +This UI kit provides SharePoint users with another tool in their toolbox. While building a page in SharePoint is easy, we wanted to provide the ability to mockup sites and pages. It allows you to explore different design options for your site without the limitation of admin privileges and tenant restrictions, and doesn’t expose organization data. + +Figma mockups provide a quick snapshot of SharePoint updates which business stakeholders can use to plan and make decisions. They can provide appropriate requirements and use this UI kit in collaboration with their design team to iterate in the life cycle of your organization's intranet. + +### Share designs with ease + +This UI kit provides you with page layouts and a selection of web parts to allow you to mockup and share new ideas across organizations and companies. Figma gives you the flexibility of reviewing and sharing your designs without having to spend time and resources creating it in SharePoint. Figma also allows you to download your designs into easy-to-use formats that can be used in documentation and presentations. Learn more at https://www.figma.com/ + +Note that Figma does not build the pages in SharePoint, so once you finalize a design in Figma, you will need to build it in SharePoint. You should evaluate if Figma is the right solution for mocking up sites and pages for SharePoint. + +### Community feedback + +Please tell us what’s missing, what doesn’t work for you, and where your biggest challenges are by leaving a comment on the [Figma SharePoint Web UI kit page](https://aka.ms/SPWebUIkit). + +### Past Tech Community blog posts for each SharePoint Web UI Kit release + +v3.0: [Figma Variables and new components available (v3.0.0) in the SharePoint Web UI Kit](https://techcommunity.microsoft.com/t5/microsoft-sharepoint-blog/figma-variables-and-new-components-available-v3-0-0-in-the/ba-p/4180339) + +v2.2: [SharePoint Web UI Kit - New Figma web part components available (v2.2) and feedback requested](https://techcommunity.microsoft.com/t5/microsoft-sharepoint-blog/sharepoint-web-ui-kit-new-figma-web-part-components-available-v2/ba-p/4031084) + +v2.1: [New web parts available in the SharePoint Web UI kit!](https://techcommunity.microsoft.com/t5/microsoft-sharepoint-blog/new-web-parts-available-in-the-sharepoint-web-ui-kit/ba-p/3956251) + +v2.0: [Updated content for the SharePoint Web UI kit!](https://techcommunity.microsoft.com/t5/microsoft-sharepoint-blog/updated-content-for-the-sharepoint-web-ui-kit/ba-p/3905250) + +v1.0: [Introducing a new SharePoint Web UI kit!](https://techcommunity.microsoft.com/t5/microsoft-sharepoint-blog/introducing-a-new-sharepoint-web-ui-kit/ba-p/3870293) ## See also diff --git a/docs/design/designing-a-web-part-icon.md b/docs/design/designing-a-web-part-icon.md index 9b784b9ce..fd9b128ae 100644 --- a/docs/design/designing-a-web-part-icon.md +++ b/docs/design/designing-a-web-part-icon.md @@ -1,8 +1,8 @@ --- title: Designing a web part icon description: Learn how to design a web part icon that will look great in SharePoint. -ms.date: 08/24/2018 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # Designing a SharePoint web part icon @@ -13,13 +13,13 @@ Web part icons are designed to be simple, representative, and symbolic. Every ic ## Grid keyline shapes -Web part icons are displayed at 32x32 px but are designed at twice the size, or 64x64 px. Create icons at 100% to ensure that pixels are accurate. +Web part icons are displayed at 32x32 px but are designed at twice the size, or 64x64 px. Create icons at 100% to ensure that pixels are accurate. ![Web part icon grid](../images/02_Icons_sizes.png) ## Layout -Design icons within the 64x64 px container area. This ensures that the icon renders correctly. +Design icons within the 64x64 px container area. This ensures that the icon renders correctly. ![Grid example for web part icons at 64px](../images/03_Icons_Layout.png) @@ -32,7 +32,7 @@ Not all icons or logos are designed in a perfect square. Use this guide of basic ## Pixel clarity -Try to avoid any icon distortion by snapping your edges to the X and Y coordinates. Use whole numbers when possible. +Try to avoid any icon distortion by snapping your edges to the X and Y coordinates. Use whole numbers when possible. ![Example of an icon that is not aligned to the pixel and one that is](../images/05_Icons_pixel_clarity.png) @@ -49,4 +49,3 @@ Web part icons can contain one color or be full color. Most icons work best when Export icons as SVGs at 64x64 px with transparent backgrounds. You can find the icon grid in the [SharePoint Design toolkit](https://developer.microsoft.com/fabric#/resources). - diff --git a/docs/design/empty-states.md b/docs/design/empty-states.md index 25217f409..dc78df4c2 100644 --- a/docs/design/empty-states.md +++ b/docs/design/empty-states.md @@ -1,13 +1,13 @@ --- title: Empty states for web parts description: The empty state is a visual representation of a web part, pre-configured to a content source like a list or with placeholder content, such as images and text. -ms.date: 4/16/2018 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # Empty state of a web part -The empty state is a visual representation of a web part, pre-configured to a content source like a list or with placeholder content, such as images and text. +The empty state is a visual representation of a web part, pre-configured to a content source like a list or with placeholder content, such as images and text. The following web parts have a content source set by default but no content to show for a newly created Communication site (that is, they feature an empty state): @@ -18,7 +18,7 @@ The following web parts have a content source set by default but no content to s - Hero - Image gallery -Empty states are designed to convey the purpose, structure, and layout options of web parts before the web part is configured or content is added. The empty state is also a perfect way to illustrate the vertical rhythm and layout of a page that starts from a template. Empty states behave similarly to fully configured web parts, and reflow to accommodate available space. They should support author-configured web part layouts. +Empty states are designed to convey the purpose, structure, and layout options of web parts before the web part is configured or content is added. The empty state is also a perfect way to illustrate the vertical rhythm and layout of a page that starts from a template. Empty states behave similarly to fully configured web parts, and reflow to accommodate available space. They should support author-configured web part layouts. ![Image that shows sample web part empty states](../images/empty_state_template_01.png) @@ -26,9 +26,9 @@ Empty states are different from placeholders in that the latter are meant to be ## Empty state and editing rights -Web parts with empty states can change interaction options and display text depending on the permission level and mode of the page. +Web parts with empty states can change interaction options and display text depending on the permission level and mode of the page. -In the following example (left to right), a person with editing rights sees an empty state of the Events web part in Edit and Read modes. The last image shows a simplified empty state view for page readers that have no editing rights, with a message appropriate to their permission level. +In the following example (left to right), a person with editing rights sees an empty state of the Events web part in Edit and Read modes. The last image shows a simplified empty state view for page readers that have no editing rights, with a message appropriate to their permission level. ![Author amd reader empty states](../images/empty_state_events_02.png) @@ -38,7 +38,7 @@ The following are layout options for the Events web part in an empty state. ## Interactions with an empty state -Empty states are designed primarily for people with editing rights and change interaction options based on the current page mode. Authors can manually add content to web parts in the Read mode, such as adding a new event or new news post. +Empty states are designed primarily for people with editing rights and change interaction options based on the current page mode. Authors can manually add content to web parts in the Read mode, such as adding a new event or new news post. The following example shows an empty state with multiple items stacked vertically, where the first item acts as a call to action (CTA) to learn more or create an event. diff --git a/docs/design/grid-and-responsive-design.md b/docs/design/grid-and-responsive-design.md index 9aba73a1d..7e12fd385 100644 --- a/docs/design/grid-and-responsive-design.md +++ b/docs/design/grid-and-responsive-design.md @@ -1,85 +1,72 @@ --- title: SharePoint grid and responsive design -description: The underlying page grid system and the breakpoints, or key screen sizes where the layout of the pages will change. -ms.date: 01/23/2018 -localization_priority: Priority +description: The underlying page grid system and the breakpoints, or key screen sizes where the layout of the pages will change. +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint grid and responsive design - -Responsive experiences seamlessly scale across devices to better display your content on a range of different screen sizes. Responsive design also eliminates the need to build multiple versions of your site pages to support different devices. -The design guidance for responsive pages in the SharePoint authoring environment incorporates a responsive grid system that is based on [Office UI Fabric](https://developer.microsoft.com/fabric). This article describes the underlying page grid system and the breakpoints, or key screen sizes where the layout of the pages will change. +Responsive experiences seamlessly scale across devices to better display your content on a range of different screen sizes. Responsive design also eliminates the need to build multiple versions of your site pages to support different devices. +The design guidance for responsive pages in the SharePoint authoring environment incorporates a responsive grid system that is based on [Office UI Fabric](https://developer.microsoft.com/fabric). This article describes the underlying page grid system and the breakpoints, or key screen sizes where the layout of the pages will change. ![SharePoint page on multiple devices](../images/design-grid-responsive-overview.png) +## Page type grids - -## Page type grids - -Each page type in the SharePoint authoring experience can have its own rules for how it applies the Fabric responsive grid. This is to ensure that each page looks great, regardless of what device it's designed for, and that the experience is optimized for that environment. The basic grid in the SharePoint desktop experiences is a 12-column structure. The number of columns and gutter width adjust based on the screen width. +Each page type in the SharePoint authoring experience can have its own rules for how it applies the Fabric responsive grid. This is to ensure that each page looks great, regardless of what device it's designed for, and that the experience is optimized for that environment. The basic grid in the SharePoint desktop experiences is a 12-column structure. The number of columns and gutter width adjust based on the screen width. The following sections show the basic grid structure applied across different types of SharePoint pages, to help you better understand how the grid adjusts to support the experience and device needs. - ![Twelve column grid diagram](../images/design-grid_diagram.png) -
- ### Team sites The content area for a team site is locked to the left. Team sites have a left navigation; therefore, the space that web parts occupy on the grid and the reflow behavior respects the space given to the navigation. The max width of the content area of a Team site is 1204 px and the minimum size is 320 px for mobile support. ![Team site](../images/design-grid-team-site.png) -
- The following examples show how the grid adjusts between key breakpoints on a team site. #### Small 320 x 568 + The small size has a single centered column area, with 20 px margins left and right. ![Team site small grid](../images/design-grid-Team-site-S-Canvas-no-column.png) -
- #### Medium 480 x 854 + The medium size has 12 columns, with 16 px gutters. ![Team site medium grid](../images/design-grid-Team-site-M-Canvas-16px-gutters.png) -
- #### Large 640 x 1024 + The large size has 12 columns, with 24 px gutters. ![Team site large grid](../images/design-grid-Team-site-L-Canvas-24px-gutters.png) -
- #### XL 1024 x 768 + The XL size has 12 columns, with 24 px gutters. ![Team site XL grid](../images/design-grid-Team-site-XL-Canvas-24px-gutters.png) -
- #### XXL 1366 x 768 + The XXL size has 12 columns, with 32 px gutters. ![Team site XXL grid](../images/design-grid-Team-site-XXL-Canvas-32px-gutters.png) -
- #### XXXL 1920 x 1080 + The XXXL size has 12 columns, with 32 px gutters. ![Team site XXXL grid](../images/design-grid-Team-site-XXXL-Canvas-32px-gutters-maxwidth-1204.png) -
- #### Team site multicolumn pages and web parts + Web parts scale horizontally depending on the page layout. The following example shows how the size of a web part adjusts to accommodate the left navigation. ![Team site multicolumn page with web parts](../images/design-grid-Team-site-web-parts.png) @@ -91,75 +78,64 @@ Communication sites have a top navigation and a centered content area. The maxim ![Communication site](../images/design-grid-communication_site.png) -
- The following examples show how the grid adjusts between key breakpoints on a communication site. #### Small 320 x 568 + The small size has a single centered column area, with 20 px margins left and right. ![Communication site small grid](../images/design-grid-Communication-site-S-Canvas-no-column.png) -
- #### Medium 480 x 854 + The medium size has 12 columns, with 16 px gutters. ![Communication site medium grid](../images/design-grid-Communication-site-M-Canvas-16px-gutters.png) -
- #### Large 640 x 1024 + The large size has 12 columns, with 24 px gutters. ![Communication site large grid](../images/design-grid-Communication-site-L-Canvas-24px-gutters.png) -
- #### XL 1024 x 768 + The XL size has 12 columns, with 24 px gutters. ![Communication site XL grid](../images/design-grid-Communication-site-XL-Canvas-24px-gutters.png) -
- #### XXL 1366 x 768 + The XXL size has 12 columns, with 32 px gutters. ![Communication site XXL grid](../images/design-grid-Communication-site-XXL-Canvas-32px-gutters-maxwidth-1204.png) -
- #### XXXL 1920 x 1080 + The XXXL size has 12 columns, with 32 px gutters. ![Communication site XXXL grid](../images/design-grid-Communication-site-XXXL-Canvas-32px-gutters-maxwidth-1204.png) -
- #### Communication site multicolumn pages and web parts + Web parts scale horizontally depending on the page layout. This example shows a communication site and web parts for single to three column layouts. ![Communication site multi-column with web parts](../images/design-grid-Communciation-site-web-parts.png) +## Breakpoints - -## Breakpoints - -To create a smooth flowing experience between screen sizes, the SharePoint UI should adapt layouts for the following breakpoint widths: +To create a smooth flowing experience between screen sizes, the SharePoint UI should adapt layouts for the following breakpoint widths: - 320 px - 1024 px - 1366 px - 1920 px - + Within these breakpoints, you should take into consideration how your content shifts when the viewport size becomes optimized for the nearest breakpoint. Note that this diagram is for illustration only and is not pixel accurate. ![SharePoint diagram showing breakpoints](../images/design-grid-breakpoints.png) -
- The responsive grid for both team sites and communication sites adjusts when going from large breakpoints to mobile breakpoints. This optimizes the site for the device and screen size. The following table describes the grid sizes at various breakpoints based on popular device sizes. @@ -176,11 +152,7 @@ The responsive grid for both team sites and communication sites adjusts when goi | 1600 | Web 1600x900 | XX-Large | 12 | 32 | 3 | | 1920 | Web 1920x1080 | XXX-Large | 12 | 32 | 3 | -
- ## See also - [Design toolkit and assets](https://developer.microsoft.com/fabric#/resources) - [Designing great SharePoint experiences](design-guidance-overview.md) - - diff --git a/docs/design/key-web-part-examples.md b/docs/design/key-web-part-examples.md index ab599f1db..e1ba4a44b 100644 --- a/docs/design/key-web-part-examples.md +++ b/docs/design/key-web-part-examples.md @@ -1,15 +1,15 @@ --- title: Key web part examples -description: A visual overview of Communication site and Team site templates. -ms.date: 5/08/2018 -localization_priority: Priority +description: A visual overview of Communication site and Team site templates. +ms.date: 06/28/2022 +ms.localizationpriority: high --- # Key web part examples -Web parts are the building blocks of your page. +Web parts are the building blocks of your page. -This is a visual overview of Communication site and Team site templates, highlighting how web parts work together to create a coherent overall design. Use these pages as reference when designing a SharePoint web part. +This is a visual overview of Communication site and Team site templates, highlighting how web parts work together to create a coherent overall design. Use these pages as reference when designing a SharePoint web part. It is important to consider how the web part will look and function when sitting next to other web parts on a page. Follow the patterns in this documentation and on the [Office UI Fabric site](https://developer.microsoft.com/fabric) to ensure consistency in layout and grid alignment, font size and hierarchy, commanding, empty states, and more. @@ -19,22 +19,20 @@ It is important to consider how the web part will look and function when sitting The Topic design is used when you have a lot of information to share, such as news, events, reports, and other content. It is built from the Hero, News, Events, Highlighted content, Quick links, and People web parts. -![Topic site homepage](../images/sites_topic.png) +![Topic site homepage](../images/sites_topic.png) ### Showcase design The Showcase design is used to feature a product, team, or event. It leverages the Hero and Image gallery web parts to show rich visual content. -![Showcase site homepage](../images/sites_showcase.png) +![Showcase site homepage](../images/sites_showcase.png) ## Team sites The Team site design is the default layout for any new team. It features the News, Quick links, Highlighted content, and Document library web parts. -![Team site homepage](../images/sites_teamsite.png) +![Team site homepage](../images/sites_teamsite.png) These example site and web part designs have been added to the SharePoint toolkit and can be used as reference when designing web parts. For more information, see the [SharePoint toolkit](https://developer.microsoft.com/fabric#/resources). - - diff --git a/docs/design/layout-patterns.md b/docs/design/layout-patterns.md index 699db6cc8..0d8891ca4 100644 --- a/docs/design/layout-patterns.md +++ b/docs/design/layout-patterns.md @@ -1,13 +1,13 @@ --- title: Layout patterns description: Find common SharePoint web part layout types and responsive patterns. -ms.date: 08/24/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint web part layouts -SharePoint uses a number of different layout types for web parts. The most common are grid, list, filmstrip, carousel, and compact. Each one of these five layouts serves a different purpose, depending on the layout, breakpoints, and content density of a page. +SharePoint uses a number of different layout types for web parts. The most common are grid, list, filmstrip, carousel, and compact. Each one of these five layouts serves a different purpose, depending on the layout, breakpoints, and content density of a page. When selecting a layout that works best for your web part, consider the type of content you are displaying. Is it highly visual or rich in text and data? Determine how much space is needed on the page for enough content to be displayed. Consider shortening long descriptions to optimize for displaying more items to the user. Remember that you can use the [property pane](reactive-and-nonreactive-web-parts.md) to let authors have control over how much content is displayed. diff --git a/docs/design/placeholders-and-fallbacks.md b/docs/design/placeholders-and-fallbacks.md index 41140447f..5354450c2 100644 --- a/docs/design/placeholders-and-fallbacks.md +++ b/docs/design/placeholders-and-fallbacks.md @@ -1,14 +1,14 @@ --- title: Placeholders and fallbacks in SharePoint web parts description: Add placeholders to SharePoint web parts as a fallback if an issue occurs loading content or data. -ms.date: 01/23/2018 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # Placeholders and fallbacks in SharePoint web parts -You can add placeholders to SharePoint web parts that can also be used as a fallback if an issue occurs loading content or data for a web part. The web part name and description are automatically added from the metadata submitted with the web part. +You can add placeholders to SharePoint web parts that can also be used as a fallback if an issue occurs loading content or data for a web part. The web part name and description are automatically added from the metadata submitted with the web part. You can add a button that users can select to return to a state where they can configure the web part. diff --git a/docs/design/reactive-and-nonreactive-web-parts.md b/docs/design/reactive-and-nonreactive-web-parts.md index 87a981c83..38935ba67 100644 --- a/docs/design/reactive-and-nonreactive-web-parts.md +++ b/docs/design/reactive-and-nonreactive-web-parts.md @@ -1,47 +1,41 @@ --- title: Reactive and nonreactive SharePoint web parts description: Reactive web parts are client-side only; nonreactive web parts have elements that require a server to operate. -ms.date: 01/23/2018 -localization_priority: Priority +ms.date: 03/08/2023 +ms.localizationpriority: high --- # Reactive and nonreactive SharePoint web parts Reactive web parts are client-side only; nonreactive web parts have elements that require a server to operate. We recommend that you build your SharePoint web parts to be reactive because that best fits the UX model and WYSIWYG principles for authoring. However, it might not be possible or cost-effective in all cases to build reactive web parts. - ## Reactive web parts Reactive web parts are fully client-side web parts. This means that each component configured in the property pane reflects the change made within the web part on the page. For example, for the To-Do List web part, unchecking “Completed Tasks” hides this view in the web part. -A reactive web part +![A reactive web part](../images/design-reactive-01.png) ## Nonreactive web parts -Nonreactive web parts are not fully client-side; generally, one or more properties need to make a call to set/pull or store data on a server. For nonreactive web parts, you should enable the **Apply** button at the bottom of the property pane. -You can also customize the **Apply** button to be a more specific action. +Nonreactive web parts aren't fully client-side; generally, one or more properties need to make a call to set/pull or store data on a server. For nonreactive web parts, you should enable the **Apply** button at the bottom of the property pane. -A nonreactive web part with Apply and Cancel buttons +You can also customize the **Apply** button to be a more specific action. -
+![A nonreactive web part with Apply and Cancel buttons](../images/design-reactive-02.png) The following examples show nonreactive web parts in the context of the [three property pane structures](design-a-web-part.md). -**Single pane example** - -A nonreactive web part with a single pane property structure - -
+### Single pane example -**Accordion groups example** +![A nonreactive web part with a single pane property structure](../images/design-reactive-03.png) -A nonreactive web part with an according groups pane property structure +### Accordion groups example -
+![A nonreactive web part with an according groups pane property structure](../images/design-reactive-04.png) -**Steps pane example** +### Steps pane example -A nonreactive web part with a steps pane property structure +![A nonreactive web part with a steps pane property structure](../images/design-reactive-05.png) ## See also diff --git a/docs/design/semantic_slots.md b/docs/design/semantic_slots.md index d45201a01..a6e5632b2 100644 --- a/docs/design/semantic_slots.md +++ b/docs/design/semantic_slots.md @@ -1,13 +1,13 @@ --- title: Designing for section backgrounds using semantic slots description: Learn how to design your web part to take advantage of section backgrounds using semantic slots. -ms.date: 12/06/2018 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # Designing for section backgrounds using semantic slots -When designing web parts for section backgrounds, you can use Office UI Fabric’s semantic slot system to guarantee accessibility and to enforce consistency across SharePoint sites. Semantic slots target customizations of specific page elements in order to align color usage and interaction patterns. They also allow you the flexibility to add or assign multiple palette colors for your components so they look great on all section backgrounds. This article will provide examples for semantic slots and how to incorporate them into your web part designs. Before getting started, you should be familiar with [how to design a SharePoint web part](https://docs.microsoft.com/sharepoint/dev/design/design-a-web-part) in order to understand the basic structure of web parts. You should also be familiar with [themes and colors in SharePoint](https://docs.microsoft.com/sharepoint/dev/design/themes-colors). +When designing web parts for section backgrounds, you can use Office UI Fabric’s semantic slot system to guarantee accessibility and to enforce consistency across SharePoint sites. Semantic slots target customizations of specific page elements in order to align color usage and interaction patterns. They also allow you the flexibility to add or assign multiple palette colors for your components so they look great on all section backgrounds. This article will provide examples for semantic slots and how to incorporate them into your web part designs. Before getting started, you should be familiar with [how to design a SharePoint web part](design-a-web-part.md) in order to understand the basic structure of web parts. You should also be familiar with [themes and colors in SharePoint](themes-colors.md). ## Section background @@ -15,7 +15,7 @@ Section background is a feature that applies background color to a canvas secti ## Variant vs. Section background -A variant describes different values of color generated from an existing theme. A variant will share the same set of colors as the original theme it was generated from, but will apply those colors differently. See [Office UI Fabric variant documentation](https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/variants/README.md) for more detail. +A variant describes different values of color generated from an existing theme. A variant will share the same set of colors as the original theme it was generated from, but will apply those colors differently. See [@fluentui/scheme-utilities](https://github.com/microsoft/fluentui/blob/master/packages/scheme-utilities/README.md) for more detail. A Section Background allows the user to apply a variant color from the theme to a canvas section. Both concepts share "Neutral", "Soft", and "Strong" options and can be used interchangeably when describing color usage. @@ -25,48 +25,25 @@ A semantic slot is a theming slot that targets specific page elements. A Offic For example, default text uses the "bodyText" semantic slot. On the None, Neutral, and Soft section backgrounds, bodyText is assigned neutralPrimary. On the Strong section background, the palette color of bodyText changes to white. Semantic slots can be assigned palette colors for all variants in dark themes as well. -In the table below, you can see all eight palette colors defined for the bodyText slot. +In the table below, you can see all eight palette colors defined for the bodyText slot. ![Example table showing semantic slots on light and dark theme variants](../images/doc-semantic-slot-940px-table.png) -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Light themes Dark themes
NoneneutralPrimary #333333neutralPrimary #ffffff
NeutralneutralPrimary #333333neutralPrimary #ffffff
SoftneutralPrimary #333333neutralPrimary #ffffff
Strongwhite #ffffffwhite #1f1f1f
-
- -! Note -The current semantic slot list is defined by commonly used design patterns in SharePoint. We want to avoid creating case-specific semantic slots. When designing a new web part, consider aligning to an existing design pattern. Office UI Fabric's policy is that semantic slots may never be removed from the list, so any additions are permanent. +| Weight | Light themes | Dark themes | +| ------- | ---------------------- | ---------------------- | +| None | neutralPrimary #333333 | neutralPrimary #ffffff | +| Neutral | neutralPrimary #333333 | neutralPrimary #ffffff | +| Soft | neutralPrimary #333333 | neutralPrimary #ffffff | +| Strong | white #ffffff | white #ffffff | + +> [!NOTE] +> The current semantic slot list is defined by commonly used design patterns in SharePoint. We want to avoid creating case-specific semantic slots. When designing a new web part, consider aligning to an existing design pattern. Office UI Fabric's policy is that semantic slots may never be removed from the list, so any additions are permanent. ## Identifying semantic slots in your designs -Semantic slots should be assigned based on the function of a page element. The name of a semantic slot can quickly tell you how it’s meant to be used. You can find all existing semantic slots and their use case examples in the [Fabric semantic colors documentation](https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/styling/src/interfaces/ISemanticColors.ts). +Semantic slots should be assigned based on the function of a page element. The name of a semantic slot can quickly tell you how it’s meant to be used. You can find all existing semantic slots and their use case examples in the [Fabric semantic colors documentation](https://developer.microsoft.com/fluentui#/styles/web/colors/theme-slots). -Fabric palette colors should be referenced from your site theme’s color ramp. If your site is using a SharePoint out of the box theme, you can reference [SharePoint theme color ramps](https://fluentfabric.azurewebsites.net/#/color/products). If your site is using a custom theme, you can generate a unique color ramp using the [Fabric theme generator](https://developer.microsoft.com/fabric#/styles/themegenerator). +Fabric palette colors should be referenced from your site theme’s color ramp. If your site is using a SharePoint out of the box theme, you can reference [SharePoint theme color ramps](https://fluentfabric.azurewebsites.net/#/color/products). If your site is using a custom theme, you can generate a unique color ramp using the [Fluent UI Theme Designer](https://aka.ms/themedesigner). ![Example of redlines for a web part in the None section background](../images/doc-semantic-slot-1.png) diff --git a/docs/design/showcase-web-part.md b/docs/design/showcase-web-part.md index ce8eb74f0..09965c263 100644 --- a/docs/design/showcase-web-part.md +++ b/docs/design/showcase-web-part.md @@ -1,86 +1,61 @@ --- title: "SharePoint web part design showcase: Create a To-Do list property pane" description: Create a To-Do list web part that uses a single pane and is reactive. -ms.date: 01/23/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint web part design showcase: Create a To-Do list property pane This article describes how to create a To-Do list web part. This example uses the single pane [property pane type](design-a-web-part.md) and is [reactive](reactive-and-nonreactive-web-parts.md) and based on the [Office UI Fabric](https://developer.microsoft.com/fabric) responsive grid. - ## Create a To-Do list web part 1. Add a description to help users understand more about the web part and its properties. - In this example, the description is "Select a source for your to-dos and customize the display for the list of tasks." - - ![Adding a description](../images/design-showcase-01.png) - -
- -2. Add a Fabric [drop-down component](https://developer.microsoft.com/fabric#/components/dropdown) connected to a list. - - ![Adding a Fabric dropdown](../images/design-showcase-02.png) - -
- -3. Add a Fabric [checkbox component](https://developer.microsoft.com/fabric#/components/checkbox) to display completed tasks. - - ![Adding a Fabric check box](../images/design-showcase-03.png) - -
+ In this example, the description is "Select a source for your to-dos and customize the display for the list of tasks." -4. Add two more check boxes to control display options. + ![Adding a description](../images/design-showcase-01.png) - ![Adding two more Fabric check boxes](../images/design-showcase-04.png) +1. Add a Fabric [drop-down component](https://developer.microsoft.com/fabric#/components/dropdown) connected to a list. -
+ ![Adding a Fabric dropdown](../images/design-showcase-02.png) -5. Add a Fabric [slider](https://developer.microsoft.com/fabric#/components/slider) for the maximum number of items to display. +1. Add a Fabric [checkbox component](https://developer.microsoft.com/fabric#/components/checkbox) to display completed tasks. - ![Adding a Fabric slider](../images/design-showcase-05.png) + ![Adding a Fabric check box](../images/design-showcase-03.png) -
+1. Add two more check boxes to control display options. -6. Next, the author of the page selects a list or manually adds tasks to prepopulate the To-Do list web part. + ![Adding two more Fabric check boxes](../images/design-showcase-04.png) - ![Select a list in pane](../images/design-showcase-06.png) +1. Add a Fabric [slider](https://developer.microsoft.com/fabric#/components/slider) for the maximum number of items to display. -
+ ![Adding a Fabric slider](../images/design-showcase-05.png) - ![Select a list in pane expanded](../images/design-showcase-07.png) +1. Next, the author of the page selects a list or manually adds tasks to prepopulate the To-Do list web part. -
+ ![Select a list in pane](../images/design-showcase-06.png) - ![Manual addition of tasks to list](../images/design-showcase-08.png) + ![Select a list in pane expanded](../images/design-showcase-07.png) -
+ ![Manual addition of tasks to list](../images/design-showcase-08.png) -7. The web part shows an indicator of items loading onto the page. +1. The web part shows an indicator of items loading onto the page. - ![Indicator of items](../images/design-showcase-09.png) + ![Indicator of items](../images/design-showcase-09.png) -
+1. Items from the list load. -8. Items from the list load. + ![List items loading](../images/design-showcase-10.png) - ![List items loading](../images/design-showcase-10.png) + When the new tasks are loaded, they fade into view by using animation components from Office UI Fabric. -
+ ![New tasks loaded](../images/design-showcase-11.png) - When the new tasks are loaded, they fade into view by using animation components from Office UI Fabric. +1. The property pane controls the UI. Tasks with pivots enabled are displayed via the Display check boxes in the property pane. - ![New tasks loaded](../images/design-showcase-11.png) - -
- -9. The property pane controls the UI. Tasks with pivots enabled are displayed via the Display check boxes in the property pane. - - ![Property pane controlling web part items](../images/design-showcase-12.png) - -
+ ![Property pane controlling web part items](../images/design-showcase-12.png) ## Responsive views @@ -88,20 +63,14 @@ The following example shows the 2/3 column view of the web part. ![Two thirds column view](../images/design-showcase-13.png) -
- The following example shows the 1/3 column view of the web part. ![One third column view](../images/design-showcase-14.png) -
- The following example shows the mobile (read-only) view of the web part. ![Mobile view of the to-do list web part](../images/design-showcase-15.png) -
- ## See also - [Designing great SharePoint experiences](design-guidance-overview.md) diff --git a/docs/design/themes-colors.md b/docs/design/themes-colors.md index e8dfac7c5..d2eee4ec8 100644 --- a/docs/design/themes-colors.md +++ b/docs/design/themes-colors.md @@ -1,8 +1,8 @@ --- title: SharePoint themes and colors description: Design principles that help form the current SharePoint themes and color palette. -ms.date: 05/21/2018 -localization_priority: Priority +ms.date: 09/04/2024 +ms.localizationpriority: high --- # SharePoint themes and colors @@ -19,90 +19,13 @@ The SharePoint color palette is now optimized for screens and devices. In additi Neutral colors recede into the background to let our products shine. They allow brand colors to pop when we need to draw attention to content. When coupling neutrals with brand colors, make sure there is suitable contrast between them. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Neutral greysblack: #000000
neutralDark: #212121
neutralPrimary: #333333
neutralPrimaryAlt: #3c3c3c
neutralSecondary: #666666
neutralTertiary: #a6a6a6
neutralTertiaryAlt: #c8c8c8
neutralQuaternary: #d0d0d0
neutralQuaternaryAlt: #dadada
neutralLight: #eaeaea
neutralLighter: #f4f4f4
neutralLighterAlt: #f8f8f8
white: #ffffff
-
+![Neutral greys](../images/sharepoint-neutralgreys.png) ## Shades and tints After you select a color, light and dark shades of the accent color are created based on HSB values of color luminosity. Web parts and apps can use shade variations to create visual hierarchy and provide an indication of interaction. -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Theme primary colorsthemeDarker: #004578
themeDark: #005a9e
themeDarkAlt: #106ebe
themePrimary: #0078d4
themeSecondary: #2b88d8
themeTertiary: #71afe5
themeLight: #c7e0f4
themeLighter: #deecf9
themeLighterAlt: #eff6fc
- -
- +![Theme primary colors](../images/sharepoint-theme-primary.png) ## Dark themes @@ -110,22 +33,6 @@ SharePoint includes a palette that supports dark themes. The SharePoint-provided ![SharePoint dark theme color palette, Red EF6950, Yellow FFC83D, Green 00b294, Blue 3a96dd, Purple 9c89e9, Grey b1adab](../images/sharepoint-themes-dark.png) -## Principles - -The following design principles helped form the current SharePoint themes and color palette. - -### Guided -Our theming system works at a global level so that updates can be made consistently across each site, allowing users to optimize their websites effortlessly. Our theming system operates in a controlled environment so that successful outcomes can be optimized quickly. - -### Smart and efficient -Our theming system expedites the site creation process by using smart algorithms to generate options that maximize aesthetic choices. - -### Professional -Our themes embody a professional look and feel that ensures coherency and conveys the brand of our enterprise audiences. - -### Accessible -Our built-in accessibility checker ensures universal design at all levels of default themes. For users who decide to customize, we provide helpful guidelines to design for accessibility. - ## See also - [Accessibility](accessibility.md) diff --git a/docs/design/ui-text-for-web-parts.md b/docs/design/ui-text-for-web-parts.md index 9be1c6ec3..5dfd50870 100644 --- a/docs/design/ui-text-for-web-parts.md +++ b/docs/design/ui-text-for-web-parts.md @@ -1,64 +1,56 @@ --- title: UI text guidelines for SharePoint web parts description: Use simple, understandable, and concise UI text to create effective web parts in SharePoint. -ms.date: 01/23/2018 -localization_priority: Normal +ms.date: 03/08/2023 +ms.localizationpriority: medium --- # UI text guidelines for SharePoint web parts - -One aspect of creating effective web parts in SharePoint is to use simple, understandable, and concise UI text. By keeping your message clear and easy to understand, you ensure that customers move through your experiences quickly and can identify the content they are looking for. This article provides guidance for writing UI text for key areas within SharePoint web parts. +One aspect of creating effective web parts in SharePoint is to use simple, understandable, and concise UI text. By keeping your message clear and easy to understand, you ensure that customers move through your experiences quickly and can identify the content they're looking for. This article provides guidance for writing UI text for key areas within SharePoint web parts. ## Capitalization -Use sentence casing (first letter of first word is capitalized, the rest all lowercase) for all UI elements, including buttons, page titles, and control labels. - +Use sentence casing (first letter of first word is capitalized, the rest all lowercase) for all UI elements, including buttons, page titles, and control labels. Always capitalize: - The first word of a new sentence. - The word following a colon in a title or heading. For example, "Step 1: Begin by entering your account information." -- Proper nouns, such as the names of people, cities, and so on. - -An image web part with sentence-style capitalization highlighted +- Proper nouns, such as the names of people, cities, and so on. -
+![Screenshot of an image alternative-text web part with sentence-style capitalization highlighted](../images/design-uitext-01.png) -An image web part with sentence-style capitalization highlighted +![Screenshot of an image gallery add web part with sentence-style capitalization highlighted](../images/design-uitext-02.png) ## Punctuation Follow the basic rules of punctuation to avoid grammatical errors in your experience. The following table provides guidance and reminders about what punctuation to use when, and why. -|Punctuation |Guidance |Example | -|-------------|------------------------------------------------|-----------------| -|Colons (:) | Use colons if you are introducing a list in the web part description.
Don't use colons in UI labels.| Choose one of the following: Cats, Dogs, Quokkas | -|Commas (,) | Use serial commas (including before the word "and"). |I like cats, birds, and dogs. | -|Ellipses (…)| Use ellipses to show truncation and for progress indicator strings.
Don't use ellipses to indicate that the user must make further choices.|Truncation: Last modified by John Armstr…
Progress indicator: Uploading… | -|Periods (.) | Use periods as you normally would for descriptions.
Don't use periods in titles, headings, or labels. Don't use periods for radio button options or check boxes. | Select the content that you want to highlight and how you want it displayed. Use a filter to narrow your selection. | - - +| Punctuation | Guidance | Example | +| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| Colons (:) | Use colons if you're introducing a list in the web part description.
Don't use colons in UI labels. | Choose one of the following: Cats, Dogs, Quokkas | +| Commas (,) | Use serial commas (including before the word "and"). | I like cats, birds, and dogs. | +| Ellipses (…) | Use ellipses to show truncation and for progress indicator strings.
Don't use ellipses to indicate that the user must make further choices. | Truncation: Last modified by John Armstr…
Progress indicator: Uploading… | +| Periods (.) | Use periods as you normally would for descriptions.
Don't use periods in titles, headings, or labels. Don't use periods for radio button options or check boxes. | Select the content that you want to highlight and how you want it displayed. Use a filter to narrow your selection. | ## Voice and tone Crafting the right tone in your product communication is essential to building a strong, lasting relationship with your audience. Try to keep your words crisp and clear, warm and relaxed, and approachable. How you talk to your audience influences how they engage with your site and content, and how much value they derive from it. -**Do:** +### Do -- Use a casual, conversational tone in the UI. -- Use contractions. For example, use "can't" instead of "cannot". +- Use a casual, conversational tone in the UI. +- Use contractions. For example, use "can't" instead of "can't". - Read your UI text out loud to test the tone. Does it sound like everyday language? -- Use simple words. -- Remove technical details if they're not relevant to the user experience. -- Use "Please" only if you are inconveniencing the user. Avoid overuse. -- Use "Sorry" only in error messages in SharePoint that result in serious problems for the customer. +- Use simple words. +- Remove technical details if they're not relevant to the user experience. +- Use "Please" only if you're inconveniencing the user. Avoid overuse. +- Use "Sorry" only in error messages in SharePoint that result in serious problems for the customer. +### Don't -**Don't:** - -- Clutter the UI text with unnecessary repetition. Make every word meaningful. - +- Clutter the UI text with unnecessary repetition. Make every word meaningful. ## Pronouns @@ -66,25 +58,21 @@ Avoid pronouns in UI elements if possible. If you can say something equally well If your design does warrant using pronouns, apply the following guidelines to make sure that you're using them correctly. -**Do:** +### Do - Use second person ("you" or "your") when you're presenting something that belongs to the user. For example, "Your drafts" or "Your images". - Use first person ("me" or "my") for UI in which the user instructs the service to do something. For example, "Alert me when someone responds to my post." - Use "they" or "their" as a singular possessive modifier to avoid awkward "he/she" or "his/her" constructs. Ideally, rewrite the sentence as plural if possible. - Avoid using "them"; instead, use words like "someone" or "people". For example, "Enter a user name and domain to give someone permission to use this PC." -An image showing the correct use of the second person you and the incorrect use of the third person users in the UI - -
+![An image showing the correct use of the second person you and the incorrect use of the third person users in the UI](../images/design-uitext-03.png) -An image showing the correct use of the UI text Select the page you want people to see first +![An image showing the correct use of the UI text Select the page you want people to see first](../images/design-uitext-04.png) -**Don't:** +### Don't - Use third person references, as they sound impersonal and can create a disconnected customer experience. Instead of saying "Users can change the layout", use a phrase like "You can change the layout". - - ## Error messages Error conditions are inherent in any software or service. Your error messages can affect the overall user satisfaction with the product. A good error message should do the following: @@ -93,50 +81,44 @@ Error conditions are inherent in any software or service. Your error messages ca - Provide a workaround or resolution suggestions. - Show empathy. - - The following is an example of an error message that occurs when a user tries to edit a page that's checked out by another user. - -| You can't edit right now | -|-------------------------------------------------------------------------| +| You can't edit right now | +| ------------------------------------------------------------------------------- | | Another user is currently editing this page. Please try again in a few minutes. | - ## Links to help articles Make an effort to link strategically to help articles. Try to anticipate where the user might need help, and then include a link to the help article close to that UI element. The following are some key things to remember when you place help article links in your UI. -**Do:** - -- Keep the in-product help links specific. Ensure that the target article is appropriate. When the user opens the article, they should be able to locate the information they need. -- Use natural language for your hyperlinks. +### Do - +- Keep the in-product help links specific. Ensure that the target article is appropriate. When the user opens the article, they should be able to locate the information they need. +- Use natural language for your hyperlinks. -**Don’t:** +### Don't - Put a help article link next to every UI element. This results in visual noise. - Include multiple links that go to the same target in the same UI. -- Use "click here" for the text for your hyperlink. +- Use "click here" for the text for your hyperlink. -An image of the More information and examples as the help link text +![An image of the More information and examples as the help link text](../images/design-uitext-05.png) ## Hint text Hint text, or ghost text, is the text element you display in a UI element, typically a text box, to help the user interact with the UI. The hint text gives information about what the user should enter. For example, it might mention field restrictions or show an example. -**Do:** +### Do - Use hint text sparingly, and only if it helps the user. Not all UI elements require hint text. For some complex fields, hint text can help provide more context and clarity. For example, if you have a field that requires the user to enter a secured URL, the hint text https://www.example.com might be more helpful than the text **Enter secure URL here.** -**Don't** +### Don't - Repeat the label. For example, if you have a text box with the label **Name**, the hint text **Enter name** is redundant and potentially confusing. -The following hint text is for the embed web part. The text field can accept a secure website address or an iframe embed code. The text shows an example of both. +The following hint text is for the embed web part. The text field can accept a secure website address or an ` + + +``` + +## Load the document preview dynamically + +If you intend to dynamically load the preview in the same page without leaving it, you might get a CORS error if you attempt to access the Microsoft Graph endpoint directly from a script from your page. + +One way to solve this problem is to create an endpoint in your application that makes the request and returns the url. + +For example, your server-side code should first obtain the document's preview url: + +```csharp +[HttpGet] +[AuthorizeForScopes(Scopes = new string[] { "Files.Read.All" })] +public async Task> GetPreviewUrl(string driveId, string itemId) +{ + // Obtain tokens for the the request + // Use the function created in the first step + return url + "&nb=true"; //Use nb=true to suppress banner +} +``` + +The client-side application can then use the browser's `fetch` API to request and inject the url into the `iframe`: + +```javascript +async function preview(driveId, itemId) { + const url = `/GetPreviewUrl?driveId=${driveId}&itemId=${itemId}`; + const response = await fetch(url, { + credentials: 'include', + }).then(response => response.text()); + + document.getElementById('preview').src = response + "&nb=true"; //Use nb=true to suppress banner +} +``` diff --git a/docs/embedded/development/tutorials/using-webhooks.md b/docs/embedded/development/tutorials/using-webhooks.md new file mode 100644 index 000000000..b0511b294 --- /dev/null +++ b/docs/embedded/development/tutorials/using-webhooks.md @@ -0,0 +1,113 @@ +--- +title: Using Webhooks +description: Use webhooks with SharePoint Embedded. +ms.date: 03/03/2025 +ms.localizationpriority: high +--- + +# Using Webhooks + +## Set Up Webhooks with SharePoint Embedded + +Webhooks are automated messages that are transmitted by an application when a trigger is activated. They can be used in SPE to enable the automation of workflows, the integration of systems, and to respond to events in real-time. + +You'll use webhooks to invoke the Azure Cognitive Services APIs from the application whenever an existing file is updated, or a new file is uploaded. + +To set up webhooks with your [current SharePoint Embedded application](/training/modules/sharepoint-embedded-create-app/), you need to: + +1. Create and register a webhook endpoint to get notifications whenever there's a change in your container. This will be done using REST APIs. +1. Connect to Graph and subscribe to changes. You can expose your application to the internet by either running it locally or deploying it on the cloud. For this tutorial, you'll be employing the former by utilizing ngrok and then subscribing to the changes by making a POST call. +1. Perform any desired action by handling the webhook data. One such use case is covered in [Enabling document processing with Azure Cognitive Services tutorial](./doc-processing-acs.md). + +![using webhooks schema](../../images/Using-Webhooks.png) + +> [!TIP] +> To learn more about the Microsoft Graph APIs used in this tutorial, see [Create subscription](/graph/api/subscription-post-subscriptions). + +## Create and register a webhook + +Open the **index.ts** file and add an endpoint `onReceiptAdded`: + +```typescript +server.post('/api/onReceiptAdded', async (req, res, next) => { + try { + const response = await onReceiptAdded(req, res); + res.send(200, response) + } catch (error: any) { + res.send(500, { message: `Error in API server: ${error.message}` }); + } + next(); +}); +``` + +You also need to add the query parser plugin at the top of this file so that it runs at server startup: + +```typescript +server.use(restify.plugins.bodyParser(), restify.plugins.queryParser()); +``` + +Create **onReceiptAdded.ts** and implement the method `onReceiptAdded` to read `validationToken` and `driveId`. `validationToken` is required when Microsoft Graph makes a one-time call to verify the endpoint upon creation of the webhook subscription. `driveId` is the container-id for which the subscription is created. + +```typescript +require('isomorphic-fetch'); + +export const onReceiptAdded = async (req: Request, res: Response) => { + + const validationToken = req.query['validationToken']; + if (validationToken) { + res.send(200, validationToken, {"Content-Type":"text/plain"}); + return; + } + + const driveId = req.query['driveId']; + if (!driveId) { + res.send(200, "Notification received without driveId, ignoring", {"Content-Type":"text/plain"}); + return; + } + + console.log(`Received driveId: ${driveId}`); + + res.send(200, ""); + return; +} +``` + +## Connect to Graph and subscribe to changes + +Follow the [documentation](https://ngrok.com/docs/getting-started/) to create a tunnel for your backend server using ngrok. + +After starting the app, run the following command in a terminal: + +```powershell +ngrok http 3001 +``` + +On successful completion, you should get the following output. The public-facing endpoint for the app is highlighted in the red rectangle: + +![ngrok registration](../../images/ngrok-registration.png) + +Once the tunneling is active, you can subscribe to delta changes in the container by adding the webhook URL. To do that, open Postman and make the following `POST` request with the appropriate graph access token and `notificationUrl` with the `driveId` appended as a query parameter to ensure that you get notifications for changes only in the desired container. + +```json +POST https://graph.microsoft.com/v1.0/subscriptions +{ + "changeType": "updated", + "notificationUrl":"https://5ac2-2404-f801-8028-3-691a-87b2-d309-545b.ngrok-free.app/api/onReceiptAdded?driveId={{ContainerId}}", + "resource": "drives/{{ContainerId}}/root", + "expirationDateTime": "2024-01-20T03:58:34.088Z", + "clientState": "" +} +``` + +You can use the following code snippet for setting the max possible expiration time of 4230 minutes from the current time by adding this to the "Pre-request Script" section. It will set an environment variable that can be used in the request body. + +```javascript +var now = new Date() +var duration = 1000 * 60 * 4230; // max lifespan of driveItem subscription is 4230 minutes +var expiry = new Date(now.getTime() + duration); +var expiryDateTime = expiry.toISOString(); + +pm.environment.set("ContainerSubscriptionExpiry", expiryDateTime); +``` + +At this point, if you add/update any file in the container, you'll get a notification at the previously added endpoint (`/api/onReceiptAdded`) and a log message at the console: `Received driveId: ` diff --git a/docs/embedded/getting-started/containertypes.md b/docs/embedded/getting-started/containertypes.md new file mode 100644 index 000000000..f21edc78f --- /dev/null +++ b/docs/embedded/getting-started/containertypes.md @@ -0,0 +1,207 @@ +--- +title: Create New SharePoint Embedded Container Types +description: This article explains how Container Types work and the steps to create new Container Types. +ms.date: 03/03/2025 +ms.localizationpriority: high +--- + +# SharePoint Embedded Container Types + +A container type is a SharePoint Embedded resource that defines the relationship, access privileges, and billing accountability between a SharePoint Embedded application and a set of containers. Also, the container type defines behaviors on the set of containers. + +Each container type is strongly coupled with one SharePoint Embedded application, which is referred to as the owning application. The owning application developer is responsible for creating and managing their container types. SharePoint Embedded mandates a 1:1 relationship between owning application and a container type. + +Container type is represented on each container instance as an immutable property (ContainerTypeID) and is used across the entire SharePoint Embedded ecosystem, including: + +- **Access authorization**: A SharePoint Embedded application must be associated with a container type to get access to container instances of that type. Once associated, the application has access to all container instances of that type. The actual access privilege is determined by the application-ContainerTypeID permission setting. The owning application by default has full access privilege to all container instances of the container type it's strongly coupled with. Learn more about [SharePoint Embedded Authorization](../development/auth.md). +- **Easy exploration**: Container type can be created for trial purposes, allowing developers to explore SharePoint Embedded application development and assess its features for free. +- **Billing**: Container types for non-trial purposes are billable and must be created with an Azure Subscription. The usage of containers is metered and charged. Learn more about [metering](../administration/billing/meters.md) and the [SharePoint Embedded billing experience](../administration/billing/billingmanagement.md). +- **Configurable behaviors**: Container type defines selected behaviors for all container instances of that type. Learn more about setting [Container type configuration](../getting-started/containertypes.md#configuring-container-types). + +> [!NOTE] +> +> 1. You must specify the purpose of the container type you're creating at creation time. Depending on the purpose, you may or may not need to provide your Azure Subscription ID. A container type set for trial purposes can't be converted for production; or vice versa. +> 1. Standard and pass through container types can't be converted once created. If you want to convert a standard container type to pass through billing or vice versa, you must delete and re-create the container type. +> 1. You must use the latest version of SharePoint PowerShell to configure a container type. For permissions and the most current information about Windows PowerShell for SharePoint Embedded, see the documentation at [Intro to SharePoint Embedded Management Shell](/powershell/sharepoint/sharepoint-online/introduction-sharepoint-online-management-shell). + +## Creating Container Types + +SharePoint Embedded has 2 different Container Types you can create. + +1. [Trial Container Type](#trial-container-type) +1. [Standard Container Type](#standard-container-types-non-trial) + +### Prerequisites to create SharePoint Embedded container type + +A new container type will be created using **SharePoint Online Management Shell**: + +1. Download and install the [latest version of SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588) +1. Open SharePoint Online Management Shell from **Start** screen, type **sharepoint**, and then select **SharePoint Online Management Shell**. +1. Connect to SPO service using `Connect-SPOService` cmdlet by providing admin credentials associated with tenancy. For information on [how to use Connect-SPOService](/powershell/module/sharepoint-online/connect-sposervice), refer the linked documentation. + +### Tenant requirements + +- An active instance of SharePoint is required in your Microsoft 365 tenant. +- Users who will be authenticating into SharePoint Embedded Container Types and Containers must be in Entra ID (Members and Guests) + + > [!NOTE] + > An Office license is not required to collaborate on Microsoft Office documents stored in a container. + +### Roles and Permissions + +- The admin who sets up the billing relationship for SharePoint Embedded needs to have owner or contributor permissions on the Azure subscription. +- Admin needs to have a SharePoint Embedded Administrator or Global Admin role to operate billing cmdlets. + +### Azure Subscription + +For the standard billing container type, the global administrator or SharePoint Embedded Administrator needs to set up: + +- An existing SharePoint tenancy +- An Azure subscription in the tenancy +- A resource group attached to the Azure subscription + +## Trial Container Type + +A container type can be created for trial/development purposes and isn't linked to any Azure billing profile. This enables developers to explore SharePoint Embedded application development and assess its features for free. For trial container types, the developer tenant is the same as the consuming tenant. +Each developer can have only one container type in the trial status in their tenant at a time. The trial container type is valid for up to 30 days but can be removed at any time within this period. + +To create a container type for trial purposes, you can: + +- Use SharePoint Embedded Visual Studio Code Extension to create the container type in just a few steps. The Visual Studio Code extension registers your container type and creates containers for you. +- Use SharePoint PowerShell. You must be a SharePoint Embedded Administrator or Global Administrator to run the following cmdlet. If you're a SharePoint Administrator, grant yourself the SharePoint Embedded Admin role as well to execute these cmdlets. + + ```powershell + New-SPOContainerType [–TrialContainerType] [-ContainerTypeName] [-OwningApplicationId] [-ApplicationRedirectUrl] [] + ``` + +The following restrictions are applied to trial container types: + +- Up to five containers of the container type can be created. This includes active containers and those in the recycle bin. +- Each container has up to 1 GB of storage space. +- The container type expires after 30 days and access to any existing containers of that container type will be removed. +- The developer must permanently delete all containers of an existing container type in trial status to create a new container type for trial. This includes containers in the deleted container collection. +- The container type is restricted to work in the developer tenant. It can't be deployed in other consuming tenants. + +## Standard Container Types (non-trial) + +A standard container type in SharePoint Embedded defines the relationship, access privileges, and billing profile between an application and its containers. It establishes how the application interacts with the containers, including access permissions, and is associated with a billing profile for non-trial purposes. Each tenant can have 25 container types at a time. + +### Billing profile + +SharePoint Embedded is a consumption-based Pay-as-you-go (PAYG) offering meaning you pay only for what you use. SharePoint Embedded provides two billing models that the tenant developing the SharePoint Embedded application can select for respective container types, tailoring it to their unique business requirements. The two billing models are Standard and Pass-through billing. + +### Standard Container Type - with billing profile + +With the standard billing profile, all consumption-based charges are directly billed to the tenant who owns or develops the application. The admin in the developer tenant must establish a valid billing profile when creating a standard container type. + +![Standard](../images/1bill521.png) + +Each developer tenant can create up to five container types consisting of 1 trial container type and 4 standard container types or 5 standard container types. +Standard container types are created using the [New-SPOContainerType](/powershell/module/sharepoint-online/new-spocontainertype) cmdlet. + +You need the following to create a standard container type: + +- Use SharePoint PowerShell. You must be a SharePoint Embedded Administrator or Global Administrator to run this cmdlet. If you're a SharePoint Administrator, grant yourself the SharePoint Embedded Admin role as well to execute these cmdlets. +- An Azure subscription and a resource group must be present in the Azure portal for regular billing. +- An App registration must be created in Microsoft Entra ID. + +To create a standard container type using an Azure billing profile, use the following cmdlets: + +```powershell +New-SPOContainerType [-ContainerTypeName] [-OwningApplicationId] [-ApplicationRedirectUrl] [] +``` + +Once the container type is created, add the Azure billing profile. + +```powershell +Add-SPOContainerTypeBilling –ContainerTypeId -AzureSubscriptionId -ResourceGroup -Region +``` + +> [!NOTE] +> The user or admin who sets up a billing relationship for SharePoint Embedded must have owner or contributor permissions on the Azure subscription. +> +> Every container type must have an owning application. +> +> A single-owning app can only own one container type at a time. +> +> An Azure subscription can be attached to any number of container types. +> +> If the cmdlet above fails with a SubscriptionNotRegistered error, it is because **Microsoft.Syntex** is not registered as a resource provider in the subscription. The cmdlet will send a resource provider registration request on your behalf but it will take a few minutes to be completed. Please wait 5-10 minutes and try again until the cmdlet succeeds. + +### Standard Container Type - pass-through billing + +With pass-through billing, consumption-based charges are billed directly to the tenant registered to use the SharePoint Embedded application (consuming tenant). Admins in the developer tenant don't need to set up an Azure billing profile when creating a pass-through SharePoint Embedded container type. + +![Pass Through](../images/2bill521.png) + +For container types intended to be directly billed to a customer use the flag `-IsPassThroughBilling`. For the direct to customer billed container type, there's no need to attach a billing profile. + +To create a pass through billing, standard container type, use the following cmdlet: + +```powershell +New-SPOContainerType [-ContainerTypeName] [-OwningApplicationId] [-ApplicationRedirectUrl] [-IsPassThroughBilling] [] +``` + +Once the container type is [registered](../getting-started/register-api-documentation.md) in the consuming tenant, the consuming tenant admin (SharePoint Admin or Global Admin) needs to set up the billing profile in the consuming tenant to use the SharePoint Embedded application. + +#### Set Up Billing Profile in Consuming Tenant + +1. In [Microsoft 365 admin center](https://admin.microsoft.com/), select **Setup**, and the view the **Billing and licenses** section. Select **Activate pay-as-you-go services.** + + ![Microsoft 365 admin center Files and Content](../images/SyntexActivatePAYGSetup.png) + +1. Select **Go to Pay as you go services**. +1. Select **Apps** under **Syntex services for**, select **Apps** and **SharePoint Embedded** + + ![Microsoft 365 admin center SharePoint Embedded Billing setting](../images/SyntexPAYGActivateSPE.png) + + > [NOTE] + The subscription configured in the Syntex services will reflect the consuming charges in the Azure billing portal. + +1. [Register the container type](#registering-container-types) using the App only authentication token. + +## Configuring Container Types + +The Developer Admin can set selected settings on the SharePoint Embedded container types created by using this PowerShell cmdlet. + +This cmdlet allows admins to set [Microsoft 365 content discoverability](../development/content-experiences/user-experiences-overview.md) and [sharing](../development/sharing-and-perm.md) settings on container types. The setting applies to all container instances of the container type: + +```powershell +Set-SPOContainerTypeConfiguration -ContainerTypeId 4f0af585-8dcc-0000-223d-661eb2c604e4 -DiscoverabilityDisabled $False +``` + +## Viewing Container Types + +The Developer Admin can view all the SharePoint Embedded container types they created on their tenant using `Get-SPOContainerType`. This cmdlet retrieves and returns the list of container types created for a SharePoint Embedded Application in the tenant. + +```powershell +Get-SPOContainerType [] +``` + +Example output of the `Get-SPOContainerType` cmdlet + +```powershell +ContainerTypeId : 4f0af585-8dcc-0000-223d-661eb2c604e4 +ContainerTypeName : ContosoLegal +OwningApplicationId : a735e4af-b86e-0000-93ba-1faded6c39e1 +Classification : Standard +AzureSubscriptionId : 564e9025-f7f5-xxx9-9ddd-4cdxxxx1755 +ResourceGroup : prod-resources +Region : EastUS +``` + +## Registering Container Types + +To create and interact with containers, you must [register](../getting-started/register-api-documentation.md) the container type within the Consuming Tenant. The owning application defines the permissions for the container type by invoking the [registration API](../getting-started/register-api-documentation.md). + +## Deleting Container Types + +Developer admins can delete both trial and standard container types. To delete a container type, you must first remove all containers of that container type, including from the deleted container collection. To remove containers, refer to [Consuming Tenant Admin](../administration/consuming-tenant-admin/cta.md). +Once all the containers are deleted, Developer admins can delete the container type using `Remove-SPOContainerType`. + +```powershell +Remove-SPOContainerType [-ContainerTypeId ] +``` +## SharePoint Embedded meters + +To learn more about the supported pay-as-you-go meters, refer to the [SharePoint Embedded meters](../administration/billing/meters.md) article. diff --git a/docs/embedded/getting-started/register-api-documentation.md b/docs/embedded/getting-started/register-api-documentation.md new file mode 100644 index 000000000..320893e72 --- /dev/null +++ b/docs/embedded/getting-started/register-api-documentation.md @@ -0,0 +1,175 @@ +--- +title: Register File Storage container Type Application Permissions +description: Register the container type. +ms.date: 03/03/2025 +ms.localizationpriority: high +--- + +# Register file storage container type application permissions + +In order for a SharePoint Embedded application to interact with containers in a consuming tenant, the container type must first be registered in the consuming tenant. Container type registration happens when the owning application invokes the registration API to specify what permissions can be performed against its container type. The registration API also grants access to other Guest Apps to interact with the owning application's containers. For example, a SharePoint Embedded application can grant permissions to another application--a Guest App so that the Guest App can perform backup operations against its containers. + +Since the registration API controls the permissions that a SharePoint Embedded application can perform against the container in the consuming tenant, this call should be one of the first APIs invoked. Failure to do so results in access denied errors when invoking other APIs against the container and/or the content in the containers. + +There are no restrictions on how many times the registration API can be invoked. How often the registration API is invoked and when it's invoked is dependent on the SharePoint Embedded application. However, the last successful call to the registration API determines the settings used in the consuming tenant. + +## Authentication and authorization requirements + +For the container type's owning application to act on a consuming tenant, some pre-requisites must be completed: + +- the owning app must have a service principal installed on the consuming tenant; and +- the owning app must be granted admin consent to perform container type registration in the consuming tenant. + +> [!NOTE] +> Only the owning application of the container type can invoke the registration API in the consuming tenant. + +Both requirements can be satisfied by having a tenant administrator of the consuming tenant [grant admin consent](/entra/identity/enterprise-apps/grant-admin-consent?pivots=portal) to the container type's owning application. + +The container type registration API requires the `Container.Selected` app-only permission for SharePoint (see [Exceptional access patterns](../development/auth.md#exceptional-access-patterns)). You will need to use the [client credentials grant flow](/entra/identity-platform/v2-oauth2-client-creds-grant-flow) and [request a token with a certificate](/entra/identity-platform/v2-oauth2-client-creds-grant-flow#second-case-access-token-request-with-a-certificate) to use the registration API. + +> [!NOTE] +> The registration API is **NOT** a Microsoft Graph API but a SharePoint API. This API will be ported to Microsoft Graph in the future. + +To request admin consent from a tenant administrator in the consuming tenant, you may direct them to the [admin consent endpoint](/entra/identity-platform/v2-admin-consent). For the right endpoints on national clouds, see [Microsoft identity platform endpoints on national clouds](/entra/identity-platform/authentication-national-cloud#microsoft-entra-authentication-endpoints): + +```http +https://login.microsoftonline.com//adminconsent?client_id= +``` + +You may configure the admin consent endpoint to fit your needs, including handling errors and successful grants. For more information, see [Admin consent URI](/entra/identity-platform/v2-admin-consent). + + +## Container type Permissions + +The registration API determines what permissions a SharePoint Embedded application can perform against containers and content in containers for the specified container type. + +| Permission | Description | +| -------------------- | ------------------------------------------------------------------------------------------------------------------ | +| None | Has no permissions to any containers or content of this container type. | +| ReadContent | Can read content of containers of this container type. | +| WriteContent | Can write content to containers for this container type. This permission can't be granted without the ReadContent permission. | +| Create | Can create containers of this container type. | +| Delete | Can delete containers of this container type. | +| Read | Can read the metadata of containers of this container type. | +| Write | Can update the metadata of containers of this container type. | +| EnumeratePermissions | Can enumerate the members of a container and their roles for containers of this container type. | +| AddPermissions | Can add members to the container for containers of this container type. | +| UpdatePermissions | Can update (change roles of) existing memberships in the container for containers of this container type. | +| DeletePermissions | Can delete other members (but not self) from the container for containers of this container type. | +| DeleteOwnPermissions | Can remove own membership from the container for containers of this container type. | +| ManagePermissions | Can add, remove (including self) or update members in the container roles for containers of this container type. | +| Full | Has all permissions for containers of this container type. | + +## HTTP request + +```http +PUT {RootSiteUrl}/_api/v2.1/storageContainerTypes/{containerTypeId}/applicationPermissions +``` + +> [!NOTE] +> This is NOT a Graph API +> +> `{RootSiteURL}` is the SharePoint URL of the consuming tenant. For example, https://contoso.sharepoint.com. + +### Request body + +In the request body, supply a JSON representation of the container type permissions for the SharePoint Embedded applications. + +### Response + +If successful, this method returns a `200 OK` response code and the container type permissions configured for the SharePoint Embedded applications in the response body. + +| HTTP Code | Description | +| :--------: | ----------- | +| 400 | Bad request. | +| 401 | Request lacks valid authentication credentials. | +| 403 | Provided authentication credentials are valid but insufficient to perform the requested operation. Examples: the calling app isn't the owning app of the container type. | +| 404 | Container type doesn't exist. | + +## Examples + +### Register the container type in a consuming tenant with permissions only for the Owning App + +Register the container type in the consuming tenant and grant full permissions to the Owning Application (AppId 71392b2f-1765-406e-86af-5907d9bdb2ab) for Delegated and AppOnly calls. + +#### Request + +```json +PUT {RootSiteUrl}/_api/v2.1/storageContainerTypes/{containerTypeId}/applicationPermissions +Content-Type: application/json + +{ + "value": [ + { + "appId": "71392b2f-1765-406e-86af-5907d9bdb2ab", + "delegated": ["full"], + "appOnly": ["full"] + } + ] +} +``` + +#### Response + +```json +HTTP/1.1 200 OK +Content-type: application/json + +{ + "value": [ + { + "appId": "71392b2f-1765-406e-86af-5907d9bdb2ab", + "delegated": ["full"], + "appOnly": ["full"] + } + ] +} +``` + +### Register the container type in a consuming tenant with permissions for a Guest App + +Register the container type in the consuming tenant and grant full permissions to the Owning Application (AppId 71392b2f-1765-406e-86af-5907d9bdb2ab) for Delegated and AppOnly calls. In addition, grant a Guest App (AppId 89ea5c94-7736-4e25-95ad-3fa95f62b6) read and write permissions only for Delegated calls. + +#### Request + +```json +PUT /storagecontainerTypes/{containerTypeId}/applicationPermissions +Content-Type: application/json + +{ + "value": [ + { + "appId": "71392b2f-1765-406e-86af-5907d9bdb2ab", + "delegated": ["full"], + "appOnly": ["full"] + }, + { + "appId": "89ea5c94-7736-4e25-95ad-3fa95f62b6", + "delegated": ["read", "write"], + "appOnly": ["none"] + } + ] +} +``` + +#### Response + +```json +HTTP/1.1 200 OK +Content-type: application/json + +{ + "value": [ + { + "appId": "71392b2f-1765-406e-86af-5907d9bdb2ab", + "delegated": ["full"], + "appOnly": ["read"] + }, + { + "appId": "89ea5c94-7736-4e25-95ad-3fa95f62b6", + "delegated": ["read", "write"], + "appOnly": ["none"] + } + ] +} +``` diff --git a/docs/embedded/getting-started/spembedded-for-vscode.md b/docs/embedded/getting-started/spembedded-for-vscode.md new file mode 100644 index 000000000..343a842f5 --- /dev/null +++ b/docs/embedded/getting-started/spembedded-for-vscode.md @@ -0,0 +1,176 @@ +--- +title: SharePoint Embedded for Visual Studio Code +description: Installation and getting started with SharePoint Embedded for Visual Studio Code +ms.date: 07/16/2025 +ms.localizationpriority: high +--- + +# SharePoint Embedded for Visual Studio Code + +The SharePoint Embedded Visual Studio Code extension helps developers get started for free with SharePoint Embedded application development. + +> [!IMPORTANT] +> To start building with SharePoint Embedded, you'll need administrative access to a Microsoft 365 tenant. +> If you don't already have a tenant, you can get your own tenant with the [Microsoft 365 Developer Program](https://developer.microsoft.com/microsoft-365/dev-program), [Microsoft Customer Digital Experience](https://cdx.transform.microsoft.com/), or create a free trial of a [Microsoft 365 E3 license](https://www.microsoft.com/microsoft-365/enterprise/microsoft365-plans-and-pricing). + +## Install SharePoint Embedded for Visual Studio Code + +1. Open a new window in [Visual Studio Code](https://code.visualstudio.com/) and navigate to "**Extensions**" on the activity bar. +1. Search "SharePoint Embedded" in the Extensions view. You can also view the extension in [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=SharepointEmbedded.ms-sharepoint-embedded-vscode-extension). +1. Select **"Install"** and the SharePoint Embedded icon will appear on the activity bar. +1. If already installed, please update to the latest version if one is available. +1. Select the icon to open the SharePoint Embedded view and create a container type with trial configuration. + +![SharePoint Embedded VS Extensions](../images/vsx-images/n1downloadvsx.png) + +### Sign in with admin credentials + +To use the extension, you must sign in to a Microsoft 365 tenant with an administrator account. + +![Install](../images/vsx-images/n2vsx-signin.png) + +- Authentication opens a new tab in an external browser to grant permissions + + ![authorize and authenticate the extension to your M365 Entra tenant](../images/vsx-images/auth-allow-extension-uri.png) + +- Review the requested permissions carefully, then select **Accept** on the pop-up window prompting admin consent + + ![review before consenting to the permissions the extension is asking for](../images/vsx-images/n3vsx-grant-admin-consent.png) + +After successful authorization, select open on the dialog to be redirected to VSCode: + +![authorization completed in browser now redirecting to visual studio code](../images/vsx-images/auth-redirect.png) + +## Create a container type with a trial configuration + +Once signed in, you're prompted to create a [container type with trial configuration](./containertypes.md#trial-container-type). A container type lets you get started calling SharePoint Embedded APIs and building a proof-of-concept application using SharePoint Embedded. Learn more about [container types](containertypes.md). + +![home screen](../images/vsx-images/n4vsx-home-screen.png) + +- Select **Create Trial Container Type** +- Follow the prompts to name your container type. You can change your container type name later on. + +![create container type](../images/vsx-images/n5a-name-ct.png) + +> [!NOTE] +> SharePoint Embedded for Visual Studio Code only supports container types with trial configuration at this time. Other container types with standard or pass-through billing configurations must be created using the SharePoint Online PowerShell Module. + +## Create a Microsoft Entra ID App + +Every container type is owned by a Microsoft Entra ID application. The first step when creating a free trial container type is to create a new or select an existing Microsoft Entra ID application as the owning application. You can either specify the name of your new application or pick one of your existing applications. Learn more about SharePoint Embedded [app architecture](../development/app-architecture.md) + +- Follow the prompts to name your new Entra application or select an existing application ID: + +![Create App](../images/vsx-images/n6aname-app.png) + +> [!NOTE] +> If you choose an existing application, the extension will update that app's configuration settings for it to work with both SharePoint Embedded and this extension. Doing this is NOT recommended on production applications. + +After your container type is created and your application is configured, you'll be able to view your local tenant registration as a tree in the left nav-bar. + +## Register your container type + +After creating your container type, you'll need to register that container type on your local tenant. Learn more about container type [registration](./register-api-documentation.md). + +- Follow the prompts and select **Register on local tenant** on the lower right corner of the VS Code window + + ![local tenant registration popup](../images/vsx-images/local-tenant-registration-popup.png) + +- If you don't see the prompt, you can right-click on your `` and select **Register** from the menu + + ![register](../images/vsx-images/n7aregister-ct.png) + +### Grant permissions + +Review permissions and follow the prompt to grant admin consent + +![grant admin consent popup](../images/vsx-images/auth-grant-admin-consent-popup.png) + +An external browser window will pop open for you to sign-in and grant admin consent + +![login permissions](../images/vsx-images/n9alogin-grant-permissions.png) + +## Create your first container + +With your container type registered, you can now create your first container. Only five containers of container type can be created to upload and manage content. + +- Right-click on the **Containers** drop-down from the tree in the left nav-bar and select **Create container** +- Enter a name for the container you would like to create + +![create container](../images/vsx-images/n10acreate-container.png) +![name container](../images/vsx-images/n11aname-first-cont.png) + +## Recycling Containers + +You can also recycle and recover containers within the extension. + +![recycle containers](../images/vsx-images/n12arecycle-cont.png) + +![final home page](../images/vsx-images/n13a-final-home-page.png) + +## Load Sample App + +With your free trial container type created, you can use the extension to load one of the SharePoint Embedded sample apps and automatically populate the runtime configuration file with the details of your Microsoft Entra ID app and container type. + +![Load Sample App](../images/vsx-images/n15vsxsa-c.png) + +When loading the sample application, you'll be notified that it will create plain text secrets to authenticate on your local machine. + +![sample app plain text secrets notice](../images/vsx-images/sample-app-app-secrets-notice.png) + +If no client secret is found on your application, it will ask if you would like to create one. Press OK to proceed. + +![sample app creating client secret](../images/vsx-images/sample-app-create-client-secret.png) + +> [!IMPORTANT] +> This isn't intended for production environments. [Find out more on how to setup Application Registration for production environments here.](/entra/identity-platform/quickstart-register-app) + +## Using Sample App + +In your terminal, run the following command, this will start the sample application, which consists of 2 parts: + +1. **React Client Application** - The frontend user interface running on port 8080 +1. **Azure Function Application Server** - The backend API server that handles SharePoint Embedded operations + +```console +# Navigate to your sample application directory +cd [your-path]\SharePoint-Embedded-Samples\Samples\spe-typescript-react-azurefunction + +# Install dependencies and start the application +npm run start +``` + +> [!NOTE] +> The initial startup may take a few minutes as dependencies are installed and both applications are built. Wait for both console outputs to appear before navigating to the application. + +This will install the dependencies and run the server and client application, once running, you'll see the following in the terminal, after which you can navigate to http://localhost:8080 to access the application. + +![function api console logs](../images/vsx-images/fn-api-logs.png) + +![client app console logs](../images/vsx-images/client-app-logs.png) + +Once both applications are running successfully: + +1. Open your web browser and navigate to **http://localhost:8080** +1. Sign in using your Microsoft 365 administrator account (the same account used in the VS Code extension) +1. On the home page, select **"Containers"** to begin creating containers and uploading files +1. Follow the on-screen prompts to interact with your SharePoint Embedded containers + +![home-page-for-spe-sample-app](../images/vsx-images/spe-sample-app-home.png) + +> [!IMPORTANT] +> This sample application stores authentication secrets in plain text for development purposes only. Never use this configuration in a production environment. + +### Troubleshooting + +If you encounter issues: + +- **Port already in use**: If port 8080 is already in use, the application will automatically try the next available port +- **Dependencies not installing**: Try running `npm install` manually before `npm run start` +- **Authentication errors**: Ensure your Microsoft Entra ID app is properly configured with the correct redirect URIs + +## Export Postman Environment + +The [SharePoint Embedded Postman Collection](https://github.com/microsoft/SharePoint-Embedded-Samples/tree/main/Postman) allows you to explore and call the SharePoint Embedded APIs. The Collection requires an environment file with variables used for authentication and various identifiers. This extension automates the generation of this populated environment file so you can import it into Postal worker and immediately call the SharePoint Embedded APIs. + +![Export Postman Environment](../images/vsx-images/n14postman-c.png) diff --git a/docs/embedded/images/1bill521.png b/docs/embedded/images/1bill521.png new file mode 100644 index 000000000..6528d71c3 Binary files /dev/null and b/docs/embedded/images/1bill521.png differ diff --git a/docs/embedded/images/2bill521.png b/docs/embedded/images/2bill521.png new file mode 100644 index 000000000..d4dfc162b Binary files /dev/null and b/docs/embedded/images/2bill521.png differ diff --git a/docs/embedded/images/DTCBilling1.png b/docs/embedded/images/DTCBilling1.png new file mode 100644 index 000000000..6a24fa4b5 Binary files /dev/null and b/docs/embedded/images/DTCBilling1.png differ diff --git a/docs/embedded/images/DTCBilling2.png b/docs/embedded/images/DTCBilling2.png new file mode 100644 index 000000000..b4c7318b9 Binary files /dev/null and b/docs/embedded/images/DTCBilling2.png differ diff --git a/docs/embedded/images/Document-Processing.png b/docs/embedded/images/Document-Processing.png new file mode 100644 index 000000000..7982dba53 Binary files /dev/null and b/docs/embedded/images/Document-Processing.png differ diff --git a/docs/embedded/images/SPEAdmin1.png b/docs/embedded/images/SPEAdmin1.png new file mode 100644 index 000000000..87c3a1fa8 Binary files /dev/null and b/docs/embedded/images/SPEAdmin1.png differ diff --git a/docs/embedded/images/SPEAdmin10.png b/docs/embedded/images/SPEAdmin10.png new file mode 100644 index 000000000..9f5feab08 Binary files /dev/null and b/docs/embedded/images/SPEAdmin10.png differ diff --git a/docs/embedded/images/SPEAdmin11.png b/docs/embedded/images/SPEAdmin11.png new file mode 100644 index 000000000..1027fc70a Binary files /dev/null and b/docs/embedded/images/SPEAdmin11.png differ diff --git a/docs/embedded/images/SPEAdmin12.png b/docs/embedded/images/SPEAdmin12.png new file mode 100644 index 000000000..102e0dacf Binary files /dev/null and b/docs/embedded/images/SPEAdmin12.png differ diff --git a/docs/embedded/images/SPEAdmin13.png b/docs/embedded/images/SPEAdmin13.png new file mode 100644 index 000000000..83d556813 Binary files /dev/null and b/docs/embedded/images/SPEAdmin13.png differ diff --git a/docs/embedded/images/SPEAdmin14.png b/docs/embedded/images/SPEAdmin14.png new file mode 100644 index 000000000..dc66703b5 Binary files /dev/null and b/docs/embedded/images/SPEAdmin14.png differ diff --git a/docs/embedded/images/SPEAdmin15.png b/docs/embedded/images/SPEAdmin15.png new file mode 100644 index 000000000..4a3f80cdb Binary files /dev/null and b/docs/embedded/images/SPEAdmin15.png differ diff --git a/docs/embedded/images/SPEAdmin16.png b/docs/embedded/images/SPEAdmin16.png new file mode 100644 index 000000000..03568e615 Binary files /dev/null and b/docs/embedded/images/SPEAdmin16.png differ diff --git a/docs/embedded/images/SPEAdmin2.png b/docs/embedded/images/SPEAdmin2.png new file mode 100644 index 000000000..8be14b0b4 Binary files /dev/null and b/docs/embedded/images/SPEAdmin2.png differ diff --git a/docs/embedded/images/SPEAdmin3.png b/docs/embedded/images/SPEAdmin3.png new file mode 100644 index 000000000..010bf998b Binary files /dev/null and b/docs/embedded/images/SPEAdmin3.png differ diff --git a/docs/embedded/images/SPEAdmin4.png b/docs/embedded/images/SPEAdmin4.png new file mode 100644 index 000000000..26b05d149 Binary files /dev/null and b/docs/embedded/images/SPEAdmin4.png differ diff --git a/docs/embedded/images/SPEAdmin5.png b/docs/embedded/images/SPEAdmin5.png new file mode 100644 index 000000000..b82c2bbfc Binary files /dev/null and b/docs/embedded/images/SPEAdmin5.png differ diff --git a/docs/embedded/images/SPEAdmin6.png b/docs/embedded/images/SPEAdmin6.png new file mode 100644 index 000000000..e80422388 Binary files /dev/null and b/docs/embedded/images/SPEAdmin6.png differ diff --git a/docs/embedded/images/SPEAdmin7.png b/docs/embedded/images/SPEAdmin7.png new file mode 100644 index 000000000..1b97c3acb Binary files /dev/null and b/docs/embedded/images/SPEAdmin7.png differ diff --git a/docs/embedded/images/SPEAdmin8.png b/docs/embedded/images/SPEAdmin8.png new file mode 100644 index 000000000..62cd5b268 Binary files /dev/null and b/docs/embedded/images/SPEAdmin8.png differ diff --git a/docs/embedded/images/SPEAdmin9.png b/docs/embedded/images/SPEAdmin9.png new file mode 100644 index 000000000..08a6f7120 Binary files /dev/null and b/docs/embedded/images/SPEAdmin9.png differ diff --git a/docs/embedded/images/SPEArch.png b/docs/embedded/images/SPEArch.png new file mode 100644 index 000000000..cb0818e3f Binary files /dev/null and b/docs/embedded/images/SPEArch.png differ diff --git a/docs/embedded/images/SPECTDedicated.png b/docs/embedded/images/SPECTDedicated.png new file mode 100644 index 000000000..67b94e68c Binary files /dev/null and b/docs/embedded/images/SPECTDedicated.png differ diff --git a/docs/embedded/images/SPECTShared.png b/docs/embedded/images/SPECTShared.png new file mode 100644 index 000000000..bcc4de7e8 Binary files /dev/null and b/docs/embedded/images/SPECTShared.png differ diff --git a/docs/embedded/images/SharePointEmbeddedToS-1.jpg b/docs/embedded/images/SharePointEmbeddedToS-1.jpg new file mode 100644 index 000000000..03777613c Binary files /dev/null and b/docs/embedded/images/SharePointEmbeddedToS-1.jpg differ diff --git a/docs/embedded/images/SharePointEmbeddedToS-2.jpg b/docs/embedded/images/SharePointEmbeddedToS-2.jpg new file mode 100644 index 000000000..c7196e505 Binary files /dev/null and b/docs/embedded/images/SharePointEmbeddedToS-2.jpg differ diff --git a/docs/embedded/images/SharePointEmbeddedToS-3.jpg b/docs/embedded/images/SharePointEmbeddedToS-3.jpg new file mode 100644 index 000000000..e7fb61050 Binary files /dev/null and b/docs/embedded/images/SharePointEmbeddedToS-3.jpg differ diff --git a/docs/embedded/images/SharePointEmbeddedToS-4.jpg b/docs/embedded/images/SharePointEmbeddedToS-4.jpg new file mode 100644 index 000000000..0d29fbfd4 Binary files /dev/null and b/docs/embedded/images/SharePointEmbeddedToS-4.jpg differ diff --git a/docs/embedded/images/SharePointEmbeddedToS-5.jpg b/docs/embedded/images/SharePointEmbeddedToS-5.jpg new file mode 100644 index 000000000..e09f5cd1c Binary files /dev/null and b/docs/embedded/images/SharePointEmbeddedToS-5.jpg differ diff --git a/docs/embedded/images/SharingPartitions.png b/docs/embedded/images/SharingPartitions.png new file mode 100644 index 000000000..5b3b4bd66 Binary files /dev/null and b/docs/embedded/images/SharingPartitions.png differ diff --git a/docs/embedded/images/SyntexActivatePAYGSetup.png b/docs/embedded/images/SyntexActivatePAYGSetup.png new file mode 100644 index 000000000..00147f57b Binary files /dev/null and b/docs/embedded/images/SyntexActivatePAYGSetup.png differ diff --git a/docs/embedded/images/SyntexPAYGActivateSPE.png b/docs/embedded/images/SyntexPAYGActivateSPE.png new file mode 100644 index 000000000..739a58a47 Binary files /dev/null and b/docs/embedded/images/SyntexPAYGActivateSPE.png differ diff --git a/docs/embedded/images/Using-Webhooks.png b/docs/embedded/images/Using-Webhooks.png new file mode 100644 index 000000000..5d98224cf Binary files /dev/null and b/docs/embedded/images/Using-Webhooks.png differ diff --git a/docs/embedded/images/add-owners-one.png b/docs/embedded/images/add-owners-one.png new file mode 100644 index 000000000..bba134252 Binary files /dev/null and b/docs/embedded/images/add-owners-one.png differ diff --git a/docs/embedded/images/add-owners-two.png b/docs/embedded/images/add-owners-two.png new file mode 100644 index 000000000..fe7af04ed Binary files /dev/null and b/docs/embedded/images/add-owners-two.png differ diff --git a/docs/embedded/images/app-arch.png b/docs/embedded/images/app-arch.png new file mode 100644 index 000000000..0129f6719 Binary files /dev/null and b/docs/embedded/images/app-arch.png differ diff --git a/docs/embedded/images/app-flow7.jpg b/docs/embedded/images/app-flow7.jpg new file mode 100644 index 000000000..cbf6f4801 Binary files /dev/null and b/docs/embedded/images/app-flow7.jpg differ diff --git a/docs/embedded/images/app-registration-console-platform.png b/docs/embedded/images/app-registration-console-platform.png new file mode 100644 index 000000000..177c0bc5a Binary files /dev/null and b/docs/embedded/images/app-registration-console-platform.png differ diff --git a/docs/embedded/images/apparc-1.png b/docs/embedded/images/apparc-1.png new file mode 100644 index 000000000..082e51788 Binary files /dev/null and b/docs/embedded/images/apparc-1.png differ diff --git a/docs/embedded/images/apparc-2.png b/docs/embedded/images/apparc-2.png new file mode 100644 index 000000000..7f8a72df8 Binary files /dev/null and b/docs/embedded/images/apparc-2.png differ diff --git a/docs/embedded/images/apparchexample.png b/docs/embedded/images/apparchexample.png new file mode 100644 index 000000000..f862809ad Binary files /dev/null and b/docs/embedded/images/apparchexample.png differ diff --git a/docs/embedded/images/architecture-overview.png b/docs/embedded/images/architecture-overview.png new file mode 100644 index 000000000..b815cb4cd Binary files /dev/null and b/docs/embedded/images/architecture-overview.png differ diff --git a/docs/embedded/images/billing-1.png b/docs/embedded/images/billing-1.png new file mode 100644 index 000000000..14eb0f29a Binary files /dev/null and b/docs/embedded/images/billing-1.png differ diff --git a/docs/embedded/images/billing-2.png b/docs/embedded/images/billing-2.png new file mode 100644 index 000000000..669b0642a Binary files /dev/null and b/docs/embedded/images/billing-2.png differ diff --git a/docs/embedded/images/billing-manage.png b/docs/embedded/images/billing-manage.png new file mode 100644 index 000000000..014db7f05 Binary files /dev/null and b/docs/embedded/images/billing-manage.png differ diff --git a/docs/embedded/images/billmanag1.png b/docs/embedded/images/billmanag1.png new file mode 100644 index 000000000..bebe7f8b9 Binary files /dev/null and b/docs/embedded/images/billmanag1.png differ diff --git a/docs/embedded/images/billmanag2.png b/docs/embedded/images/billmanag2.png new file mode 100644 index 000000000..1bca53b4f Binary files /dev/null and b/docs/embedded/images/billmanag2.png differ diff --git a/docs/embedded/images/billmanag3.png b/docs/embedded/images/billmanag3.png new file mode 100644 index 000000000..2ac8dd97b Binary files /dev/null and b/docs/embedded/images/billmanag3.png differ diff --git a/docs/embedded/images/ctaux1.png b/docs/embedded/images/ctaux1.png new file mode 100644 index 000000000..c5ff77540 Binary files /dev/null and b/docs/embedded/images/ctaux1.png differ diff --git a/docs/embedded/images/ctaux10.png b/docs/embedded/images/ctaux10.png new file mode 100644 index 000000000..d60b84e5d Binary files /dev/null and b/docs/embedded/images/ctaux10.png differ diff --git a/docs/embedded/images/ctaux11.png b/docs/embedded/images/ctaux11.png new file mode 100644 index 000000000..01dc83bc0 Binary files /dev/null and b/docs/embedded/images/ctaux11.png differ diff --git a/docs/embedded/images/ctaux12.png b/docs/embedded/images/ctaux12.png new file mode 100644 index 000000000..b7f53ffed Binary files /dev/null and b/docs/embedded/images/ctaux12.png differ diff --git a/docs/embedded/images/ctaux13.png b/docs/embedded/images/ctaux13.png new file mode 100644 index 000000000..e77fd7b11 Binary files /dev/null and b/docs/embedded/images/ctaux13.png differ diff --git a/docs/embedded/images/ctaux14.png b/docs/embedded/images/ctaux14.png new file mode 100644 index 000000000..b62786140 Binary files /dev/null and b/docs/embedded/images/ctaux14.png differ diff --git a/docs/embedded/images/ctaux15-n.png b/docs/embedded/images/ctaux15-n.png new file mode 100644 index 000000000..c534fae69 Binary files /dev/null and b/docs/embedded/images/ctaux15-n.png differ diff --git a/docs/embedded/images/ctaux2.png b/docs/embedded/images/ctaux2.png new file mode 100644 index 000000000..3c5dac782 Binary files /dev/null and b/docs/embedded/images/ctaux2.png differ diff --git a/docs/embedded/images/ctaux3.png b/docs/embedded/images/ctaux3.png new file mode 100644 index 000000000..88728dc03 Binary files /dev/null and b/docs/embedded/images/ctaux3.png differ diff --git a/docs/embedded/images/ctaux4.png b/docs/embedded/images/ctaux4.png new file mode 100644 index 000000000..5c06e1b4f Binary files /dev/null and b/docs/embedded/images/ctaux4.png differ diff --git a/docs/embedded/images/ctaux5.png b/docs/embedded/images/ctaux5.png new file mode 100644 index 000000000..4ca1d7238 Binary files /dev/null and b/docs/embedded/images/ctaux5.png differ diff --git a/docs/embedded/images/ctaux6.png b/docs/embedded/images/ctaux6.png new file mode 100644 index 000000000..ab0b73ff8 Binary files /dev/null and b/docs/embedded/images/ctaux6.png differ diff --git a/docs/embedded/images/ctaux7.png b/docs/embedded/images/ctaux7.png new file mode 100644 index 000000000..d5f841cc6 Binary files /dev/null and b/docs/embedded/images/ctaux7.png differ diff --git a/docs/embedded/images/ctaux8.png b/docs/embedded/images/ctaux8.png new file mode 100644 index 000000000..48e3c9b4e Binary files /dev/null and b/docs/embedded/images/ctaux8.png differ diff --git a/docs/embedded/images/ctaux9.png b/docs/embedded/images/ctaux9.png new file mode 100644 index 000000000..233cded62 Binary files /dev/null and b/docs/embedded/images/ctaux9.png differ diff --git a/docs/embedded/images/enable1.png b/docs/embedded/images/enable1.png new file mode 100644 index 000000000..e6f7a30d3 Binary files /dev/null and b/docs/embedded/images/enable1.png differ diff --git a/docs/embedded/images/enable2.png b/docs/embedded/images/enable2.png new file mode 100644 index 000000000..d3bcbbfa2 Binary files /dev/null and b/docs/embedded/images/enable2.png differ diff --git a/docs/embedded/images/enable3.png b/docs/embedded/images/enable3.png new file mode 100644 index 000000000..52f0cd78e Binary files /dev/null and b/docs/embedded/images/enable3.png differ diff --git a/docs/embedded/images/enable4.png b/docs/embedded/images/enable4.png new file mode 100644 index 000000000..3bd2d76ee Binary files /dev/null and b/docs/embedded/images/enable4.png differ diff --git a/docs/embedded/images/enable5.png b/docs/embedded/images/enable5.png new file mode 100644 index 000000000..ec852a6ce Binary files /dev/null and b/docs/embedded/images/enable5.png differ diff --git a/docs/embedded/images/featuretbl.png b/docs/embedded/images/featuretbl.png new file mode 100644 index 000000000..e2cf7c5df Binary files /dev/null and b/docs/embedded/images/featuretbl.png differ diff --git a/docs/embedded/images/filter-on-delete.png b/docs/embedded/images/filter-on-delete.png new file mode 100644 index 000000000..87599873d Binary files /dev/null and b/docs/embedded/images/filter-on-delete.png differ diff --git a/docs/embedded/images/filter.png b/docs/embedded/images/filter.png new file mode 100644 index 000000000..6f1eacbeb Binary files /dev/null and b/docs/embedded/images/filter.png differ diff --git a/docs/embedded/images/itemcount.png b/docs/embedded/images/itemcount.png new file mode 100644 index 000000000..5ceb712fe Binary files /dev/null and b/docs/embedded/images/itemcount.png differ diff --git a/docs/embedded/images/ngrok-registration.png b/docs/embedded/images/ngrok-registration.png new file mode 100644 index 000000000..86c133609 Binary files /dev/null and b/docs/embedded/images/ngrok-registration.png differ diff --git a/docs/embedded/images/office1.png b/docs/embedded/images/office1.png new file mode 100644 index 000000000..8ff7d3ba9 Binary files /dev/null and b/docs/embedded/images/office1.png differ diff --git a/docs/embedded/images/office2.png b/docs/embedded/images/office2.png new file mode 100644 index 000000000..3753f7c67 Binary files /dev/null and b/docs/embedded/images/office2.png differ diff --git a/docs/embedded/images/raasflow.png b/docs/embedded/images/raasflow.png new file mode 100644 index 000000000..a23fd1eff Binary files /dev/null and b/docs/embedded/images/raasflow.png differ diff --git a/docs/embedded/images/raaspic2.png b/docs/embedded/images/raaspic2.png new file mode 100644 index 000000000..bd77feabc Binary files /dev/null and b/docs/embedded/images/raaspic2.png differ diff --git a/docs/embedded/images/reassign-user.png b/docs/embedded/images/reassign-user.png new file mode 100644 index 000000000..5ae1447ed Binary files /dev/null and b/docs/embedded/images/reassign-user.png differ diff --git a/docs/embedded/images/remove-user.png b/docs/embedded/images/remove-user.png new file mode 100644 index 000000000..ffa8d357a Binary files /dev/null and b/docs/embedded/images/remove-user.png differ diff --git a/docs/embedded/images/sc1.png b/docs/embedded/images/sc1.png new file mode 100644 index 000000000..7e284f0a5 Binary files /dev/null and b/docs/embedded/images/sc1.png differ diff --git a/docs/embedded/images/sc2.png b/docs/embedded/images/sc2.png new file mode 100644 index 000000000..f621f6df3 Binary files /dev/null and b/docs/embedded/images/sc2.png differ diff --git a/docs/embedded/images/sc3.png b/docs/embedded/images/sc3.png new file mode 100644 index 000000000..62e1623f4 Binary files /dev/null and b/docs/embedded/images/sc3.png differ diff --git a/docs/embedded/images/sc4.png b/docs/embedded/images/sc4.png new file mode 100644 index 000000000..285aa9dad Binary files /dev/null and b/docs/embedded/images/sc4.png differ diff --git a/docs/embedded/images/sc5.png b/docs/embedded/images/sc5.png new file mode 100644 index 000000000..5fb5d3ae5 Binary files /dev/null and b/docs/embedded/images/sc5.png differ diff --git a/docs/embedded/images/sc6.png b/docs/embedded/images/sc6.png new file mode 100644 index 000000000..98fc406ed Binary files /dev/null and b/docs/embedded/images/sc6.png differ diff --git a/docs/embedded/images/sc7.png b/docs/embedded/images/sc7.png new file mode 100644 index 000000000..fb4038ad6 Binary files /dev/null and b/docs/embedded/images/sc7.png differ diff --git a/docs/embedded/images/search.png b/docs/embedded/images/search.png new file mode 100644 index 000000000..02c1c3ffc Binary files /dev/null and b/docs/embedded/images/search.png differ diff --git a/docs/embedded/images/sensitivity-label.png b/docs/embedded/images/sensitivity-label.png new file mode 100644 index 000000000..5180a30a0 Binary files /dev/null and b/docs/embedded/images/sensitivity-label.png differ diff --git a/docs/embedded/images/sorting-on-deleted.png b/docs/embedded/images/sorting-on-deleted.png new file mode 100644 index 000000000..961e81d55 Binary files /dev/null and b/docs/embedded/images/sorting-on-deleted.png differ diff --git a/docs/embedded/images/sorting.png b/docs/embedded/images/sorting.png new file mode 100644 index 000000000..3f495f85c Binary files /dev/null and b/docs/embedded/images/sorting.png differ diff --git a/docs/embedded/images/spe-vscode-marketplace.png b/docs/embedded/images/spe-vscode-marketplace.png new file mode 100644 index 000000000..ac9a383b6 Binary files /dev/null and b/docs/embedded/images/spe-vscode-marketplace.png differ diff --git a/docs/embedded/images/speco-apparch.png b/docs/embedded/images/speco-apparch.png new file mode 100644 index 000000000..ec05874da Binary files /dev/null and b/docs/embedded/images/speco-apparch.png differ diff --git a/docs/embedded/images/speco-appscopingvenn.png b/docs/embedded/images/speco-appscopingvenn.png new file mode 100644 index 000000000..d5727486a Binary files /dev/null and b/docs/embedded/images/speco-appscopingvenn.png differ diff --git a/docs/embedded/images/speco-bound.png b/docs/embedded/images/speco-bound.png new file mode 100644 index 000000000..8f3cff455 Binary files /dev/null and b/docs/embedded/images/speco-bound.png differ diff --git a/docs/embedded/images/speco-cloneproject.png b/docs/embedded/images/speco-cloneproject.png new file mode 100644 index 000000000..4573bdc74 Binary files /dev/null and b/docs/embedded/images/speco-cloneproject.png differ diff --git a/docs/embedded/images/speco-createappsecret.png b/docs/embedded/images/speco-createappsecret.png new file mode 100644 index 000000000..b283b8259 Binary files /dev/null and b/docs/embedded/images/speco-createappsecret.png differ diff --git a/docs/embedded/images/speco-createclientsecret.png b/docs/embedded/images/speco-createclientsecret.png new file mode 100644 index 000000000..37cf20e57 Binary files /dev/null and b/docs/embedded/images/speco-createclientsecret.png differ diff --git a/docs/embedded/images/speco-createcontosocontainer2.png b/docs/embedded/images/speco-createcontosocontainer2.png new file mode 100644 index 000000000..995cd7f88 Binary files /dev/null and b/docs/embedded/images/speco-createcontosocontainer2.png differ diff --git a/docs/embedded/images/speco-createdcontainer.png b/docs/embedded/images/speco-createdcontainer.png new file mode 100644 index 000000000..e429321c4 Binary files /dev/null and b/docs/embedded/images/speco-createdcontainer.png differ diff --git a/docs/embedded/images/speco-feedbackcombined.png b/docs/embedded/images/speco-feedbackcombined.png new file mode 100644 index 000000000..c3d95ef63 Binary files /dev/null and b/docs/embedded/images/speco-feedbackcombined.png differ diff --git a/docs/embedded/images/speco-feedbackmodal.png b/docs/embedded/images/speco-feedbackmodal.png new file mode 100644 index 000000000..ef3b9ab51 Binary files /dev/null and b/docs/embedded/images/speco-feedbackmodal.png differ diff --git a/docs/embedded/images/speco-feedbackthumbsdown.png b/docs/embedded/images/speco-feedbackthumbsdown.png new file mode 100644 index 000000000..d9e3bd0f5 Binary files /dev/null and b/docs/embedded/images/speco-feedbackthumbsdown.png differ diff --git a/docs/embedded/images/speco-ragai.png b/docs/embedded/images/speco-ragai.png new file mode 100644 index 000000000..28b3f3eac Binary files /dev/null and b/docs/embedded/images/speco-ragai.png differ diff --git a/docs/embedded/images/speco-ragm365.png b/docs/embedded/images/speco-ragm365.png new file mode 100644 index 000000000..17a016ff8 Binary files /dev/null and b/docs/embedded/images/speco-ragm365.png differ diff --git a/docs/embedded/images/speco-ragquery.png b/docs/embedded/images/speco-ragquery.png new file mode 100644 index 000000000..b8a52311b Binary files /dev/null and b/docs/embedded/images/speco-ragquery.png differ diff --git a/docs/embedded/images/speco-reacttypescripthomepage.png b/docs/embedded/images/speco-reacttypescripthomepage.png new file mode 100644 index 000000000..b25861791 Binary files /dev/null and b/docs/embedded/images/speco-reacttypescripthomepage.png differ diff --git a/docs/embedded/images/speco-runnpmrunstart.png b/docs/embedded/images/speco-runnpmrunstart.png new file mode 100644 index 000000000..1f26f6395 Binary files /dev/null and b/docs/embedded/images/speco-runnpmrunstart.png differ diff --git a/docs/embedded/images/speco-runsampleapp.png b/docs/embedded/images/speco-runsampleapp.png new file mode 100644 index 000000000..3d3341eaf Binary files /dev/null and b/docs/embedded/images/speco-runsampleapp.png differ diff --git a/docs/embedded/images/speco-setshowsidebartrue.png b/docs/embedded/images/speco-setshowsidebartrue.png new file mode 100644 index 000000000..2b73eac96 Binary files /dev/null and b/docs/embedded/images/speco-setshowsidebartrue.png differ diff --git a/docs/embedded/images/speco-spechatenabled.png b/docs/embedded/images/speco-spechatenabled.png new file mode 100644 index 000000000..87f35bb1b Binary files /dev/null and b/docs/embedded/images/speco-spechatenabled.png differ diff --git a/docs/embedded/images/speco-uncommentchatsidebar.png b/docs/embedded/images/speco-uncommentchatsidebar.png new file mode 100644 index 000000000..ccc7cfd46 Binary files /dev/null and b/docs/embedded/images/speco-uncommentchatsidebar.png differ diff --git a/docs/embedded/images/speco-vscodeclonedproject.png b/docs/embedded/images/speco-vscodeclonedproject.png new file mode 100644 index 000000000..c88e78db4 Binary files /dev/null and b/docs/embedded/images/speco-vscodeclonedproject.png differ diff --git a/docs/embedded/images/speco-vscodeextensiondisablediscovery.png b/docs/embedded/images/speco-vscodeextensiondisablediscovery.png new file mode 100644 index 000000000..d1c9d63d2 Binary files /dev/null and b/docs/embedded/images/speco-vscodeextensiondisablediscovery.png differ diff --git a/docs/embedded/images/vscodeconsentperms.png b/docs/embedded/images/vscodeconsentperms.png new file mode 100644 index 000000000..05d708775 Binary files /dev/null and b/docs/embedded/images/vscodeconsentperms.png differ diff --git a/docs/embedded/images/vscodecontcreate.png b/docs/embedded/images/vscodecontcreate.png new file mode 100644 index 000000000..df87b340f Binary files /dev/null and b/docs/embedded/images/vscodecontcreate.png differ diff --git a/docs/embedded/images/vscodecontname.png b/docs/embedded/images/vscodecontname.png new file mode 100644 index 000000000..9b2c6d17a Binary files /dev/null and b/docs/embedded/images/vscodecontname.png differ diff --git a/docs/embedded/images/vscodeinstall.png b/docs/embedded/images/vscodeinstall.png new file mode 100644 index 000000000..68ea5d36c Binary files /dev/null and b/docs/embedded/images/vscodeinstall.png differ diff --git a/docs/embedded/images/vscodelaunch.png b/docs/embedded/images/vscodelaunch.png new file mode 100644 index 000000000..50ada3175 Binary files /dev/null and b/docs/embedded/images/vscodelaunch.png differ diff --git a/docs/embedded/images/vscodelogin.png b/docs/embedded/images/vscodelogin.png new file mode 100644 index 000000000..b6921c523 Binary files /dev/null and b/docs/embedded/images/vscodelogin.png differ diff --git a/docs/embedded/images/vscoderegister.png b/docs/embedded/images/vscoderegister.png new file mode 100644 index 000000000..5cfb6fb43 Binary files /dev/null and b/docs/embedded/images/vscoderegister.png differ diff --git a/docs/embedded/images/vscodetree.png b/docs/embedded/images/vscodetree.png new file mode 100644 index 000000000..3d7337b18 Binary files /dev/null and b/docs/embedded/images/vscodetree.png differ diff --git a/docs/embedded/images/vsx-images/auth-allow-extension-uri.png b/docs/embedded/images/vsx-images/auth-allow-extension-uri.png new file mode 100644 index 000000000..f71029396 Binary files /dev/null and b/docs/embedded/images/vsx-images/auth-allow-extension-uri.png differ diff --git a/docs/embedded/images/vsx-images/auth-grant-admin-consent-popup.png b/docs/embedded/images/vsx-images/auth-grant-admin-consent-popup.png new file mode 100644 index 000000000..a8b8485e7 Binary files /dev/null and b/docs/embedded/images/vsx-images/auth-grant-admin-consent-popup.png differ diff --git a/docs/embedded/images/vsx-images/auth-redirect.png b/docs/embedded/images/vsx-images/auth-redirect.png new file mode 100644 index 000000000..ee09cc6bb Binary files /dev/null and b/docs/embedded/images/vsx-images/auth-redirect.png differ diff --git a/docs/embedded/images/vsx-images/client-app-logs.png b/docs/embedded/images/vsx-images/client-app-logs.png new file mode 100644 index 000000000..61c81ce0f Binary files /dev/null and b/docs/embedded/images/vsx-images/client-app-logs.png differ diff --git a/docs/embedded/images/vsx-images/fn-api-logs.png b/docs/embedded/images/vsx-images/fn-api-logs.png new file mode 100644 index 000000000..dc0263c40 Binary files /dev/null and b/docs/embedded/images/vsx-images/fn-api-logs.png differ diff --git a/docs/embedded/images/vsx-images/local-tenant-registration-popup.png b/docs/embedded/images/vsx-images/local-tenant-registration-popup.png new file mode 100644 index 000000000..e233afcf7 Binary files /dev/null and b/docs/embedded/images/vsx-images/local-tenant-registration-popup.png differ diff --git a/docs/embedded/images/vsx-images/n10acreate-container.png b/docs/embedded/images/vsx-images/n10acreate-container.png new file mode 100644 index 000000000..6be23f1cc Binary files /dev/null and b/docs/embedded/images/vsx-images/n10acreate-container.png differ diff --git a/docs/embedded/images/vsx-images/n11aname-first-cont.png b/docs/embedded/images/vsx-images/n11aname-first-cont.png new file mode 100644 index 000000000..3a184eb9c Binary files /dev/null and b/docs/embedded/images/vsx-images/n11aname-first-cont.png differ diff --git a/docs/embedded/images/vsx-images/n12arecycle-cont.png b/docs/embedded/images/vsx-images/n12arecycle-cont.png new file mode 100644 index 000000000..6c26b1b20 Binary files /dev/null and b/docs/embedded/images/vsx-images/n12arecycle-cont.png differ diff --git a/docs/embedded/images/vsx-images/n13a-final-home-page.png b/docs/embedded/images/vsx-images/n13a-final-home-page.png new file mode 100644 index 000000000..bb77e35ed Binary files /dev/null and b/docs/embedded/images/vsx-images/n13a-final-home-page.png differ diff --git a/docs/embedded/images/vsx-images/n14postman-c.png b/docs/embedded/images/vsx-images/n14postman-c.png new file mode 100644 index 000000000..86d9b8a80 Binary files /dev/null and b/docs/embedded/images/vsx-images/n14postman-c.png differ diff --git a/docs/embedded/images/vsx-images/n15vsxsa-c.png b/docs/embedded/images/vsx-images/n15vsxsa-c.png new file mode 100644 index 000000000..6391443a2 Binary files /dev/null and b/docs/embedded/images/vsx-images/n15vsxsa-c.png differ diff --git a/docs/embedded/images/vsx-images/n1downloadvsx.png b/docs/embedded/images/vsx-images/n1downloadvsx.png new file mode 100644 index 000000000..94229faf7 Binary files /dev/null and b/docs/embedded/images/vsx-images/n1downloadvsx.png differ diff --git a/docs/embedded/images/vsx-images/n2vsx-signin.png b/docs/embedded/images/vsx-images/n2vsx-signin.png new file mode 100644 index 000000000..fa78d61e6 Binary files /dev/null and b/docs/embedded/images/vsx-images/n2vsx-signin.png differ diff --git a/docs/embedded/images/vsx-images/n3vsx-grant-admin-consent.png b/docs/embedded/images/vsx-images/n3vsx-grant-admin-consent.png new file mode 100644 index 000000000..c6cfd5cdc Binary files /dev/null and b/docs/embedded/images/vsx-images/n3vsx-grant-admin-consent.png differ diff --git a/docs/embedded/images/vsx-images/n4vsx-home-screen.png b/docs/embedded/images/vsx-images/n4vsx-home-screen.png new file mode 100644 index 000000000..6b9a85cae Binary files /dev/null and b/docs/embedded/images/vsx-images/n4vsx-home-screen.png differ diff --git a/docs/embedded/images/vsx-images/n5a-name-ct.png b/docs/embedded/images/vsx-images/n5a-name-ct.png new file mode 100644 index 000000000..aca25d3a8 Binary files /dev/null and b/docs/embedded/images/vsx-images/n5a-name-ct.png differ diff --git a/docs/embedded/images/vsx-images/n6aname-app.png b/docs/embedded/images/vsx-images/n6aname-app.png new file mode 100644 index 000000000..d58360b2a Binary files /dev/null and b/docs/embedded/images/vsx-images/n6aname-app.png differ diff --git a/docs/embedded/images/vsx-images/n7aregister-ct.png b/docs/embedded/images/vsx-images/n7aregister-ct.png new file mode 100644 index 000000000..9ae83ca19 Binary files /dev/null and b/docs/embedded/images/vsx-images/n7aregister-ct.png differ diff --git a/docs/embedded/images/vsx-images/n9alogin-grant-permissions.png b/docs/embedded/images/vsx-images/n9alogin-grant-permissions.png new file mode 100644 index 000000000..a5cdd7fe2 Binary files /dev/null and b/docs/embedded/images/vsx-images/n9alogin-grant-permissions.png differ diff --git a/docs/embedded/images/vsx-images/sample-app-app-secrets-notice.png b/docs/embedded/images/vsx-images/sample-app-app-secrets-notice.png new file mode 100644 index 000000000..1ade7d0fb Binary files /dev/null and b/docs/embedded/images/vsx-images/sample-app-app-secrets-notice.png differ diff --git a/docs/embedded/images/vsx-images/sample-app-create-client-secret.png b/docs/embedded/images/vsx-images/sample-app-create-client-secret.png new file mode 100644 index 000000000..2bddaef4f Binary files /dev/null and b/docs/embedded/images/vsx-images/sample-app-create-client-secret.png differ diff --git a/docs/embedded/images/vsx-images/spe-sample-app-home.png b/docs/embedded/images/vsx-images/spe-sample-app-home.png new file mode 100644 index 000000000..575c8da11 Binary files /dev/null and b/docs/embedded/images/vsx-images/spe-sample-app-home.png differ diff --git a/docs/embedded/overview.md b/docs/embedded/overview.md new file mode 100644 index 000000000..9f707d52e --- /dev/null +++ b/docs/embedded/overview.md @@ -0,0 +1,72 @@ +--- +title: SharePoint Embedded Overview +description: Microsoft SharePoint Embedded is a cloud-based file and document management system suitable for use in any application. SharePoint Embedded is a new API-only solution that enables app developers to harness the power of the Microsoft 365 file and document storage platform for any app, and is suitable for enterprises building line-of-business applications and ISVs building multitenant applications. +ms.date: 08/17/2024 +ms.localizationpriority: high +--- + +# Overview of SharePoint Embedded + +Microsoft SharePoint Embedded is a cloud-based file and document management system suitable for use in any application. SharePoint Embedded is a new API-only solution that enables app developers to harness the power of the Microsoft 365 file and document storage platform for any app, and is suitable for enterprises building line-of-business applications and ISVs building multitenant applications. + +SharePoint Embedded allows you to integrate advanced Microsoft 365 features into your apps including full-featured collaborative functions from Office, Purview's security and compliance tools, and Copilot capabilities. + +> [!IMPORTANT] +> Help us shape the future of SharePoint Embedded! +> Take our [quick survey](https://forms.microsoft.com/r/1YpGd2pAUS) and share your experience! + +## App documents stay in their Microsoft 365 tenant + +When a consumer uses a SharePoint Embedded application in their Microsoft 365 tenant, SharePoint Embedded creates another partition within their tenant. This storage partition doesn't have a user experience and the documents in the partition are only accessible via APIs. This means that all documents will be accessible to the developer’s application, but the documents will only reside in the consumer’s Microsoft 365 tenant. Within this new storage partition inside of a Microsoft 365 tenant, a SharePoint Embedded application can create many "File Storage Containers" for storing content. + +## Introducing File Storage Containers + +SharePoint Embedded applications use Microsoft Graph APIs to store files and documents in a new entity called a "File Storage Container” or Container for short.  If you’re an ISV, your app will create these containers in your customer’s Microsoft 365 tenant, and if you’re an enterprise, your app will create these containers in your own tenant. Each container provides a place to store files - you can think of them as similar to an API-only Document Library in SharePoint, but with some slight differences. Your app can create many of these containers inside each tenant that uses your app, and each container can be granted permissions separately storing many files with multiple terabytes of content. + +SharePoint Embedded containers are dedicated to and accessible by just your app, so the files and documents your app depends on are isolated and secure within that tenant boundary. + +## App-managed content experiences + +By default, the content stored within a Microsoft 365 tenant by a SharePoint Embedded application is only accessible through that owning application. Applications using SharePoint Embedded also provide the user experience layer for accessing and managing content, using some of the rich content capabilities that Microsoft 365 offers such as: + +- Core content management features like support for any file type and folder structure, searching, sharing, automatic versioning, recycle-bin, and more +- Collaboration features like view, edit, and co-authoring Office Word, Excel, and PowerPoint documents in Office Web and Desktop + +SharePoint Embedded is used by several types of applications: + +- Certain Microsoft products use SharePoint Embedded to manage customer content, such as Loop and Designer. +- ISVs can use SharePoint Embedded in their apps to manage content within their customer’s Microsoft 365 tenant +- Enterprises can use SharePoint Embedded to manage and store content within their own Microsoft 365 tenant, but outside of regular Microsoft 365 entitlements + +## Consumer Microsoft 365 settings apply to app documents + +All documents stored in the SharePoint partition created by the SharePoint Embedded app are in the consumer’s Microsoft 365 tenant and therefore are subject to the consumer’s Microsoft 365 tenant settings. + +This includes settings from Microsoft Purview compliance, risk, and security settings, documents can be opened from Office clients, and customers can use the Office web clients to view and collaborate on the documents. Choosing applications that are built on SharePoint Embedded provides the app consumer Microsoft Purview security and compliance capabilities on that app content, such as: + +- eDiscovery +- Auditing +- Data loss prevention (DLP) +- Retention policies, sensitivity labels, conditional access + +## Understanding the costs and billing for SharePoint Embedded content + +Microsoft 365 customers have different entitlements related to storage, usage, and features depending on the licenses the customer has purchased. + +The partition created in the consumer’s Microsoft 365 tenant by a SharePoint Embedded app doesn’t count towards other Microsoft 365 entitlements including the total amount of Microsoft SharePoint storage that can be used by your organization. Instead, the partition in the consumer’s Microsoft 365 tenant by the SharePoint Embedded app are billed separately through an Azure subscription on a pay-as-you-go metered consumption model that’s based on total storage and the number of API calls. + +> [!NOTE] +> Learn more about billing for SharePoint Embedded, see [Billing Meters](./administration/billing/meters.md). + +## Get Started with SharePoint Embedded + +[Review the prerequisites](./administration/billing/billing.md) + +Create a "File Storage Container" in 15 minutes or less: + +- [Free trial: SharePoint Embedded for Visual Studio Code](./getting-started/spembedded-for-vscode.md) + +Follow manual set-up on SharePoint Embedded from the following Microsoft Learning modules: + +- [Microsoft Learning: SharePoint Embedded - overview & configuration](/training/modules/sharepoint-embedded-setup) +- [Microsoft Learning: SharePoint Embedded - building applications](/training/modules/sharepoint-embedded-create-app) diff --git a/docs/embedded/scenarios-and-use-cases.md b/docs/embedded/scenarios-and-use-cases.md new file mode 100644 index 000000000..2c199f287 --- /dev/null +++ b/docs/embedded/scenarios-and-use-cases.md @@ -0,0 +1,71 @@ +--- +title: Scenarios and Use Cases +description: Scenarios and Use Cases for SharePoint Embedded +ms.date: 05/21/2024 +ms.localizationpriority: high +--- + +# Scenarios and use cases for SharePoint Embedded + +Use these example scenarios to prompt ideas about how custom applications can use SharePoint Embedded. + +> [!NOTE] +> This article is not intended to be an exhaustive list of all SharePoint Embedded features and scenarios. The intention is that these scenarios are contextualized examples of how combinations of features can be used. + +## Scenario: Structured user experience + +### Description + +Where your application requires a guided user experience to make users work in a structured way, rather than the flexible experience of SharePoint. + +Where your application is enabling a business-critical or time sensitive process, use the dedicated resource allocation of SharePoint Embedded to simplify management of throttling. + +### Examples + +- Extended Relationship Management (XRM) applications +- Engagement-based applications +- Workflow-based collaboration, with defined state + +### Why use SharePoint Embedded instead of SharePoint? + +- Your application is the only user interface, allowing you to create a prescriptive user experience +- Resources are separate from your Microsoft 365 entitlements– allowing for simpler resource management. + +## Scenario: Highly controlled collaboration + +### Description + +When building applications on top of SharePoint, it will still be possible for a user with permissions to navigate to the underlying site. Based on their permission level, a user might complete actions in the SharePoint interface that weren't intended by your application, for example changing site settings. These actions might have unintended consequences for your application or content. + +Because SharePoint Embedded is headless, there's no user interface other than what is provided by your custom application. If you don't supply a method to change content or settings through your application, then it won’t be possible for a user to circumvent this through SharePoint. You have the choice for which collaborative features are available in your application, for example sharing. + +### Examples + +- Deal room applications +- Shared research environments + +### Why use SharePoint Embedded instead of SharePoint? + +- You need the collaborative capabilities of SharePoint, only via a highly customized user interface +- You're handling high-value content, where you want to manage risk by removing abilities for a user to discover or alter the content repository +- All containers for the application can share default sharing settings that are separate from your OneDrive and SharePoint settings +- Content is logically separated from other Microsoft 365 content + +## Scenario: Customer facing document upload + +### Description + +Your application is aimed at an end customer, either within your organization or externally, who needs to upload a file as part of their interaction. You require a simplified end-user experience in your custom application, along with the Microsoft 365 capabilities of document storage and compliance. + +Using SharePoint Embedded will support this scenario, while not requiring the users of your application to have access or entitlement to your Microsoft 365 tenant. + +### Examples + +- Applying evidence to mortgage application +- Identity document verification + +### Why use SharePoint Embedded instead of SharePoint? + +- It's critical to segregate this data from the rest of your Microsoft 365 storage, while still being in scope for compliance tools like eDiscovery +- No Microsoft 365 licensing is required for users, or the use of external users in SharePoint +- Containers offer a simple, flexible unit of data storage diff --git a/docs/embedded/whats-new.md b/docs/embedded/whats-new.md new file mode 100644 index 000000000..4a0ba7af0 --- /dev/null +++ b/docs/embedded/whats-new.md @@ -0,0 +1,19 @@ +--- +title: What's new in SharePoint Embedded? +description: Updates about Microsoft SharePoint Embedded. +ms.date: 06/23/2025 +ms.localizationpriority: medium +--- + +# What's new in SharePoint Embedded + +## June 2025 + +- The `CopilotEmbeddedChatHosts` container type setting is now required to use [SharePoint Embedded agent](./development/declarative-agent/spe-da-adv.md#csp-policies). It must be set by the application owner via [`Set-SPOContainerTypeConfiguration`](/powershell/module/sharepoint-online/set-spocontainertypeconfiguration) and can optionally be overridden by consuming tenant administrators via [`Set-SPOApplication`](/powershell/module/SharePoint-online/set-spoapplication). + +## May 2025 + +- The limit of container types that a partner tenant can create has been increased to 25 by default. See [Limits and Calling Patterns](./development/limits-calling.md#size-limits). +- SharePoint Embedded agent switched to a consumption-based model for all users regardless of whether they have a Copilot license or not. See [SharePoint Embedded agent](./development/declarative-agent/spe-da.md). +- The guidance on how to grant admin consent to a SharePoint Embedded application has been updated to use URL-based admin consent. See [Authentication and authorization](./development/auth.md#whats-next). +- Documented an exceptional access pattern for operations that may require a user license. See [Authentication and authorization](./development/auth.md#operations-that-require-a-user-license). diff --git a/docs/features/embed-pages-to-teams.md b/docs/features/embed-pages-to-teams.md new file mode 100644 index 000000000..a4085809f --- /dev/null +++ b/docs/features/embed-pages-to-teams.md @@ -0,0 +1,13 @@ +--- +title: Embedding modern SharePoint pages in Microsoft Teams as personal apps +description: SharePoint pages can be embedded as personal apps in the Microsoft Teams. +ms.date: 06/28/2022 +ms.localizationpriority: high +--- + +# Embedding modern SharePoint pages in Microsoft Teams as personal apps + +_**Applies to:** Microsoft 365_ + +> [!Important] +> When you are planning to embed SharePoint sites in Microsoft Teams, please use the [Viva Connections model](/sharepoint/guide-to-setting-up-viva-connections) for the supported experience. diff --git a/docs/features/groupify/groupify-csom.md b/docs/features/groupify/groupify-csom.md index 472cb636a..32e38e055 100644 --- a/docs/features/groupify/groupify-csom.md +++ b/docs/features/groupify/groupify-csom.md @@ -1,16 +1,16 @@ --- -title: Connect to new Office 365 group - CSOM development -description: Client-side object model development for connecting to a new Office 365 group operation. -ms.date: 4/23/2018 -localization_priority: Priority +title: Connect to new Microsoft 365 group - CSOM development +description: Client-side object model development for connecting to a new Microsoft 365 group operation. +ms.date: 06/28/2022 +ms.localizationpriority: high --- -# Connect to new Office 365 group: CSOM development +# Connect to new Microsoft 365 group: CSOM development The SharePoint client-side object model (CSOM) provides access to the SharePoint object model from code that is running locally or on a different server than SharePoint. > [!IMPORTANT] -> It is **not** supported to connect a Communication site to Office 365 group. +> It is **not** supported to connect a Communication site to Microsoft 365 group. ## Prerequisites @@ -23,7 +23,7 @@ You also need to reference the [Microsoft.SharePointOnline.CSOM](https://www.nug ## CSOM code example -The following example shows how to create a __Microsoft.Online.SharePoint.TenantAdministration.Tenant__ object and call the __GetAllTenantThemes__ method to return a list of themes. +The following example shows how to create a __Microsoft.Online.SharePoint.TenantAdministration.Tenant__ object and call the __CreateGroupForSite__ method to return a list of themes. > [!NOTE] > * The URL used to create the context object includes the _-admin_ suffix, because **TenantAdministration** methods work with the admin site. @@ -44,23 +44,24 @@ foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c); ctx.Credentials = new SharePointOnlineCredentials("admin@mydomain.com", passWord); Tenant tenant = new Tenant(ctx); tenant.CreateGroupForSite("https://contoso.sharepoint.com/sites/team-site", "display-name-for-group", "alias-for-group", true); +ctx.ExecuteQuery(); ``` ## Methods in Microsoft.Online.SharePoint.TenantAdministration.Tenant class -Use the following methods to customize the set of available themes for a SharePoint tenant administration site. You can add a new custom theme, update an existing theme, or delete a theme, and you can retrieve a specific theme or all themes. You can also hide or restore the default themes that come with SharePoint. +Use the following methods to create a new Microsoft 365 Group and attach it to an existing site. ### CreateGroupForSite method -Create a new Office 365 group and attach it to an existing site. After this succeeds for a given site, calling it again with the same site will throw an Exception. +Create a new Microsoft 365 group and attach it to an existing site. After this succeeds for a given site, calling it again with the same site will throw an Exception. __Namespace:__ Microsoft.Online.SharePoint.TenantAdministration.Tenant
__Return type:__ void |Parameter | Type |Description | |----------- |------ |-------------| -| siteUrl | string | URL of the site to connect to a new Office 365 group. | +| siteUrl | string | URL of the site to connect to a new Microsoft 365 group. | | displayName | string | Display Name group to create. | | alias | string | Alias of the new group to create. | | isPublic | bool | Whether the group is public or private. | @@ -81,8 +82,5 @@ __type:__ Microsoft.Online.SharePoint.TenantAdministration.GroupCreationParams - When using POST to update a hub site with new information, use the following additional header values: | Header | Value | @@ -63,8 +61,7 @@ For GET, no request body is needed. When using POST to update a hub site with ne #### Sample request ```HTTP -GET -https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-499c-92db-38800eefbe44' +GET https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-499c-92db-38800eefbe44' ``` #### Sample response @@ -73,19 +70,19 @@ https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-49 ```JSON { - "@odata.context": "https://contoso.sharepoint.com/_api/$metadata#hubsites/$entity", - "@odata.type": "#SP.HubSite", - "@odata.id": "https://contoso.sharepoint.com/_api/HubSites/GetById", - "@odata.etag": "\"3\"", - "@odata.editLink": "HubSites/GetById", - "Description": null, - "ID": "f93eff08-5806-499c-92db-38800eefbe44", - "LogoUrl": "https://contoso.sharepoint.com/sites/marketing/SiteAssets/__hubLogo____hubLogo__.png", - "SiteId": "f93eff08-5806-499c-92db-38800eefbe44", - "SiteUrl": "https://contoso.sharepoint.com/sites/marketing", - "Targets": "", - "TenantInstanceId": "00000000-0000-0000-0000-000000000000", - "Title": "" + "@odata.context": "https://contoso.sharepoint.com/_api/$metadata#hubsites/$entity", + "@odata.type": "#SP.HubSite", + "@odata.id": "https://contoso.sharepoint.com/_api/HubSites/GetById", + "@odata.etag": "\"3\"", + "@odata.editLink": "HubSites/GetById", + "Description": null, + "ID": "f93eff08-5806-499c-92db-38800eefbe44", + "LogoUrl": "https://contoso.sharepoint.com/sites/marketing/SiteAssets/__hubLogo____hubLogo__.png", + "SiteId": "f93eff08-5806-499c-92db-38800eefbe44", + "SiteUrl": "https://contoso.sharepoint.com/sites/marketing", + "Targets": "", + "TenantInstanceId": "00000000-0000-0000-0000-000000000000", + "Title": "" } ``` @@ -94,8 +91,7 @@ https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-49 #### Sample request ```HTTP -POST -https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-499c-92db-38800eefbe44' +POST https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-499c-92db-38800eefbe44' ``` #### Sample response @@ -110,6 +106,28 @@ https://contoso.sharepoint.com/_api/HubSites/GetById?hubSiteId='f93eff08-5806-49 } ``` +### Associate a hub with another hub (parent hub association) + +#### Sample request + +```HTTP +POST https://contoso.sharepoint.com/_api/HubSites/GetById('f93eff08-5806-499c-92db-38800eefbe44') +``` + +```JSON +{ + "__metadata": { "type": "SP.HubSite" }, + "Title":"Marketing hub site", + "LogoUrl": "https://contoso.sharepoint.com/sites/marketing/SiteAssets/__hubLogo____hubLogo__.png", + "Description": "Hub site for marketing coordination", + "ParentHubSiteId":"269da5d4-6a9e-45a5-9502-a74d14977293" +} +``` + +#### Sample response + +**Status code:** 204 + ## See also - [Hub site REST API](hub-site-rest-api.md) diff --git a/docs/features/hub-site/REST-hubsitedata-method.md b/docs/features/hub-site/REST-hubsitedata-method.md index aba75ce34..9d0911b2d 100644 --- a/docs/features/hub-site/REST-hubsitedata-method.md +++ b/docs/features/hub-site/REST-hubsitedata-method.md @@ -1,8 +1,8 @@ --- title: HubSiteData REST method description: Gets hub site data for the current web. -ms.date: 6/18/2019 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # HubSiteData diff --git a/docs/features/hub-site/REST-hubsites-method.md b/docs/features/hub-site/REST-hubsites-method.md index c19a5fbcd..5db692961 100644 --- a/docs/features/hub-site/REST-hubsites-method.md +++ b/docs/features/hub-site/REST-hubsites-method.md @@ -1,8 +1,8 @@ --- title: HubSites REST method description: Gets information about all hub sites that the current user can access. -ms.date: 6/18/2019 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # HubSites diff --git a/docs/features/hub-site/REST-joinhubsite-method.md b/docs/features/hub-site/REST-joinhubsite-method.md index ab84427dd..0962b6db4 100644 --- a/docs/features/hub-site/REST-joinhubsite-method.md +++ b/docs/features/hub-site/REST-joinhubsite-method.md @@ -1,8 +1,8 @@ --- title: JoinHubSite REST method description: Associates a site with an existing hub site. You can also use this method to disassociate a site from a hub site. -ms.date: 6/18/2019 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # JoinHubSite diff --git a/docs/features/hub-site/REST-registerhubsite.method.md b/docs/features/hub-site/REST-registerhubsite.method.md index 4ee23cc85..50a8a7d82 100644 --- a/docs/features/hub-site/REST-registerhubsite.method.md +++ b/docs/features/hub-site/REST-registerhubsite.method.md @@ -1,8 +1,8 @@ --- title: RegisterHubSite REST method description: Registers an existing site as a hub site. -ms.date: 6/18/2019 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # RegisterHubSite diff --git a/docs/features/hub-site/REST-sphubsite-type.md b/docs/features/hub-site/REST-sphubsite-type.md index 394429cf4..36cfaad0d 100644 --- a/docs/features/hub-site/REST-sphubsite-type.md +++ b/docs/features/hub-site/REST-sphubsite-type.md @@ -1,8 +1,8 @@ --- title: SPHubSite object type -description: Contains data describing a SharePoint hub site. -ms.date: 6/18/2019 -localization_priority: Normal +description: The SPHubSite object type contains data describing a SharePoint hub site. +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # SPHubSite object type diff --git a/docs/features/hub-site/REST-sphubsitedata-type.md b/docs/features/hub-site/REST-sphubsitedata-type.md index 45014adc6..6457fbd56 100644 --- a/docs/features/hub-site/REST-sphubsitedata-type.md +++ b/docs/features/hub-site/REST-sphubsitedata-type.md @@ -1,8 +1,8 @@ --- title: SPHubSiteData object type -description: Contains data describing a SharePoint hub site. -ms.date: 6/18/2019 -localization_priority: Normal +description: The SPHubSiteData object type contains data describing a SharePoint hub site. +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # SPHubSiteData object type diff --git a/docs/features/hub-site/REST-synchubsitetheme-method.md b/docs/features/hub-site/REST-synchubsitetheme-method.md index 545e974ba..9980cfe9d 100644 --- a/docs/features/hub-site/REST-synchubsitetheme-method.md +++ b/docs/features/hub-site/REST-synchubsitetheme-method.md @@ -1,13 +1,13 @@ --- title: SyncHubSiteTheme REST method description: Applies any theme updates from the parent hub site. -ms.date: 6/18/2019 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # SyncHubSiteTheme -Applies any theme updates from the parent hub site. +Applies any theme updates from the parent hub site. ## HTTP request diff --git a/docs/features/hub-site/REST-unregisterhubsite-method.md b/docs/features/hub-site/REST-unregisterhubsite-method.md index 787f462fb..bc676626d 100644 --- a/docs/features/hub-site/REST-unregisterhubsite-method.md +++ b/docs/features/hub-site/REST-unregisterhubsite-method.md @@ -1,16 +1,13 @@ --- title: UnRegisterHubSite REST method description: Unregisters a hub site so that it is no longer a hub site. -ms.date: 4/20/2018 -localization_priority: Normal +ms.date: 06/28/2022 +ms.localizationpriority: medium --- # UnRegisterHubSite -> [!IMPORTANT] -> The hub sites feature is currently in preview and is subject to change. It is not currently supported for use in production environments. - -Unregisters a hub site so that it is no longer a hub site. It will become a regular site. Any sites associated with the hub site will no longer be associated. This can take up to an hour to propagate. If you want to speed up the process, first remove any associated sites before unregistering the hub site. +Unregisters a hub site so that it is no longer a hub site. It will become a regular site. Any sites associated with the hub site will no longer be associated. This can take up to an hour to propagate. If you want to speed up the process, first remove any associated sites before unregistering the hub site. ## HTTP request diff --git a/docs/features/hub-site/create-hub-site-with-powershell.md b/docs/features/hub-site/create-hub-site-with-powershell.md index efa2b5465..16c183783 100644 --- a/docs/features/hub-site/create-hub-site-with-powershell.md +++ b/docs/features/hub-site/create-hub-site-with-powershell.md @@ -1,74 +1,57 @@ --- title: Create SharePoint hub sites using PowerShell description: Example code for creating a SharePoint hub site by using PowerShell. -ms.date: 6/20/2019 -localization_priority: Priority +ms.date: 04/23/2025 +ms.localizationpriority: high --- # Create SharePoint hub sites by using PowerShell If you're a global or SharePoint admin in Office 365, you can convert any existing site to a hub site by using Microsoft PowerShell. In this example, you'll learn how to create a SharePoint hub site and to associate another site with it. In this scenario, you are setting up sites for the Contoso marketing department: + - You will create a hub site that all other marketing sites will be associated with. - You will then specify settings and permissions for the hub site. -- Finally, you will create a second site and associate it with the hub site. +- Finally, you will create a second site and associate it with the hub site. > [!NOTE] > To work with this example in SharePoint Online, we recommend that you use a developer tenant and not your production tenant. All of the following steps use a fictional tenant named "Contoso" that you can replace with your tenant name. -## Connect to SPO - -First, you need to connect to SharePoint Online by using PowerShell. The commands use both the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588) (-SPO) and the [SharePoint PnP PowerShell Online module](https://www.powershellgallery.com/packages/SharePointPnPPowerShellOnline) (-PnP). - -1. Start Windows PowerShell. - -2. Run the [Connect-SPOService](https://docs.microsoft.com/powershell/module/sharepoint-online/connect-sposervice?view=sharepoint-ps) cmdlet to connect to SharePoint Online. Sign in with your global or SharePoint admin credentials: +## Using PnP PowerShell - ```powershell - Connect-SPOService -Url "https://-admin.sharepoint.com" - ``` +The samples below can be performed using [PnP PowerShell](https://www.powershellgallery.com/packages/PnP.PowerShell). > [!NOTE] > In the remainder of this exercise, **contoso** will be used as the tenant name. Continue to use your own tenant name in place of **contoso**. -## Create a new hub site +[!INCLUDE [pnp-powershell](../../../includes/snippets/open-source/pnp-powershell.md)] -Next, create the marketing site that will serve as a hub site that other sites can associate with. The intent is that any sites that are marketing-oriented will be part of the hub site. This applies common navigation and branding across the associated sites, enables team members to search across all the sites associated with the single hub site, and takes advantage of other hub site features. +## Create a new hub site -1. Create the site using the [New-PnPSite](https://docs.microsoft.com/powershell/module/sharepoint-pnp/new-pnpsite) cmdlet: +First, we will create the marketing site that will serve as a hub site that other sites can associate with. The intent is that any sites that are marketing-oriented will be part of the hub site. This applies common navigation and branding across the associated sites, enables team members to search across all the sites associated with the single hub site, and takes advantage of other hub site features. - ```powershell - Connect-PnPOnline -SPOManagementShell - New-PnPSite -Type TeamSite - -title "Contoso marketing division" - -alias "marketing" - -Description "Main site for collaboration for marketing teams at Contoso" - ``` +1. Connect to the SharePoint Online Admin center using interactive login and [registered Azure AD (Entra ID)](https://pnp.github.io/powershell/articles/registerapplication.html) application: - The `-SPOManagementShell` parameter allows you to reuse the credentials you signed in with by using the Connect-SPOService cmdlet. + ```powershell + Connect-PnPOnline -Url https://contoso-admin.sharepoint.com -Interactive -ClientId + ``` - The cmdlet returns the URL of the new site similar to the following: +1. Create the site to be used as a hub site using the [New-PnPSite](https://pnp.github.io/powershell/cmdlets/New-PnPSite.html) cmdlet: - ``` - https://contoso.sharepoint.com/sites/marketing - ``` + ```powershell + New-PnPSite -Type TeamSite -Title "Contoso marketing division" -Alias "marketing" -Description "Main site for collaboration for marketing teams at Contoso" + ``` -2. Register the new marketing site as a hub site by using the [Register-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/register-spohubsite?view=sharepoint-ps) cmdlet: + The cmdlet returns the URL of the new site similar to the following: - ```powershell - Register-SPOHubSite -Site https://contoso.sharepoint.com/sites/marketing - ``` + ```http + https://contoso.sharepoint.com/sites/marketing + ``` - You will see output similar to the following: +1. Register the new marketing site as a hub site by using the [Register-PnPHubSite](https://pnp.github.io/powershell/cmdlets/Register-PnPHubSite.html) cmdlet: - ``` - ID : bf0245ee-6bff-48a5-968f-0f155e2b7bbc - Title : Contoso marketing division - SiteId : bf0245ee-6bff-48a5-968f-0f155e2b7bbc - SiteUrl : https://contoso.sharepoint.com/sites/marketing - LogoUrl : - Description : - Permissions : - ``` + ```powershell + Register-PnPHubSite -Site https://contoso.sharepoint.com/sites/marketing + ``` ## Set properties and permissions on the hub site @@ -76,85 +59,56 @@ The hub site doesn't have a logo or description yet. We also want to constrain i ### Set properties -1. Upload a logo image for the site by going to `https://contoso.sharepoint.com/sites/marketing/SiteAssets` and uploading any image you like. Make a note of the image file name. +1. Upload a logo image for the site by going to `https://contoso.sharepoint.com/sites/marketing/SiteAssets` and uploading any image you like. Make a note of the image file name. +1. Use the [Set-PnPHubSite](https://pnp.github.io/powershell/cmdlets/Set-PnPHubSite.html) cmdlet to set the logo and description. In place of `mylogo.jpg`, specify the name of the image that you uploaded: -2. Use the [Set-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/set-spohubsite?view=sharepoint-ps) cmdlet to set the logo and description. In place of `mylogo.jpg`, specify the name of the image that you uploaded: + ```powershell + Set-PnPHubSite + -Identity https://contoso.sharepoint.com/sites/marketing + -LogoUrl https://contoso.sharepoint.com/sites/marketing/SiteAssets/mylogo.jpg + -Description "Main hub site for collaboration on marketing activities across Contoso" + ``` - ```powershell - Set-SPOHubSite - -Identity https://contoso.sharepoint.com/sites/marketing - -LogoUrl https://contoso.sharepoint.com/marketing/SiteAssets/mylogo.jpg - -Description "Main hub site for collaboration on marketing activities across Contoso" - ``` +### Set permissions - You will see output similar to the following: +Now we will restrict access so that only the user `nestorw@contoso.com` can make changes to the hub site associations. - ``` - ID : bf0245ee-6bff-48a5-968f-0f155e2b7bbc - Title : Contoso marketing division - SiteId : bf0245ee-6bff-48a5-968f-0f155e2b7bbc - SiteUrl : https://contoso.sharepoint.com/sites/marketing - LogoUrl : https://contoso.sharepoint.com/sites/marketing/SiteAssets/mylogo.jpg - Description : Main hub site for collaboration on marketing activities across Contoso - Permissions : - ``` +- Run the [Grant-PnPHubSiteRights](https://pnp.github.io/powershell/cmdlets/Grant-PnPHubSiteRights.html) cmdlet to grant a user rights to the marketing hub site. We'll use `nestorw@contoso` in this example, but you can use any valid user on your tenant (you can specify multiple users by separating them with a comma): -### Set permissions + ```powershell + Grant-PnPHubSiteRights -Identity https://contoso.sharepoint.com/sites/marketing -Principals "nestorw@contoso" + ``` -Now we will restrict access so that only the user `nestorw@contoso` can make changes to the hub site associations. +## Create and associate a new site -- Run the [Grant-SPOHubSiteRights](https://docs.microsoft.com/powershell/module/sharepoint-online/grant-spohubsiterights?view=sharepoint-ps) cmdlet to grant a user rights to the marketing hub site. We'll use `nestorw@contoso` in this example, but you can use any valid user on your tenant (you can specify multiple users by separating them with a comma): +The final step is to create the site we want to associate with the hub. You can repeat these steps for as many sites as you want to join to the hub. - ```powershell - Grant-SPOHubSiteRights -Identity https://contoso.sharepoint.com/sites/marketing -Principals "nestorw@contoso" -Rights Join - ``` +1. Provision the site by using the [New-PnPSite](https://pnp.github.io/powershell/cmdlets/New-PnPSite.html) cmdlet: - You will see output similar to the following: + ```powershell + New-PnPSite -Type TeamSite -Title "Online advertising team" -Alias "online-advertising" -Description "For collaboration on online advertising resources" + ``` - ``` - ID : bf0245ee-6bff-48a5-968f-0f155e2b7bbc - Title : Contoso marketing division - SiteId : bf0245ee-6bff-48a5-968f-0f155e2b7bbc - SiteUrl : https://contoso.sharepoint.com/sites/marketing - LogoUrl : https://contoso.sharepoint.com/sites/marketing/SiteAssets/mylogo.jpg - Description : Main hub site for collaboration on marketing activities across Contoso - Permissions : {0#.f|membership|nestorw@contoso.onmicrosoft.com} - ``` + The cmdlet returns the URL of the new site similar to the following: -## Create and associate a new site + ```http: + https://contoso.sharepoint.com/sites/online-advertising + ``` -The final step is to create the site we want to associate with the hub. You can repeat these steps for as many sites as you want to join to the hub. +1. Associate this site with the hub site by using the [Add-PnPHubSiteAssociation](https://pnp.github.io/powershell/cmdlets/Add-PnPHubSiteAssociation.html) cmdlet: -1. Provision the site by using the [New-PnPSite](https://docs.microsoft.com/powershell/module/sharepoint-pnp/new-pnpsite?view=sharepoint-ps) cmdlet: - - ```powershell - New-PnPSite -Type TeamSite - -title "Online advertising team" - -alias "online-advertising" - -Description "For collaboration on online advertising resources" - ``` - - The cmdlet returns the URL of the new site similar to the following: - - ``` - https://contoso.sharepoint.com/sites/online-advertising - ``` - -2. Associate this site with the hub site by using the [Add-SPOHubSiteAssociation](https://docs.microsoft.com/powershell/module/sharepoint-online/add-spohubsiteassociation?view=sharepoint-ps) cmdlet: - - ```powershell - Add-SPOHubSiteAssociation - -Site https://contoso.sharepoint.com/sites/online-advertising - -HubSite https://contoso.sharepoint.com/sites/marketing - ``` + ```powershell + Add-PnPHubSiteAssociation + -Site https://contoso.sharepoint.com/sites/online-advertising + -HubSite https://contoso.sharepoint.com/sites/marketing + ``` ## Confirm the hub site is working To confirm, you can either: -- Run the [Get-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/get-spohubsite?view=sharepoint-ps) cmdlet. - -- Sign in to SharePoint Online and view the hub site directly at `https://contoso.sharepoint.com/sites/marketing`. +- Run the [Get-PnPHubSite](https://pnp.github.io/powershell/cmdlets/Get-PnPHubSite.html) cmdlet. +- Sign in to SharePoint Online and view the hub site directly at `https://contoso.sharepoint.com/sites/marketing`. The hub site navigation appears at the top of the site. If you go to the `https://contoso.sharepoint.com/sites/online-advertising` site, it shows the same hub site navigation at the top. diff --git a/docs/features/hub-site/hub-site-o365cli.md b/docs/features/hub-site/hub-site-o365cli.md index 0a6d07033..2ecea1787 100644 --- a/docs/features/hub-site/hub-site-o365cli.md +++ b/docs/features/hub-site/hub-site-o365cli.md @@ -1,28 +1,25 @@ --- -title: Office 365 CLI commands for SharePoint hub sites -description: Use Office 365 CLI to create and manage SharePoint hub sites. -ms.date: 6/18/2019 -localization_priority: Priority +title: CLI for Microsoft 365 commands for SharePoint hub sites +description: Use CLI for Microsoft 365 to create and manage SharePoint hub sites. +ms.date: 06/27/2024 +ms.localizationpriority: high --- -# Office 365 CLI commands for SharePoint hub sites +# CLI for Microsoft 365 commands for SharePoint hub sites -Use the Office 365 CLI commands to create and manage SharePoint hub sites. +Use the CLI for Microsoft 365 commands to create and manage SharePoint hub sites. -> [!NOTE] -> Office 365 CLI is an open-source tool with active community providing support for it. There is no SLA for the open-source tool support from Microsoft. +[!INCLUDE [pnp-o365cli](../../../includes/snippets/open-source/pnp-o365cli.md)] ## Get started -To run the Office 365 CLI commands, you'll need to do the following: +To run the CLI for Microsoft 365 commands, you'll need to do the following: 1. Download and install [NodeJS LTS version](https://nodejs.org/en/) +1. Follow the instructions at [Installing the CLI](https://pnp.github.io/cli-microsoft365/user-guide/installing-cli/) to install the CLI for Microsoft 365 on your machine +1. Follow the instructions at [Logging in to Office 365](https://pnp.github.io/cli-microsoft365/user-guide/connecting-microsoft-365) to connect to your SharePoint tenant. -2. Follow the instructions at [Installing the CLI](https://pnp.github.io/office365-cli/user-guide/installing-cli/) to install the Office 365 CLI on your machine - -3. Follow the instructions at [Logging in to Office 365](https://pnp.github.io/office365-cli/user-guide/connecting-office-365/) to connect to your SharePoint tenant. - -To verify your setup and connection, try using the [hubsite list](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-list/) command to list the current hub sites. If the cmdlet runs and returns with no errors, you're ready to proceed. +To verify your setup and connection, try using the [hubsite list](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-list/) command to list the current hub sites. If the cmdlet runs and returns with no errors, you're ready to proceed. ## Hub site commands @@ -30,17 +27,17 @@ The following commands are available for managing hub sites: |Command|Description| |------|-----------| -|[hubsite connect](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-connect)| Connects the specified site collection to the given hub site | -|[hubsite data get](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-data-get)| Get hub site data for the specified site | -|[hubsite disconnect](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-disconnect)| Disconnects the specifies site collection from its hub site | -|[hubsite get](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-get)| Gets information about the specified hub site | -|[hubsite list](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-list)| Lists hub sites in the current tenant | -|[hubsite register](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-register)| Registers the specified site collection as a hub site | -|[hubsite rights grant](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-rights-grant)| Grants permissions to join the hub site for one or more principals | -|[hubsite rights revoke](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-rights-revoke)| Revokes rights to join sites to the specified hub site for one or more principals | -|[hubsite set](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-set)| Updates properties of the specified hub site | -|[hubsite theme sync](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-theme-sync)| Applies any theme updates from the parent hub site. | -|[hubsite unregister](https://pnp.github.io/office365-cli/cmd/spo/hubsite/hubsite-unregister)| Unregisters the specifies site collection as a hub site | +|[hubsite connect](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-connect)| Connects the specified site collection to the given hub site | +|[hubsite data get](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-data-get)| Get hub site data for the specified site | +|[hubsite disconnect](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-disconnect)| Disconnects the specifies site collection from its hub site | +|[hubsite get](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-get)| Gets information about the specified hub site | +|[hubsite list](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-list)| Lists hub sites in the current tenant | +|[hubsite register](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-register)| Registers the specified site collection as a hub site | +|[hubsite rights grant](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-rights-grant)| Grants permissions to join the hub site for one or more principals | +|[hubsite rights revoke](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-rights-revoke)| Revokes rights to join sites to the specified hub site for one or more principals | +|[hubsite set](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-set)| Updates properties of the specified hub site | +|[hubsite theme sync](https://pnp.github.io/cli-microsoft365/cmd/spo/site/site-hubsite-theme-sync)| Applies any theme updates from the parent hub site. | +|[hubsite unregister](https://pnp.github.io/cli-microsoft365/cmd/spo/hubsite/hubsite-unregister)| Unregisters the specifies site collection as a hub site | ## See also diff --git a/docs/features/hub-site/hub-site-overview.md b/docs/features/hub-site/hub-site-overview.md index 1d46b5d20..dff8662cc 100644 --- a/docs/features/hub-site/hub-site-overview.md +++ b/docs/features/hub-site/hub-site-overview.md @@ -1,8 +1,8 @@ --- title: SharePoint hub sites overview description: SharePoint hub sites connect and organize sites based on organizational attributes such as project, department, division, or region. -ms.date: 4/20/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # SharePoint hub sites overview @@ -17,7 +17,7 @@ For more information about creating hub sites, see [Create SharePoint hub sites - We recommend that you select a communication site or a team site that uses the modern template. If you use a classic team site, the hub site navigation will only appear on modern pages, including document libraries, lists, and site contents. Hub site settings will only appear on modern pages. -- You can create up to 2000 hub sites for an organization. +- You can create up to 2000 hub sites for an organization. - If you set up [SharePoint Multi-Geo](../../solution-guidance/multigeo-introduction.md) for your organization, any geo location where the SharePoint workload is available can be associated with a hub site. @@ -29,5 +29,5 @@ For more information about creating hub sites, see [Create SharePoint hub sites ## See also - [PowerShell cmdlets for SharePoint hub sites](hub-site-powershell.md) -- [Office 365 CLI commands for SharePoint hub sites](hub-site-o365cli.md) +- [CLI for Microsoft 365 commands for SharePoint hub sites](hub-site-o365cli.md) - [Get to know the SharePoint REST service](../../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) diff --git a/docs/features/hub-site/hub-site-powershell.md b/docs/features/hub-site/hub-site-powershell.md index d4ff42a6f..58fa78c4d 100644 --- a/docs/features/hub-site/hub-site-powershell.md +++ b/docs/features/hub-site/hub-site-powershell.md @@ -1,8 +1,8 @@ --- title: PowerShell cmdlets for SharePoint hub sites description: Use PowerShell cmdlets to create and manage SharePoint hub sites. -ms.date: 6/18/2019 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # PowerShell cmdlets for SharePoint hub sites @@ -14,8 +14,7 @@ Use PowerShell cmdlets to create and manage SharePoint hub sites. To run the PowerShell cmdlets: 1. Download and install the [SharePoint Online Management Shell](https://www.microsoft.com/download/details.aspx?id=35588). If you already have a previous version of the shell installed, uninstall it first, and then install the latest version. - -2. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. +1. Follow the instructions at [Connect to SharePoint Online PowerShell](https://technet.microsoft.com/library/fp161372.aspx) to connect to your SharePoint tenant. To verify your setup, try using the **Get-SPOHubSite** cmdlet to read the current list of hub sites. If the cmdlet runs and returns with no errors, you're ready to proceed. @@ -25,16 +24,16 @@ The following PowerShell cmdlets are available for managing hub sites: |cmdlet|Description| |------|-----------| -|[Add-SPOHubSiteAssociation](https://docs.microsoft.com/powershell/module/sharepoint-online/add-spohubsiteassociation?view=sharepoint-ps)|Adds a new association between a site and a hub site.| -|[Remove-SPOHubSiteAssociation](https://docs.microsoft.com/powershell/module/sharepoint-online/remove-spohubsiteassociation?view=sharepoint-ps)|Removes an association between a site and a hub site.| -|[Get-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/get-spohubsite?view=sharepoint-ps)|Lists hub sites or hub site information.| -|[Grant-SPOHubSiteRights](https://docs.microsoft.com/powershell/module/sharepoint-online/grant-spohubsiterights?view=sharepoint-ps)|Grants rights to users or security groups to access the hub site.| -|[Register-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/register-spohubsite?view=sharepoint-ps)|Enables the hub site feature on a site to make it a hub site.| -|[Revoke-SPOHubSiteRights](https://docs.microsoft.com/powershell/module/sharepoint-online/revoke-spohubsiterights?view=sharepoint-ps)|Revokes rights for specified principals to a hub site.| -|[Set-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/set-spohubsite?view=sharepoint-ps)|Sets the hub site information such as name, logo, and description.| -|[Unregister-SPOHubSite](https://docs.microsoft.com/powershell/module/sharepoint-online/unregister-spohubsite?view=sharepoint-ps)|Disables the hub site feature on a site.| +|[Add-SPOHubSiteAssociation](/powershell/module/sharepoint-online/add-spohubsiteassociation)|Adds a new association between a site and a hub site.| +|[Remove-SPOHubSiteAssociation](/powershell/module/sharepoint-online/remove-spohubsiteassociation)|Removes an association between a site and a hub site.| +|[Get-SPOHubSite](/powershell/module/sharepoint-online/get-spohubsite)|Lists hub sites or hub site information.| +|[Grant-SPOHubSiteRights](/powershell/module/sharepoint-online/grant-spohubsiterights)|Grants rights to users or security groups to access the hub site.| +|[Register-SPOHubSite](/powershell/module/sharepoint-online/register-spohubsite)|Enables the hub site feature on a site to make it a hub site.| +|[Revoke-SPOHubSiteRights](/powershell/module/sharepoint-online/revoke-spohubsiterights)|Revokes rights for specified principals to a hub site.| +|[Set-SPOHubSite](/powershell/module/sharepoint-online/set-spohubsite)|Sets the hub site information such as name, logo, and description.| +|[Unregister-SPOHubSite](/powershell/module/sharepoint-online/unregister-spohubsite)|Disables the hub site feature on a site.| ## See also - [SharePoint hub sites overview](hub-site-overview.md) -- [Office 365 CLI commands for SharePoint hub sites](hub-site-o365cli.md) +- [CLI for Microsoft 365 commands for SharePoint hub sites](hub-site-o365cli.md) diff --git a/docs/features/hub-site/hub-site-rest-api.md b/docs/features/hub-site/hub-site-rest-api.md index 512729964..5f22dbf4b 100644 --- a/docs/features/hub-site/hub-site-rest-api.md +++ b/docs/features/hub-site/hub-site-rest-api.md @@ -1,15 +1,15 @@ --- title: Hub site REST API description: Overview of hub site REST API for creating hub sites and associating existing sites with hub sites. -ms.date: 4/20/2018 -localization_priority: Priority +ms.date: 06/28/2022 +ms.localizationpriority: high --- # Hub site REST API -You can use the SharePoint REST interface to register sites as hub sites, associate existing sites with hub sites, and obtain or update information about hub sites. +You can use the SharePoint REST interface to register sites as hub sites, associate existing sites with hub sites, and obtain or update information about hub sites. -The SharePoint Online (and SharePoint 2016 and later on-premises) REST service supports combining multiple requests into a single call to the service by using the OData $batch query option. +The SharePoint Online (and SharePoint 2016 and later on-premises) REST service supports combining multiple requests into a single call to the service by using the OData $batch query option. For details and links to code samples, see [Make batch requests with the REST APIs](../../sp-add-ins/make-batch-requests-with-the-rest-apis.md). @@ -17,12 +17,12 @@ For details and links to code samples, see [Make batch requests with the REST AP Before you get started, make sure that you're familiar with the following: -- [Get to know the SharePoint REST service](../../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) +- [Get to know the SharePoint REST service](../../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) - [Complete basic operations using SharePoint REST endpoints](../../sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints.md) ## REST commands -The following REST commands are available for working with site designs and site scripts: +The following REST commands are available for working with hub sites: - [SP.HubSites.CanCreate](REST-cancreate-method.md) – Returns whether the current user can create a hub site. Only tenant admins can create hub sites. - [GetById](REST-getbyid-method.md) – Gets or updates information about a hub site. @@ -50,4 +50,3 @@ To remove, or disassociate a site from a hub site, call [JoinHubSite](REST-joinh ## See also - [SharePoint hub sites overview](hub-site-overview.md) - diff --git a/docs/features/site-footer.md b/docs/features/site-footer.md index 9fc9eb5ea..eb1d37583 100644 --- a/docs/features/site-footer.md +++ b/docs/features/site-footer.md @@ -1,8 +1,8 @@ --- title: Overview of the SharePoint Site footer description: SharePoint Site footers can be used to show a logo or set of links/labels in a modern SharePoint site. They can be configured using the UI settings or by using APIs. -ms.date: 1/22/2019 -localization_priority: Priority +ms.date: 09/24/2023 +ms.localizationpriority: high --- # SharePoint Site Footer @@ -10,13 +10,15 @@ localization_priority: Priority Footers are a common branding / navigation control in websites and portals. SharePoint Communication sites will have an out-of-the box footer control, which can be controlled either using UI elements or by using APIs. This control supports following elements - 8 links or labels -- Footer logo +- Footer logo - Footer name > [!IMPORTANT] -> Footer will be enabled by default for all new communication sites after the feature is rolled out. Along with this update, the content bar (also referred to as the “social bar”) - which contains the Like, Comment, View and Save for Later icons - will be docked permanently on top of the Comments section on all modern pages and news posts. +> Footer will be enabled by default for all new communication sites after the feature is rolled out. Along with this update, the content bar (also referred to as the “social bar”) - which contains the Like, Comment, View and Save for Later icons - will be docked permanently on top of the Comments section on all modern pages and news posts. +> +> Footers don't appear in sites on mobile devices or apps. -## Sample footer +## Sample footer Following picture demonstrates a footer with a logo, footer name and labels and links. @@ -24,20 +26,18 @@ Following picture demonstrates a footer with a logo, footer name and labels and ## Controlling footer rendering using code or PowerShell -You can control the footer existence with a `FooterEnabled` property in the `Web` object. Following PowerShell scripts shows how this can be done using [PnP PowerShell cmdlets](https://docs.microsoft.com/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps): - -```ps - -Connect-PnPOnline -Url "" –Credentials (Get-Credential) -$web = Get-PnPWeb -$web.FooterEnabled = $false -$web.Update() -Invoke-PnPQuery +You can control the footer existence with a `FooterEnabled` property in the `Web` object. Following PowerShell scripts shows how this can be done using [PnP PowerShell cmdlets](/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets): +```powershell +Connect-PnPOnline -Url "" –Credentials (Get-Credential) +Set-PnPFooter -Enabled:$false # for disabling the footer +Set-PnPFooter -Enabled:$true # for enabling the footer ``` > [!NOTE] -> Above PowerShell scripts assumes that you have already installed PnP PowerShell cmdlets for your environment and you are not using multi-factor authentication. You can install PnP PowerShell cmdlets to your computer by opening PowerShell console in administrative mode and executing following command: `Install-Module SharePointPnPPowerShellOnline`. If you are using multi-factor authentication, you can enable MFA login by updating the `Connect-PnPOnline` line as follows: `Connect-PnPOnline -Url "" -UseWebLogin`. +> Above PowerShell scripts assumes that you have already installed PnP PowerShell cmdlets for your environment and you are not using multi-factor authentication. You can install PnP PowerShell cmdlets to your computer by opening PowerShell console in administrative mode and executing following command: `Install-Module PnP.PowerShell -Scope CurrentUser`. If you are using multi-factor authentication, you can enable MFA login by updating the `Connect-PnPOnline` line as follows: `Connect-PnPOnline -Url "" -Interactive`. + +[!INCLUDE [pnp-powershell](../../includes/snippets/open-source/pnp-powershell.md)] ## Controlling footer using the user interface diff --git a/docs/general-development/access-sharepoint-from-mobile-and-native-device-apps.md b/docs/general-development/access-sharepoint-from-mobile-and-native-device-apps.md index cf43f3def..bc4e82403 100644 --- a/docs/general-development/access-sharepoint-from-mobile-and-native-device-apps.md +++ b/docs/general-development/access-sharepoint-from-mobile-and-native-device-apps.md @@ -1,9 +1,9 @@ --- title: Access SharePoint from mobile and native device apps -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to access Sharepoint from mobile apps and other native device apps, and from external web applications. +ms.date: 06/10/2022 ms.assetid: 42014171-5ee5-421d-9cde-413efc3aecef -localization_priority: Priority +ms.localizationpriority: high --- @@ -16,7 +16,7 @@ SharePoint Add-ins, farm solutions, and "no code" sandboxed solutions are all ru > [!IMPORTANT] -> To test and debug on any platform, you need a **developer account on Office 365**. More info: [Set up a development environment for SharePoint Add-ins on Office 365](https://msdn.microsoft.com/library/b22ce52a-ae9e-4831-9b68-c9210af6dc54%28Office.15%29.aspx) or [Create a developer site on an existing Office 365 subscription](https://msdn.microsoft.com/library/2ec857d5-dc6f-4cf6-ba45-adc845ef2a25%28Office.15%29.aspx). +> To test and debug on any platform, you need a **developer account on Office 365**. More info: [Set up a development environment for SharePoint Add-ins on Office 365](/sharepoint/dev/sp-add-ins/set-up-a-development-environment-for-sharepoint-add-ins-on-office-365) or [Create a developer site on an existing Office 365 subscription](https://msdn.microsoft.com/library/2ec857d5-dc6f-4cf6-ba45-adc845ef2a25%28Office.15%29.aspx). @@ -76,5 +76,4 @@ You can build these apps on the ASP.NET platform or a non-Microsoft stack. If yo These apps **gain authorized access to SharePoint data by using access tokens** that are issued by the Azure Control Service (ACS) in compliance with the OAuth Authentication Code flow. For more, see [Authorization Code OAuth flow for SharePoint Add-ins](https://msdn.microsoft.com/library/e89e91c7-ea39-49b9-af5a-7f047a7e2ab7%28Office.15%29.aspx). -> [!IMPORTANT] -> Azure Access Control (ACS), a service of Azure Active Directory (Azure AD), will be retired on November 7, 2018. This retirement does not impact the SharePoint Add-in model, which uses the `https://accounts.accesscontrol.windows.net` hostname (which is not impacted by this retirement). For more information, see [Impact of Azure Access Control retirement for SharePoint Add-ins](https://dev.office.com/blogs/impact-of-azure-access-control-deprecation-for-sharepoint-add-ins). +[!INCLUDE [azure-acs-retirement](../../includes/snippets/azure-acs-deprecation.md)] diff --git a/docs/general-development/accessibility-in-sharepoint.md b/docs/general-development/accessibility-in-sharepoint.md index 190af8800..ea9313596 100644 --- a/docs/general-development/accessibility-in-sharepoint.md +++ b/docs/general-development/accessibility-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Accessibility in SharePoint +description: Learn about the features, products, and services that make SharePoint accessible for people with disabilities, and find developer resources that can help you design and build apps and websites that support key accessibility scenarios. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: c9106d47-c523-49c1-b9f1-cdd7420abd5e -localization_priority: Normal +ms.localizationpriority: medium --- @@ -37,7 +37,7 @@ Users who have site administrator responsibilities typically use the SharePoint -Users who have devices that support touch can use gestures to complete operations. For more information, see [Touch](https://docs.microsoft.com/windows/desktop/uxguide/inter-touch) on MSDN, and the [Office Touch Guide](https://office.microsoft.com/support/office-touch-guide-HA102823845.aspx) on Office.com. +Users who have devices that support touch can use gestures to complete operations. For more information, see [Touch](/windows/desktop/uxguide/inter-touch) on MSDN, and the [Office Touch Guide](https://office.microsoft.com/support/office-touch-guide-HA102823845.aspx) on Office.com. diff --git a/docs/general-development/accessing-a-schema.md b/docs/general-development/accessing-a-schema.md index 817750de0..09e945d3b 100644 --- a/docs/general-development/accessing-a-schema.md +++ b/docs/general-development/accessing-a-schema.md @@ -1,9 +1,9 @@ --- title: Accessing a Schema -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This topic shows one example of how you can access and look at a schema for the REST service in Excel Services. +ms.date: 06/03/2022 ms.assetid: 02613912-36f6-4edc-a915-165d12e60bc8 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/accessing-the-soap-api.md b/docs/general-development/accessing-the-soap-api.md index bf09a3c35..5486a00fe 100644 --- a/docs/general-development/accessing-the-soap-api.md +++ b/docs/general-development/accessing-the-soap-api.md @@ -1,12 +1,12 @@ --- title: Accessing the SOAP API -ms.date: 09/25/2017 +description: The SOAP API consists of methods and a set of complex type objects that you can use to access the complete functionality of Excel Web Services. +ms.date: 06/03/2022 keywords: soap f1_keywords: - soap -ms.prod: sharepoint ms.assetid: 36e8e3d5-83ac-4bd3-b556-1af132add3eb -localization_priority: Priority +ms.localizationpriority: high --- @@ -58,7 +58,7 @@ The following table describes each element in the URL. |:-----|:-----| | _server_
|The name of the server on which Microsoft SharePoint Server 2010 is deployed.
| | _customsite_
|A custom SharePoint Server 2010 site that the server administrator creates.
| -| _.asmx_
|The name of the Web service endpoint. For Excel Web Services, it is `ExcelService.asmx`.
| +| _\.asmx_
|The name of the Web service endpoint. For Excel Web Services, it is `ExcelService.asmx`.
| For more information about the WSDL format, see the World Wide Web Consortium (W3C) WSDL specification at http://www.w3.org/TR/wsdl. diff --git a/docs/general-development/add-in-scoped-external-content-types-in-sharepoint.md b/docs/general-development/add-in-scoped-external-content-types-in-sharepoint.md index a34523ee4..9530e038b 100644 --- a/docs/general-development/add-in-scoped-external-content-types-in-sharepoint.md +++ b/docs/general-development/add-in-scoped-external-content-types-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Add-in-scoped external content types in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes external content types that are installed or scoped at the add-in level in SharePoint and enable you to create data-rich SharePoint Add-ins using external data sources. +ms.date: 06/10/2022 ms.assetid: a34cbbba-dc38-4d3d-b796-d54b5848bdfb -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/add-sharepoint-capabilities.md b/docs/general-development/add-sharepoint-capabilities.md index 04de43627..8e62f2328 100644 --- a/docs/general-development/add-sharepoint-capabilities.md +++ b/docs/general-development/add-sharepoint-capabilities.md @@ -1,9 +1,9 @@ --- title: Add SharePoint capabilities -ms.date: 09/25/2017 -ms.prod: sharepoint +ms.date: 06/13/2022 +description: Describes how-to information about adding SharePoint features and capabilities to custom apps. ms.assetid: 11ecb65e-6dc5-4cf1-80ca-3c16418697b6 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/advanced-scenarios-and-additional-samples.md b/docs/general-development/advanced-scenarios-and-additional-samples.md index 5e648bee5..e24df89fa 100644 --- a/docs/general-development/advanced-scenarios-and-additional-samples.md +++ b/docs/general-development/advanced-scenarios-and-additional-samples.md @@ -1,60 +1,33 @@ --- title: Advanced Scenarios and Additional Samples -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This topic describes some advanced REST scenarios and additional samples. It provides links to webpages where you can get more detailed information. +ms.date: 01/14/2021 ms.assetid: 110bcc88-2b55-4d80-ab5c-dc3b9658e48d -localization_priority: Normal +ms.localizationpriority: medium --- - - # Advanced Scenarios and Additional Samples This topic describes some advanced REST scenarios and additional samples. It provides links to webpages where you can get more detailed information. - - - - > [!NOTE] -> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel -) endpoint. - - - - +> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel) endpoint. ## Passing Parameters to a Workbook The [Advanced Excel Services REST API Capabilities—Passing Parameters to a Spreadsheet](https://blogs.msdn.com/cumgranosalis/archive/2009/11/05/advanced-excel-services-rest-api-capabilities-where-things-get-interesting.aspx) sample shows you how to pass parameters in REST URLs, to modify the result that you get back. This sample demonstrates how, by passing parameters into the workbook, you are able to take advantage of the data and visualization, and you can also take advantage of the logic that is behind them. - - - ## Using URL Parameters with Excel Services Gadget The [Using Advanced REST Functionality with the Excel Services Gadget](https://blogs.msdn.com/cumgranosalis/archive/2009/11/06/bringing-it-all-back-home-using-advanced-rest-functionality-with-the-excel-services-gadget.aspx) sample shows you how to use the [Advanced Excel Services REST API Capabilities—Passing Parameters to a Spreadsheet](https://blogs.msdn.com/cumgranosalis/archive/2009/11/05/advanced-excel-services-rest-api-capabilities-where-things-get-interesting.aspx) sample with the [Excel Services Gadget](https://blogs.msdn.com/cumgranosalis/archive/2009/11/03/interoducing-the-excel-services-gadget.aspx). You can use the gadget to display the results that you get from the REST API. - - - ## Embedding Workbook Data The [Excel Services REST API Examples](https://www.microsoft.com/microsoft-365/blog/2009/11/09/excel-services-in-sharepoint-2010-rest-api-examples/) sample shows you how to use the REST API to embed workbook data in interesting ways. - - - ## More REST API Syntax Examples The [Excel Services REST API Syntax](https://www.microsoft.com/microsoft-365/blog/2009/11/05/excel-services-in-sharepoint-2010-rest-api-syntax/) blog entry provides additional Excel Services REST API syntax examples. - - - ## Ideas About How to Take Advantage of the REST API The [Excel Services REST API Examples](https://www.microsoft.com/microsoft-365/blog/2009/11/04/simple-access-to-spreadsheet-data-using-the-excel-services-2010-rest-api/) blog entry provides additional ideas about what you can do with the REST API in Excel Services. - - - - diff --git a/docs/general-development/architecture-of-the-windows-phone-sharepoint-list-application-template.md b/docs/general-development/architecture-of-the-windows-phone-sharepoint-list-application-template.md index a97807e2e..dde454c5d 100644 --- a/docs/general-development/architecture-of-the-windows-phone-sharepoint-list-application-template.md +++ b/docs/general-development/architecture-of-the-windows-phone-sharepoint-list-application-template.md @@ -1,9 +1,9 @@ --- title: Architecture of the Windows Phone SharePoint List Application template -ms.date: 09/25/2017 -ms.prod: sharepoint +ms.date: 06/13/2022 +description: Describes the design pattern of projects created from the Windows Phone SharePoint List Application template. ms.assetid: 2c09bd02-bed0-4293-a4d4-1778692e246a -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/authentication-authorization-and-security-in-sharepoint.md b/docs/general-development/authentication-authorization-and-security-in-sharepoint.md index a1c2076f8..c4459f33b 100644 --- a/docs/general-development/authentication-authorization-and-security-in-sharepoint.md +++ b/docs/general-development/authentication-authorization-and-security-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Authentication, authorization, and security in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +ms.date: 06/13/2022 +description: Describes some of the enhancements added to SharePoint including updates in authentication, authorization, and security. ms.assetid: 8734790c-eb75-4d78-9604-7cc23b33b693 -localization_priority: Priority +ms.localizationpriority: high --- @@ -22,7 +22,7 @@ The following are some of the enhancements added to SharePoint: - SharePoint continues to offer support for both claims and classic authentication modes. Claims authentication is the default authentication option in SharePoint. Classic-mode authentication is deprecated and can be managed only by using Windows PowerShell. A lot of features in SharePoint require claims-mode. - - The **MigrateUsers** method from SharePoint 2010 is now deprecated, it's no longer the correct way to migrate accounts. To migrate accounts, use the new Windows PowerShell cmdlet called `Convert-SPWebApplication`. For more information see [Migrate from classic-mode to claims-based authentication in SharePoint](https://docs.microsoft.com/sharepoint/upgrade-and-update/migrate-from-classic-mode-to-claims-based-authentication-in-sharepoint-2013). + - The **MigrateUsers** method from SharePoint 2010 is now deprecated, it's no longer the correct way to migrate accounts. To migrate accounts, use the new Windows PowerShell cmdlet called `Convert-SPWebApplication`. For more information see [Migrate from classic-mode to claims-based authentication in SharePoint](/sharepoint/upgrade-and-update/migrate-from-classic-mode-to-claims-based-authentication-in-sharepoint-2013). - Requirement to register claims providers is eliminated. However, you do have to pre-configure claims type. You can choose the characters for the claim type and there is no enforcement on the ordering of claim types. diff --git a/docs/general-development/authorization-users-groups-and-the-object-model-in-sharepoint.md b/docs/general-development/authorization-users-groups-and-the-object-model-in-sharepoint.md index ad2a82133..c18a7e6da 100644 --- a/docs/general-development/authorization-users-groups-and-the-object-model-in-sharepoint.md +++ b/docs/general-development/authorization-users-groups-and-the-object-model-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Authorization, users, groups, and the object model in SharePoint -ms.date: 11/15/2018 -ms.prod: sharepoint +ms.date: 06/13/2022 +description: Describes authorization, users, groups, and the object model in SharePoint. ms.assetid: aacf3398-f0b5-48cb-9071-440b4c3a9dd1 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/basic-uri-structure-and-path.md b/docs/general-development/basic-uri-structure-and-path.md index 119f42f09..86c10a404 100644 --- a/docs/general-development/basic-uri-structure-and-path.md +++ b/docs/general-development/basic-uri-structure-and-path.md @@ -1,179 +1,92 @@ --- title: Basic URI Structure and Path -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This article provides a link explaining how to construct the URI structure and path for REST service commands in Excel Services. +ms.date: 06/07/2022 ms.assetid: d73cf6c2-0677-4726-8a3e-2ad130e1a12c -localization_priority: Priority +ms.localizationpriority: high --- # Basic URI Structure and Path This topic explains how to construct the URI structure and path for REST service commands in Excel Services. - + > [!NOTE] -> -> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel +> +> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](https://graph.microsoft.io/docs/api-reference/v1.0/resources/excel ) endpoint. - - - - ## Basic URL Structure and Path -The REST API in Excel Services gives you the ability to access resources like charts, PivotTables, tables, and named ranges in a workbook directly through a URL. Each REST URL in Excel Services is built of three parts. Following is the basic structure of the URL to access the resources in a workbook: - - - +The REST API in Excel Services gives you the ability to access resources like charts, PivotTables, tables, and named ranges in a workbook directly through a URL. Each REST URL in Excel Services is built of three parts. Following is the basic structure of the URL to access the resources in a workbook: 1. **REST aspx Page URI** The entry point to an .aspx page - - -2. **Workbook Location** The path to the workbook - - -3. **Resource Location** The path to the requested resource inside the workbook - - -Following is the construct for the REST URL to a specific element in a workbook: - - - - +1. **Workbook Location** The path to the workbook +1. **Resource Location** The path to the requested resource inside the workbook +Following is the construct for the REST URL to a specific element in a workbook: -``` - +```http http:///_vti_bin/ExcelRest.aspx/// ``` Following is an example of how a REST URL in Excel Services looks with all three parts combined. In this example, the REST URL is accessing a workbook called "sampleWorkbook.xlsx" that contains a chart called "SampleChart": - - - - - -``` +```http http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model/Charts('SampleChart') ``` -The workbook is stored in a document library. The full path to the workbook is `http://` __ `/Docs/Documents/sampleWorkbook.xlsx`. - - - +The workbook is stored in a document library. The full path to the workbook is `http://` _\_ `/Docs/Documents/sampleWorkbook.xlsx`. + The three parts of the REST URL are: - - - - -1. **REST aspx Page URI**: `http://` __ `/_vti_bin/ExcelRest.aspx` - - -2. **Workbook Location**: `/Docs/Documents/sampleWorkbook.xlsx` - - -3. **Resource Location**: `/model/Ranges('nameOfTheNamedRange')` - - + +1. **REST aspx Page URI**: `http://` _\_ `/_vti_bin/ExcelRest.aspx` +1. **Workbook Location**: `/Docs/Documents/sampleWorkbook.xlsx` +1. **Resource Location**: `/model/Ranges('nameOfTheNamedRange')` ### Accessing by Using the Discovery User Interface You can also access the chart by using the discovery user interface. To learn how access resources like charts, tables, PivotTables, and ranges by using the discovery mechanism shown in the following screen shot, see [Discovery in Excel Services REST API](discovery-in-excel-services-rest-api.md). - - - - - - ![Excel Services REST model URL](../images/SharePointServer14Con_XLSvcs_RESTModel.gif) - - - - - - - - - - - - - - - ### Marker Path Following is the aspx page for the REST service in Excel Services: - - - -``` +```http http:///_vti_bin/ExcelRest.aspx ``` -To access the REST service in Excel Services, you must preface the URL with `http://` __ `/_vti_bin/ExcelRest.aspx`. - - - +To access the REST service in Excel Services, you must preface the URL with `http://` _\_ `/_vti_bin/ExcelRest.aspx`. ### Workbook Location -The workbook location is the relative path to the workbook that has resources that you are interested in accessing. For example, assume that you have a workbook named sampleWorkbook.xlsx, saved to a trusted SharePoint document library. In this example, following is the path to the location of sampleWorkbook.xlsx: - - - +The workbook location is the relative path to the workbook that has resources that you are interested in accessing. For example, assume that you have a workbook named sampleWorkbook.xlsx, saved to a trusted SharePoint document library. In this example, following is the path to the location of sampleWorkbook.xlsx: -``` +```http http:///Docs/Documents/sampleWorkbook.xlsx ``` You take the relative path to the workbook ( `Docs/Documents/sampleWorkbook.xlsx`) and append it to the marker path. Following is the URL with the marker path and workbook location appended: - - - - - -``` +```http http:///_vti_bin/ExcelRest.aspx ``` - ### Resource Location The resource location is the path inside the workbook to the element that you request. For example, if you want to get a chart, the resource location would be similar to `/model/Charts('Chart 1')`. - - - -For the full URL, you append this to the marker path and the relative path to the workbook. Following is the full example URL: - - - - +For the full URL, you append this to the marker path and the relative path to the workbook. Following is the full example URL: -``` +```http http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model/Charts('Chart 1') - ``` - ## See also +### Concepts -#### Concepts - - - - - - [Resources URI for Excel Services REST API](resources-uri-for-excel-services-rest-api.md) - - - - [Discovery in Excel Services REST API](discovery-in-excel-services-rest-api.md) +- [Resources URI for Excel Services REST API](resources-uri-for-excel-services-rest-api.md) +- [Discovery in Excel Services REST API](discovery-in-excel-services-rest-api.md) diff --git a/docs/general-development/bcs-client-object-model-reference-for-sharepoint.md b/docs/general-development/bcs-client-object-model-reference-for-sharepoint.md index 79242e367..802acb419 100644 --- a/docs/general-development/bcs-client-object-model-reference-for-sharepoint.md +++ b/docs/general-development/bcs-client-object-model-reference-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: BCS client object model reference for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Guidelines explaining what objects are available to create client-side scripts using the SharePoint client object model. +ms.date: 06/07/2022 ms.assetid: fe7d12a3-6ea9-47f9-b69e-f66da9e661dc -localization_priority: Normal +ms.localizationpriority: medium --- @@ -480,7 +480,7 @@ The namespace is **Microsoft.BusinessData.MetadataModel**.
-- **Does the tag need to be included in a CAML query when querying an external list** +- **Does the \ tag need to be included in a CAML query when querying an external list** No. diff --git a/docs/general-development/bcs-rest-api-reference-for-sharepoint.md b/docs/general-development/bcs-rest-api-reference-for-sharepoint.md index a8469ece0..3306bb260 100644 --- a/docs/general-development/bcs-rest-api-reference-for-sharepoint.md +++ b/docs/general-development/bcs-rest-api-reference-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: BCS REST API reference for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Reference for constructing Representational State Transfer (REST) URLs using Business Connectivity Services (BCS) in SharePoint. +ms.date: 06/07/2022 ms.assetid: 364fb8d7-87d9-4be7-affd-90caba3cd0c0 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/bdc-model-schema-reference-for-sharepoint.md b/docs/general-development/bdc-model-schema-reference-for-sharepoint.md index c1629a120..f1bdccae9 100644 --- a/docs/general-development/bdc-model-schema-reference-for-sharepoint.md +++ b/docs/general-development/bdc-model-schema-reference-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: BDC model schema reference for SharePoint +description: Contains reference documentation for the BDC model schema (BDCMetadata.xsd), which you can use to create external content types in SharePoint. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 979a5ffc-f033-4e72-b2d1-11d8cb1b294a -localization_priority: Normal +ms.localizationpriority: medium --- @@ -2235,7 +2235,7 @@ The following sections describe attributes, child elements, and parent elements. |:-----|:-----| | [LocalizedDisplayNames Element in MetadataObject (BDCMetadata Schema)](https://msdn.microsoft.com/library/3202aecf-f98f-20cb-1fdd-f3a054cb24aa%28Office.15%29.aspx)
|The localized names of the parameter.
| | [Properties Element in MetadataObject (BDCMetadata Schema)](https://msdn.microsoft.com/library/9901904f-96ee-0cbb-64a9-c2aad9d72128%28Office.15%29.aspx)
|The properties of the parameter.
| -| [TypeDescriptor](https://docs.microsoft.com/dotnet/api/system.componentmodel.typedescriptor)
|The root type descriptor of the parameter.
| +| [TypeDescriptor](/dotnet/api/system.componentmodel.typedescriptor)
|The root type descriptor of the parameter.
| **Parent element** @@ -2367,7 +2367,7 @@ None | [Method Element in Methods (BDCMetadata Schema)](https://msdn.microsoft.com/library/70e87a9e-4959-0a7b-3f37-ddec36473ff4%28Office.15%29.aspx)
|| | [FilterDescriptor Element in FilterDescriptors (BDCMetadata Schema)](https://msdn.microsoft.com/library/8ce0a852-38f9-75d2-8258-27c57418f53c%28Office.15%29.aspx)
|| | [Parameter Element in Parameters (BDCMetadata Schema)](https://msdn.microsoft.com/library/811cad0b-ba71-8be0-0765-3e0dec18a0d3%28Office.15%29.aspx)
|| -| [TypeDescriptor](https://docs.microsoft.com/dotnet/api/system.componentmodel.typedescriptor)
|| +| [TypeDescriptor](/dotnet/api/system.componentmodel.typedescriptor)
|| | [TypeDescriptor Element (BDCMetadata Schema)](https://msdn.microsoft.com/library/ae423de8-c13b-aea5-d47b-17ef786fb5a7%28Office.15%29.aspx)
|| | [Association Element in MethodInstances (BDCMetadata Schema)](https://msdn.microsoft.com/library/9659a1f5-1b12-03ef-f9e3-5c9904cc5dd0%28Office.15%29.aspx)
|| | [MethodInstance Element in MethodInstances (BDCMetadata Schema)](https://msdn.microsoft.com/library/577ff9d0-706b-be7d-af5b-883e137cada8%28Office.15%29.aspx)
|| @@ -2728,7 +2728,7 @@ None |**Element**|**Description**| |:-----|:-----| | [TypeDescriptor Element (BDCMetadata Schema)](https://msdn.microsoft.com/library/ae423de8-c13b-aea5-d47b-17ef786fb5a7%28Office.15%29.aspx)
|| -| [TypeDescriptor](https://docs.microsoft.com/dotnet/api/system.componentmodel.typedescriptor)
|| +| [TypeDescriptor](/dotnet/api/system.componentmodel.typedescriptor)
|| ## See also diff --git a/docs/general-development/build-farm-solutions-in-sharepoint.md b/docs/general-development/build-farm-solutions-in-sharepoint.md index 15c1d6cc0..a0892c7e9 100644 --- a/docs/general-development/build-farm-solutions-in-sharepoint.md +++ b/docs/general-development/build-farm-solutions-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Build farm solutions in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article providing links for documentation about developing, packaging and deploying build farm solutions in SharePoint. +ms.date: 06/07/2022 ms.assetid: 96c32f08-ad93-49af-b8d0-9d194a48cc79 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/build-localized-applications-for-windows-phone-based-on-the-sharepoint-templates.md b/docs/general-development/build-localized-applications-for-windows-phone-based-on-the-sharepoint-templates.md index c4c97c933..3b6e71d05 100644 --- a/docs/general-development/build-localized-applications-for-windows-phone-based-on-the-sharepoint-templates.md +++ b/docs/general-development/build-localized-applications-for-windows-phone-based-on-the-sharepoint-templates.md @@ -1,9 +1,9 @@ --- title: Build localized applications for Windows Phone based on the SharePoint templates -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to learn how to build a localizable Windows Phone app using SharePoint templates. +ms.date: 06/07/2022 ms.assetid: c12d7fd4-8c6b-446b-970b-1eb0e5d0a9b2 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/build-mobile-apps-for-other-platforms-using-sharepoint.md b/docs/general-development/build-mobile-apps-for-other-platforms-using-sharepoint.md index f85a4e682..276d2d87d 100644 --- a/docs/general-development/build-mobile-apps-for-other-platforms-using-sharepoint.md +++ b/docs/general-development/build-mobile-apps-for-other-platforms-using-sharepoint.md @@ -1,106 +1,107 @@ --- title: Build mobile apps for other platforms using SharePoint +description: Learn how to use Representational State Transfer (REST) to create a SharePoint mobile app for any platform. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 017df869-44fb-4ffe-82fb-4654e01329ad -localization_priority: Priority +ms.localizationpriority: high --- # Build mobile apps for other platforms using SharePoint Learn how to use Representational State Transfer (REST) to create a SharePoint mobile app for any platform. + Mobile devices have become more powerful and easy to use nowadays. Laptops, netbooks, tablet PCs, and mobile phones provide workers access to the information and applications that they need to do their jobs. And developing applications for mobile devices is now easier than ever. As a result, more and more business scenarios demand integrating client applications together with their business processes. This article describes how to integrate mobile client apps together with SharePoint. You can create a mobile app to browse SharePoint content from any location and connect with SharePoint lists and libraries to access data. - - - + + + To develop a mobile app that interacts with SharePoint, you can use common services that can be accessed using open protocols. SharePoint Foundation 2010 introduced the client object models, which enabled developers to perform remote communication with SharePoint by using the web programming technology of their choice: .NET Framework, Microsoft Silverlight, or JavaScript. SharePoint introduces a Representational State Transfer (REST) service that is fully comparable to the client object models. In SharePoint, nearly every API in the client object models will have a corresponding REST endpoint. Now, developers can interact remotely with the SharePoint object model by using any technology that supports REST web requests. REST can be consumed by any programming language that you want to use for your mobile application development. You can perform basic create, read, update, and delete (CRUD) operations by using the REST interface provided by SharePoint. REST exposes all of the SharePoint entities and operations that are available in the other SharePoint client APIs. One advantage of using REST is that you don't have to add references to any SharePoint libraries or client assemblies. Instead, you make HTTP requests to the appropriate endpoints to retrieve or update SharePoint entities, such as webs, lists, and list items. For a thorough introduction to the SharePoint REST interface and its architecture, see [Use OData query operations in SharePoint REST requests](https://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72%28Office.15%29.aspx). - - - + + + ## REST endpoints in SharePoint To use the REST capabilities that are built into SharePoint, you can construct a RESTful HTTP request using the Open Data Protocol (OData) standard that corresponds to the desired client object model API. The client.svc web service handles the HTTP request and serves the appropriate response, in either Atom or JavaScript Object Notation (JSON) format. The client application must then parse that response. Figure 1 shows a high-level view of the SharePoint REST architecture. - - - + + + **Figure 1. SharePoint REST architecture** - - - - - - + + + + + + ![SharePoint REST architecture](../images/SP15Con_BuildSharePointAppsForMobileDevices_Fig2.png) - - - + + + The endpoints in the SharePoint REST service correspond to the types and members in the SharePoint client object models. By using HTTP requests, you can use these REST endpoints to perform typical CRUD operations against SharePoint artifacts, such as lists and sites. - - - + + + In general: - - - + + + - Endpoints that represent read operations map to HTTP **GET** commands. - - + + - Endpoints that represent update operations map to HTTP **POST** commands. - - + + - Endpoints that represent update or insert operations map to HTTP **PUT** commands. - - + + In choosing an HTTP request to use, you should also consider the following: - - - + + + - Use **POST** to create artifacts such as lists and sites. The SharePoint REST service supports sending **POST** commands that include object definitions to endpoints that represent collections. - - + + - For **POST** operations, any properties that are not required are set to their default values. If you try to set a read-only property as part of a **POST** operation, the service returns an exception. - - + + - Use **PUT**, **PATCH**, and **MERGE** operations to update existing SharePoint objects. Any service endpoint that represents an object property **set** operation supports both **PUT** requests and **MERGE** requests. For **MERGE** requests, setting properties is optional; any properties that you do not explicitly set retain their current property. But for **PUT** commands, any properties you do not explicitly set are set to their default properties. In addition, if you do not specify all settable properties in object updates when you use HTTP **PUT** commands, the REST service returns an exception. - - + + - Use the HTTP **DELETE** command against the specific endpoint URL to delete the SharePoint object represented by that endpoint. For recyclable objects, such as lists, files, and list items, this results in a **Recycle** operation. For more information, see [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx). - - + + ## Authenticate users to SharePoint To authenticate your mobile app with SharePoint, you can use the MS-OFBA protocol. For more information, see [[MS-OFBA]: Office Forms Based Authentication Protocol Specification](https://msdn.microsoft.com/library/30c7bbe9-b284-421f-b866-4e7ed4866027%28Office.15%29.aspx). The protocol client is configured to store and transmit cookies. The protocol client relies on the remote protocol server to set the user's identity as one or more HTTP cookies. After the user's identity is established, the client then sends each cookie with each subsequent HHT request. - - - + + + When a user signs in to SharePoint, the user's token is validated and then used to sign in to SharePoint. The user's token is a security token that is issued by an identity provider. SharePoint supports several kinds of authentication. For more information, see [Authentication, authorization, and security in SharePoint](authentication-authorization-and-security-in-sharepoint.md). To authenticate a user, you can use the REST interface. The authorization process verifies that an authenticated subject (an app or a user the app is acting on behalf of.md) has permission to perform certain operations or to access specific resources (for example, a list or a SharePoint document folder.md). - - - + + + OData lets you access a data source, such as a database, by browsing to a specially constructed URL. This allows for a simplified approach for connecting to, and working with, data sources that are hosted within an organization. OData is a protocol that uses HTTP, Atom, and JavaScript Object Notation (JSON) to enable developers to write applications that communicate with an ever-growing number of data sources. Microsoft supports the creation of this standard as a way to enable the exchange of data between applications and data stores that can be accessed from the web. The new OData connector enables SharePoint to communicate with OData providers. For more information, see [Open Data Protocol](http://www.odata.org). - - - + + + The following code demonstrates how to authenticate your app to SharePoint using REST endpoints for basic or forms-based authentication. The following code example is written in C#, but any other programming language can be used to create the Http request, as per the requirement of the platform. - - - -```cs + + + +```csharp string SharePointUrl = "https://Target SharePoint site"; @@ -118,7 +119,7 @@ void odataAt_AuthenticationCompleted(object sender, AuthenticationCompletedEvent endpointRequest.Method = "GET"; endpointRequest.Accept = "application/json;odata=verbose"; endpointRequest.CookieContainer = (sender as ODataAuthenticator).CookieContainer; - + endpointRequest.BeginGetResponse(new AsyncCallback((IAsyncResult res) => { HttpWebRequest webReq = res.AsyncState as HttpWebRequest; @@ -136,21 +137,21 @@ void odataAt_AuthenticationCompleted(object sender, AuthenticationCompletedEvent ``` To authenticate an **HttpWebrequest** to the endpoint, you should first authenticate to SharePoint with the **ODataAuthenticator** class. Before calling the **Authenticate** method, register the **ODataAuthenticator** object to the **AuthenticationCompleted** event. - - - + + + After authentication is done inside the **OnAuthenticationCompleted** event, you can use the **CookieContainer** property on the **ODataAuthenticator** object, which can be attached to the **HttpWebRequest** object to authenticate the REST calls to SharePoint. - - - + + + ## Work with SharePoint list items using REST The following example shows how to **retrieve** all of a list's items. - - - + + + ``` @@ -166,9 +167,9 @@ headers: ``` The following example shows how to **retrieve** a specific list item. - - - + + + @@ -177,7 +178,7 @@ The following example shows how to **retrieve** a specific list item. url: http://site url/_api/web/lists/GetByTitle('Test')/items(item id) method: GET headers: - + // MS-OFBA protocol return a cookie. Cookie: cookie accept: "application/json;odata=verbose" or "application/atom+xml" @@ -185,9 +186,9 @@ headers: ``` The following XML shows an example of the list item properties that are returned when you request the XML content type. - - - + + + @@ -212,13 +213,13 @@ The following XML shows an example of the list item properties that are returned ``` The following example shows how to **create** a list item. - + > [!NOTE] -> +> > To do this operation, you must know the **ListItemEntityTypeFullName** property of the list and pass that as the value of **type** in the HTTP request body. - - - + + + @@ -229,7 +230,7 @@ url: http://site url/_api/web/lists/GetByTitle('Test')/items method: POST body: { '__metadata': { 'type': 'SP.Data.TestListItem' }, 'Title': 'Test'} headers: - + // MS-OFBA protocol returns a cookie. Cookie: cookie X-RequestDigest = form digest value @@ -239,12 +240,12 @@ headers: ``` The following example shows how to **update** a list item. - + > [!NOTE] > To do this operation, you must know the **ListItemEntityTypeFullName** property of the list and pass that as the value of **type** in the HTTP request body. - - - + + + @@ -266,9 +267,9 @@ headers: ``` The following example shows how to **delete** a list item. - - - + + + @@ -286,42 +287,19 @@ headers: ``` For more information, see [Complete basic operations using SharePoint REST endpoints](https://msdn.microsoft.com/library/e3000415-50a0-426e-b304-b7de18f2f7d9%28Office.15%29.aspx). - - - + + + ## See also - - - -- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) - - -- [Using the SharePoint REST service](https://docs.microsoft.com/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service) - - -- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) - - -- [Choose the right API set in SharePoint](choose-the-right-api-set-in-sharepoint.md) - - -- [Use OData query operations in SharePoint REST requests](https://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72%28Office.15%29.aspx) - - -- [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx) - - -- [Open Data Protocol](http://www.odata.org/) - - -- [Authorization and authentication of SharePoint Add-ins](https://msdn.microsoft.com/library/bde5647a-fff1-4b51-b67b-2139de79ce4a%28Office.15%29.aspx) - - -- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) - - -- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) - - +- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) +- [Get to know the SharePoint REST service](../sp-add-ins/get-to-know-the-sharepoint-rest-service.md) +- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) +- [Choose the right API set in SharePoint](choose-the-right-api-set-in-sharepoint.md) +- [Use OData query operations in SharePoint REST requests](https://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72%28Office.15%29.aspx) +- [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx) +- [Open Data Protocol](http://www.odata.org/) +- [Authorization and authentication of SharePoint Add-ins](https://msdn.microsoft.com/library/bde5647a-fff1-4b51-b67b-2139de79ce4a%28Office.15%29.aspx) +- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) +- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) diff --git a/docs/general-development/build-reusable-components-for-sharepoint.md b/docs/general-development/build-reusable-components-for-sharepoint.md index 7ff1b3bf8..2245e988a 100644 --- a/docs/general-development/build-reusable-components-for-sharepoint.md +++ b/docs/general-development/build-reusable-components-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: Build reusable components for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links summarizing the most common reusable components you can build in SharePoint. +ms.date: 06/07/2022 ms.assetid: bb4467e2-57f0-4cf1-91b8-4d3d8d2358cb -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/build-sites-for-sharepoint.md b/docs/general-development/build-sites-for-sharepoint.md index 1f583c9ff..32222ca2f 100644 --- a/docs/general-development/build-sites-for-sharepoint.md +++ b/docs/general-development/build-sites-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: Build sites for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to learn about the new site authoring and publishing model for websites in SharePoint. +ms.date: 06/07/2022 ms.assetid: 3b372a63-7cdf-462a-abb4-750e611e967d -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/build-windows-phone-apps-that-access-sharepoint.md b/docs/general-development/build-windows-phone-apps-that-access-sharepoint.md index cab6a3ec2..0bcd5d7b8 100644 --- a/docs/general-development/build-windows-phone-apps-that-access-sharepoint.md +++ b/docs/general-development/build-windows-phone-apps-that-access-sharepoint.md @@ -1,38 +1,28 @@ --- title: Build Windows Phone apps that access SharePoint -ms.date: 04/19/2018 -ms.prod: sharepoint +ms.date: 06/09/2022 ms.assetid: 36681335-f772-4499-8445-f94481bc18e7 description: Create SharePoint Add-ins that integrate SharePoint and mobile devices such as Windows Phone 8 and Windows Phone 7. -localization_priority: Normal +ms.localizationpriority: medium --- - # Build Windows Phone apps that access SharePoint SharePoint provides an exciting opportunity for developers to build mobile apps that travel with users, are interactive and attractive, and are available whenever and wherever users want to work with them. You can combine Windows Phone 8 and Windows Phone 7 applications with on-premises SharePoint services and applications, or with remote SharePoint services and applications that run in the cloud (such as those that use SharePoint Online) to create powerful applications that extend the functionality beyond the traditional desktop or laptop and into a truly portable and much more accessible environment. - + The new mobility features offered by SharePoint are built on existing Microsoft tools and technologies, such as SharePoint, Windows Phone, Visual Studio, and Silverlight. Developers who are already familiar with those technologies and their related tools will be able to create SharePoint-powered mobile apps for Windows Phone without a steep learning curve. In this section, we explore some of the types of SharePoint-powered mobile apps you can build for Windows Phone 8 and Windows Phone 7 and the most common ways to customize those applications. SharePoint provides a framework and tools for developers, including Visual Studio 2010 project templates, to create mobile solutions that interact with SharePoint data both in on-premises SharePoint installations and in the cloud by using SharePoint Online. Figure 1 shows how a simple list application could look on Windows Phone. - - + **Figure 1. SharePoint list items in a Windows Phone app** ![SharePoint list items in a Windows Phone app](../images/9159345c-ce12-41a6-8994-fc2e9aa26fd6.gif) - - ## What skills do you need to create mobile apps? In this section, we assume that you're familiar with SharePoint, the .NET Framework, the Visual Studio development system, and Visual C#. It's also good to have some experience with Windows Phone 8 or Windows Phone 7 application development using Silverlight, and it helps to be familiar with XAML, the StackPanel and Pivot controls for Windows Phone, and concepts such as tombstoning, Silverlight data binding, and so on. If you are new to Windows Phone application development using Silverlight, we recommend that you check out the following resources. -- [Developing a Windows Phone Application from Start to Finish](https://msdn.microsoft.com/library/gg680270%28v=pandp.11%29.aspx) - -- [User interface for Windows Phone](https://msdn.microsoft.com/library/windowsphone/develop/ff967556%28v=vs.105%29.aspx) - -- [Quickstart: Creating a user interface with XAML for Windows Phone](https://msdn.microsoft.com/library/windowsphone/develop/jj207025%28v=vs.105%29.aspx) - -- [Pivot control architecture for Windows Phone](https://msdn.microsoft.com/library/windowsphone/develop/ff941097%28v=vs.105%29.aspx) - - +- [Developing a Windows Phone Application from Start to Finish](https://msdn.microsoft.com/library/gg680270%28v=pandp.11%29.aspx) +- [User interface for Windows Phone](https://msdn.microsoft.com/library/windowsphone/develop/ff967556%28v=vs.105%29.aspx) +- [Quickstart: Creating a user interface with XAML for Windows Phone](https://msdn.microsoft.com/library/windowsphone/develop/jj207025%28v=vs.105%29.aspx) +- [Pivot control architecture for Windows Phone](https://msdn.microsoft.com/library/windowsphone/develop/ff941097%28v=vs.105%29.aspx) ## Development overview for mobile apps using SharePoint @@ -40,34 +30,34 @@ You can build a wide variety of mobile apps using SharePoint. This section descr ### Windows Phone SharePoint Application template -This is the simplest type of mobile app you can build to bring a regular list to the phone. SharePoint offers a Visual Studio template to enable you to quickly and easily create SharePoint list applications for the Windows Phone. For example, you can build a "To Do List"-type Windows Phone application that brings your task list from SharePoint into the Windows Phone and enables the you to use your phone to update the status of a task on the go. Another example is having the product catalog for an inventory list in SharePoint available on the phone for the sales people. +This is the simplest type of mobile app you can build to bring a regular list to the phone. SharePoint offers a Visual Studio template to enable you to quickly and easily create SharePoint list applications for the Windows Phone. For example, you can build a "To Do List"-type Windows Phone application that brings your task list from SharePoint into the Windows Phone and enables the you to use your phone to update the status of a task on the go. Another example is having the product catalog for an inventory list in SharePoint available on the phone for the sales people. -Installing the Windows Phone SharePoint SDK makes two Windows Phone SharePoint Application templates available to you in Visual Studio 2010 or Visual Studio 2010 Express for Windows Phone (see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md)). +Installing the Windows Phone SharePoint SDK makes two Windows Phone SharePoint Application templates available to you in Visual Studio 2010 or Visual Studio 2010 Express for Windows Phone (see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md)). Using the Windows Phone SharePoint List Application template, you can follow the steps of a wizard to create a functional Windows Phone app that can access and manipulate data in a SharePoint list. ### New and enhanced mobility object model in SharePoint SharePoint adds several new classes to both the server and client object models to enable the SharePoint mobility scenarios that we described earlier in this article. - -To enable location-aware apps, there is a new native field type class, **SPFieldGeoLocation**, along with several associated classes for structuring the value of location fields and rendering them. These classes are also callable in the SharePoint client object model for Silverlight. The new field type also has a definition added to the standard SharePoint fldtypes.xml file and new user controls for rendering the field on the Display, Edit, and New forms. For an overview, see [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md). + +To enable location-aware apps, there is a new native field type class, **SPFieldGeoLocation**, along with several associated classes for structuring the value of location fields and rendering them. These classes are also callable in the SharePoint client object model for Silverlight. The new field type also has a definition added to the standard SharePoint fldtypes.xml file and new user controls for rendering the field on the Display, Edit, and New forms. For an overview, see [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md). To enable SharePoint authentication for Windows Phone users, the client object model includes a new **Authenticator** class and several associated classes. For an overview, see [Overview of the SharePoint mobile client authentication object model](overview-of-the-sharepoint-mobile-client-authentication-object-model.md). - -To enable automatic notifications to Windows Phone users of events on a SharePoint farm, the server object model includes several new classes, each of which is also callable from the client object model. These classes include methods that enable phone apps to register with SharePoint server apps for notifications about specified types of events. There are also methods that the server apps use to send notifications to registered subscribers. For an overview, see [Create a Windows Phone SharePoint list app to receive push notifications](how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md#BKMK_NotificationPhoneApp). - + +To enable automatic notifications to Windows Phone users of events on a SharePoint farm, the server object model includes several new classes, each of which is also callable from the client object model. These classes include methods that enable phone apps to register with SharePoint server apps for notifications about specified types of events. There are also methods that the server apps use to send notifications to registered subscribers. For an overview, see [Create a Windows Phone SharePoint list app to receive push notifications](how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md#create-a-windows-phone-sharepoint-list-app-to-receive-push-notifications). + With SharePoint, you're not limited to mobile app development just for Windows Phone 8 and Windows Phone 7. With the JavaScript programming interface and the new Representational State Transfer (REST) programming interface provided by SharePoint, you can create applications for non-Windows Phone mobile devices; you can interact with SharePoint sites by using JavaScript that executes as scripts in the browser, or remotely by using any technology that supports standard REST capabilities. The following section provides an overview of the REST and JavaScript programming interfaces. #### ECMAScript (JavaScript, JScript) object model architecture SharePoint Foundation 2010 introduced the client object models, which enabled developers to perform remote communication with SharePoint by using the web programming technology of their choice: the .NET Framework, Silverlight, or JavaScript. - + In SharePoint Foundation 2010, the client object models provide APIs that enable developers to interact with SharePoint sites from script that executes in the browser, from code (based on the .NET Framework 3.5 or later) that executes in a .NET Framework-managed application, or from code that executes in a Silverlight 2.0 application. The proxy .js and managed .dll files that compose the client object models are built on the client.svc web service, and handle the effective batching, serialization of requests, and parsing of replies. Figure 2 shows a high-level view of the SharePoint client object model architecture. **Figure 2. SharePoint client object model architecture** - + ![SharePoint client object model architecture](../images/SP15Con_BuildSharePointAppsForMobileDevices_Fig3.png) - + To learn how to use the JavaScript client object model against SharePoint data, see the [ECMAScript Client Object Model video](https://msdn.microsoft.com/SP2010DevTrainingCourse_ECMAScriptClientObjectModel.aspx). #### REST endpoints in SharePoint @@ -75,65 +65,44 @@ To learn how to use the JavaScript client object model against SharePoint data, To use the REST capabilities that are built into SharePoint, you can construct a RESTful HTTP request using the Open Data Protocol (OData) standard that corresponds to the desired client object model API. The client.svc web service handles the HTTP request and serves the appropriate response, in either Atom or JavaScript Object Notation (JSON) format. The client application must then parse that response. Figure 3 shows a high-level view of the SharePoint REST architecture. **Figure 3. SharePoint REST architecture** - + ![SharePoint REST architecture](../images/SP15Con_BuildSharePointAppsForMobileDevices_Fig2.png) - + Currently, the REST service in SharePoint is read-only. That is, only REST endpoints that represent an HTTP GET operation are available - + By default, the SharePoint REST service responses are formatted using the Atom protocol, according to the OData specification. In addition, the REST service supports HTTP Accept headers that enable developers to specify that the response is returned in JSON format. To learn more about REST services in SharePoint, see [Use OData query operations in SharePoint REST requests](https://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72%28Office.15%29.aspx). - + The SharePoint REST service supports the following OData query operators: - Filter - Take - Expand - - ## Start developing mobile apps for SharePoint The following how-tos and overviews delve into the specific information you need to start your mobile app development: -- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) - -- [Overview of Windows Phone SharePoint application templates in Visual Studio](overview-of-windows-phone-sharepoint-application-templates-in-visual-studio.md) - -- [Architecture of the Windows Phone SharePoint List Application template](architecture-of-the-windows-phone-sharepoint-list-application-template.md) - -- [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) - -- [How to: Store and retrieve SharePoint list items on a Windows Phone](how-to-store-and-retrieve-sharepoint-list-items-on-a-windows-phone.md) - -- [How to: Implement business logic and data validation in a Windows Phone app for SharePoint](how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md) - -- [How to: Support and convert SharePoint field types for Windows Phone apps](how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md) +- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) +- [Overview of Windows Phone SharePoint application templates in Visual Studio](overview-of-windows-phone-sharepoint-application-templates-in-visual-studio.md) +- [Architecture of the Windows Phone SharePoint List Application template](architecture-of-the-windows-phone-sharepoint-list-application-template.md) +- [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) +- [How to: Store and retrieve SharePoint list items on a Windows Phone](how-to-store-and-retrieve-sharepoint-list-items-on-a-windows-phone.md) +- [How to: Implement business logic and data validation in a Windows Phone app for SharePoint](how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md) +- [How to: Support and convert SharePoint field types for Windows Phone apps](how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md) +- [How to: Customize list item queries and filter data for Windows Phone apps](how-to-customize-list-item-queries-and-filter-data-for-windows-phone-apps.md) +- [How to: Customize the user interface of a SharePoint list app for Windows Phone](how-to-customize-the-user-interface-of-a-sharepoint-list-app-for-windows-ph.md) +- [How to: Use multiple SharePoint lists in a Windows Phone app](how-to-use-multiple-sharepoint-lists-in-a-windows-phone-app.md) +- [How to: Configure and use push notifications in SharePoint apps for Windows Phone](how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md) +- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) +- [How to: Create a mobile app in SharePoint that contains data from an external data source](how-to-create-a-mobile-app-in-sharepoint-that-contains-data-from-an-externa.md) +- [How to: Integrate maps with Windows Phone apps and SharePoint lists](how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md) +- [How to: Build search-driven mobile apps with the Navigation and Event Logging REST interfaces](how-to-build-search-driven-mobile-apps-with-the-navigation-and-event-logging-res.md) -- [How to: Customize list item queries and filter data for Windows Phone apps](how-to-customize-list-item-queries-and-filter-data-for-windows-phone-apps.md) - -- [How to: Customize the user interface of a SharePoint list app for Windows Phone](how-to-customize-the-user-interface-of-a-sharepoint-list-app-for-windows-ph.md) - -- [How to: Use multiple SharePoint lists in a Windows Phone app](how-to-use-multiple-sharepoint-lists-in-a-windows-phone-app.md) - -- [How to: Configure and use push notifications in SharePoint apps for Windows Phone](how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md) - -- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) - -- [How to: Create a mobile app in SharePoint that contains data from an external data source](how-to-create-a-mobile-app-in-sharepoint-that-contains-data-from-an-externa.md) - -- [How to: Integrate maps with Windows Phone apps and SharePoint lists](how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md) - -- [How to: Build search-driven mobile apps with the Navigation and Event Logging REST interfaces](how-to-build-search-driven-mobile-apps-with-the-navigation-and-event-logging-res.md) - ## See also -- [Programming models in SharePoint](programming-models-in-sharepoint.md) -- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) -- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) -- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) -- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=27570) -- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) -- [About Expression Blend](https://msdn.microsoft.com/library/cc296376%28Expression.40%29.aspx) - - - +- [Programming models in SharePoint](programming-models-in-sharepoint.md) +- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) +- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) +- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=29233) +- [About Expression Blend](https://msdn.microsoft.com/library/cc296376%28Expression.40%29.aspx) diff --git a/docs/general-development/building-search-queries-in-sharepoint.md b/docs/general-development/building-search-queries-in-sharepoint.md index 346b021ba..d95fc24dd 100644 --- a/docs/general-development/building-search-queries-in-sharepoint.md +++ b/docs/general-development/building-search-queries-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Building search queries in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links about the search syntax supported in SharePoint for building query rules and search queries. +ms.date: 06/07/2022 ms.assetid: c4372fcc-4574-4c81-a345-a1bb282ca8f7 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/business-connectivity-services-in-sharepoint.md b/docs/general-development/business-connectivity-services-in-sharepoint.md index 09679533a..fa6d231e3 100644 --- a/docs/general-development/business-connectivity-services-in-sharepoint.md +++ b/docs/general-development/business-connectivity-services-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Business Connectivity Services in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to learn about Business Connectivity Services (BCS) and get started developing BCS applications in SharePoint. +ms.date: 06/07/2022 ms.assetid: 64b7d032-4b83-4e9e-bc08-f0a161af5457 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/business-connectivity-services-programmers-reference-for-sharepoint.md b/docs/general-development/business-connectivity-services-programmers-reference-for-sharepoint.md index 39e8fe2c1..2350e05c9 100644 --- a/docs/general-development/business-connectivity-services-programmers-reference-for-sharepoint.md +++ b/docs/general-development/business-connectivity-services-programmers-reference-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: Business Connectivity Services programmers reference for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to find reference information to create solutions using Business Connectivity Services (BCS) in SharePoint. +ms.date: 06/07/2022 ms.assetid: cfc9bdf8-ddf3-40e1-83d9-dbd304cebd57 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/changes-in-the-bdc-model-schema-for-sharepoint.md b/docs/general-development/changes-in-the-bdc-model-schema-for-sharepoint.md index 26792b791..ceb41318b 100644 --- a/docs/general-development/changes-in-the-bdc-model-schema-for-sharepoint.md +++ b/docs/general-development/changes-in-the-bdc-model-schema-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: Changes in the BDC model schema for SharePoint +description: Learn what has changed in SharePoint for the BDC model schema. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 882ea867-9acb-4313-99c9-865a523b72fd -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/choose-the-right-api-set-in-sharepoint.md b/docs/general-development/choose-the-right-api-set-in-sharepoint.md index 19978dc84..8734f8b1b 100644 --- a/docs/general-development/choose-the-right-api-set-in-sharepoint.md +++ b/docs/general-development/choose-the-right-api-set-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Choose the right API set in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to learn about SharePoint APIs including the server object model, various client object models and the REST/OData web service. +ms.date: 06/07/2022 ms.assetid: f36645da-77c5-47f1-a2ca-13d4b62b320d -localization_priority: Priority +ms.localizationpriority: high --- # Choose the right API set in SharePoint diff --git a/docs/general-development/claims-based-identity-and-concepts-in-sharepoint.md b/docs/general-development/claims-based-identity-and-concepts-in-sharepoint.md index e664823bb..171dc84f4 100644 --- a/docs/general-development/claims-based-identity-and-concepts-in-sharepoint.md +++ b/docs/general-development/claims-based-identity-and-concepts-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Claims-based identity and concepts in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to learn about the claims-based identity model and concepts in SharePoint. +ms.date: 06/07/2022 ms.assetid: d96c7cf4-2e48-4223-a3c0-42368d079b74 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/claims-based-identity-in-sharepoint.md b/docs/general-development/claims-based-identity-in-sharepoint.md index 9934beb0e..49a81f2c7 100644 --- a/docs/general-development/claims-based-identity-in-sharepoint.md +++ b/docs/general-development/claims-based-identity-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Claims-based identity in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about the fundamentals of claims-based identity architecture in SharePoint. +ms.date: 06/07/2022 ms.assetid: 32b6af2a-72f3-4302-a6af-5f00143cbf67 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/claims-based-identity-term-definitions.md b/docs/general-development/claims-based-identity-term-definitions.md index e7cb54d44..8fcf7b8d0 100644 --- a/docs/general-development/claims-based-identity-term-definitions.md +++ b/docs/general-development/claims-based-identity-term-definitions.md @@ -1,9 +1,9 @@ --- title: Claims-based identity term definitions -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Definitions of key terms related to claims-based identity. +ms.date: 06/07/2022 ms.assetid: 0f3decb5-dcd8-432f-9bb8-533f2d01bef7 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/claims-provider-in-sharepoint.md b/docs/general-development/claims-provider-in-sharepoint.md index ed648e69c..6c27c9da2 100644 --- a/docs/general-development/claims-provider-in-sharepoint.md +++ b/docs/general-development/claims-provider-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Claims provider in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about the claims provider in SharePoint. +ms.date: 06/07/2022 ms.assetid: 5918d5b6-5fd6-4f41-9473-a15b1491d056 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/client-side-web-parts-maintenance-mode.md b/docs/general-development/client-side-web-parts-maintenance-mode.md index 9f0a07341..7a9543bcd 100644 --- a/docs/general-development/client-side-web-parts-maintenance-mode.md +++ b/docs/general-development/client-side-web-parts-maintenance-mode.md @@ -1,15 +1,12 @@ --- title: Maintenance mode for client-side web parts -ms.date: 12/18/2017 -ms.prod: sharepoint +description: When working with client-side web parts, you can load them in maintenance mode. The maintenance mode can be helpful when trying to debug issues related to web parts placed on the page. +ms.date: 04/28/2023 ms.assetid: 3ebd2a11-8291-4228-add0-9e0cd899dd3c -localization_priority: Normal +ms.localizationpriority: medium --- - # Maintenance mode for client-side web parts -_**Applies to:** Office 365_ - When working with client-side web parts, you can load them in maintenance mode. The maintenance mode can be helpful when trying to debug issues related to web parts placed on the page. ## Switch to maintenance mode @@ -17,13 +14,13 @@ When working with client-side web parts, you can load them in maintenance mode. > [!NOTE] > In order to load a page in the maintenance mode, you have to have edit permissions for that specific page. -To switch to the maintenance mode, navigate to the page and in the URL append `?maintenancemode=true`, for example: +To switch to the maintenance mode, navigate to the page and in the URL append **?maintenancemode=true**, for example: ```text https://contoso.sharepoint.com/sites/team?maintenancemode=true ``` -To leave the maintenance mode, remove `?maintenancemode=true` from the URL and reload the page. +To leave the maintenance mode, remove **?maintenancemode=true** from the URL and reload the page. ## Available information @@ -31,16 +28,16 @@ The maintenance mode shows various information about each web part on the page. ### Web part summary -When in maintenance mode, for each web part you will see the following summary information: +When in maintenance mode, for each web part you'll see the following summary information: ![Web part summary information displayed in maintenance mode](../images/maintenance-mode-summary.png) Property|Description --------|----------- Alias|Web part alias -Id|The unique ID of the web part -InstanceId|The ID of a specific instance of a web part (that is, if you have two more of the same web parts on a page, they will each have the same web part ID, but a different instance ID. -IsInternal|Indicates whether the web part was made by Microsoft or a third party. If `true`, it is made by Microsoft. If `false`, it is made by a third party. +ID|The unique ID of the web part +InstanceId|The ID of a specific instance of a web part (that is, if you have two more of the same web parts on a page, they'll each have the same web part ID, but a different instance ID. +IsInternal|Indicates whether the web part was made by Microsoft or a third party. If `true`, it's made by Microsoft. If `false`, it's made by a third party. Version|The version number of the web part. Environment|Enumeration indicating the environment on which the web part is running. Possible values: `1` - Local Workbench, `2` - SharePoint UserAgent|A string that contains information about the device and software in use (such as browser type and version). @@ -54,7 +51,7 @@ To get more information about the web part, switch to the **Manifest** tab. By exploring the manifest information, you can learn details such as: - where the web part bundle is hosted -- which external scripts is the web part loading and from where +- which external scripts are the web part loading and from where - what version of the SharePoint Framework has the web part been built on - which components of the SharePoint Framework does the web part use @@ -66,18 +63,28 @@ Another piece of information available in the maintenance mode, is web part data ![Web part data information displayed in maintenance mode](../images/maintenance-mode-data.png) -Using the information from the **Data** tab, you can see the configuration for each web part. This is helpful when trying to reproduce errors reported by users which could be caused by a specific web part configuration. +Using the information from the **Data** tab, you can see the configuration for each web part. This is helpful when trying to reproduce errors reported by users that could be caused by a specific web part configuration. If the web part [integrates its properties with SharePoint](../spfx/web-parts/guidance/integrate-web-part-properties-with-sharepoint.md), the data section shows the types and values that are passed to SharePoint for further processing. ## Considerations -- the maintenance mode works for client-side web parts placed on both modern and classic SharePoint pages. See the [Open and use the web part maintenance page](https://support.office.com/article/Open-and-use-the-web-part-maintenance-page-eff9ce22-d04a-44dd-ae83-ac29a5e396c2#PickTab=2016,_2013) support article, to get more information about opening classic web parts in maintenance view -- to open page in maintenance mode, you have to have edit permissions for that page -- when in maintenance mode, web part code is not being executed and you cannot edit web part properties -- in maintenance mode, you can delete or move web parts on the page -- the maintenance mode shows only information about web parts. You cannot use it to show information about SharePoint Framework extensions that are executed on the page -- switching to maintenance mode only disables executing web part code. Any SharePoint Framework extensions registered on the page will still execute +- The maintenance mode works for client-side web parts placed on both modern and classic SharePoint pages. See the [Open and use the web part maintenance page](https://support.office.com/article/Open-and-use-the-web-part-maintenance-page-eff9ce22-d04a-44dd-ae83-ac29a5e396c2#PickTab=2016,_2013) support article, to get more information about opening classic web parts in maintenance view. +- To open page in maintenance mode, you have to have edit permissions for that page +- When in maintenance mode, web part code isn't being executed and you can't edit web part properties. +- In maintenance mode, you can delete or move web parts on the page. +- The maintenance mode shows only information about web parts. You can't use it to show information about SharePoint Framework extensions that are executed on the page. +- Switching to maintenance mode only disables executing web part code. Any SharePoint Framework extensions registered on the page will still execute. + +## Disable SPFx web parts and extensions + +If you need to troubleshoot a SharePoint page to see if there is a SharePoint Framework extension or web part causing issues you can append **?disable3PCode** to the URL to disable loading of SPFx components, for example: + +```text +https://contoso.sharepoint.com/sites/team?disable3PCode +``` + +This will prevent loading of any third party SPFx components on the page. ## See also diff --git a/docs/general-development/code-samples-for-sharepoint.md b/docs/general-development/code-samples-for-sharepoint.md index ba84eb344..dae9dde63 100644 --- a/docs/general-development/code-samples-for-sharepoint.md +++ b/docs/general-development/code-samples-for-sharepoint.md @@ -1,27 +1,23 @@ --- title: Code samples for SharePoint +description: Find and download code samples for SharePoint, including samples that demonstrate SharePoint Framework, SharePoint Add-ins, user experience design, metadata management, workflows, mobile application development, REST, and other areas of SharePoint development. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: e6b52c6c-32f8-4689-8c1a-7b50039dcbe8 -localization_priority: Priority +ms.localizationpriority: high --- - - # Code samples for SharePoint Find and download code samples for SharePoint, including samples that demonstrate SharePoint Framework, SharePoint Add-ins, user experience design, metadata management, workflows, mobile application development, REST, and other areas of SharePoint development. -- [SharePoint Code Samples](https://developer.microsoft.com/SharePoint/gallery?filterBy=SharePoint,Samples) +- [SharePoint Code Samples](https://developer.microsoft.com/SharePoint/gallery?filterBy=SharePoint,Samples) > [!NOTE] > Code sample catalog has been moved to Office Dev portal, which provides you great filtering and search capabilities to find what's relevant for you. - ## See also - -- [SharePoint development](https://docs.microsoft.com/sharepoint/dev/) -- [How-tos for SharePoint](how-tos-for-sharepoint.md) -- [SharePoint Dev Center](https://developer.microsoft.com/sharepoint) -- [SharePoint Code Samples](https://developer.microsoft.com/SharePoint/gallery?filterBy=SharePoint,Samples) -- [Microsoft SharePoint Team Blog](https://developer.microsoft.com/en-us/office/blogs/) +- [SharePoint development](/sharepoint/dev/) +- [How-tos for SharePoint](how-tos-for-sharepoint.md) +- [SharePoint Dev Center](https://developer.microsoft.com/sharepoint) +- [SharePoint Code Samples](https://developer.microsoft.com/SharePoint/gallery?filterBy=SharePoint,Samples) +- [Microsoft SharePoint Team Blog](https://developer.microsoft.com/office/blogs/) diff --git a/docs/general-development/color-palettes-and-fonts-in-sharepoint.md b/docs/general-development/color-palettes-and-fonts-in-sharepoint.md index b35577862..8d613a05d 100644 --- a/docs/general-development/color-palettes-and-fonts-in-sharepoint.md +++ b/docs/general-development/color-palettes-and-fonts-in-sharepoint.md @@ -1,28 +1,30 @@ --- title: Color palettes and fonts in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Use this reference to define the color palette or font scheme that is used in a SharePoint site. +ms.date: 06/09/2022 ms.assetid: c17d375b-151f-48ae-ac32-f2ce9e68d63f -localization_priority: Priority +ms.localizationpriority: high --- - - # Color palettes and fonts in SharePoint + Use this reference to define the color palette or font scheme that is used in a SharePoint site. + +[!IMPORTANT] This extensibility option is only available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. + ## Color palettes A color palette is the combination of colors that are used in a SharePoint site. The color palette for a SharePoint site is defined in a color palette file. Color slots are also used by the master page preview file to generate thumbnail and preview images of a site. The following describes the structure of the color palette file and the master page preview file: - - - + + + - **Color palette file (.spcolor)** - + Color palette files are used in the **Change the look** wizard, which enables users to change the look and feel of their site by using the SharePoint themes user interface. By default, 32 color palette files are installed with SharePoint. You can also create additional color palette files. The following example shows the format of a color palette file. - -```xml + +```xml @@ -31,71 +33,64 @@ A color palette is the combination of colors that are used in a SharePoint site. In a color palette file, the following placeholders are replaced: - + - _InvertedSetting_ is a Boolean value. **true** if the color palette is generally light text on a dark background. **false** if the color palette is generally dark text on a light background. - - + + - _Slot1_ is the annotation name of the color slot to use as the first block of the palette icon in the color palette picker of the theming experience. - - + + - _Slot2_ is the annotation name of the color slot to use as the second block of the palette icon in the color palette picker of the theming experience. - - + + - _Slot3_ is the annotation name of the color slot to use as the third block of the palette icon in the color palette picker of the theming experience. - - + + - _ColorSlot_ is the annotation name of the color slot that you are defining (for example, SiteTitle). - - + + - _Color_ is the hexadecimal value of the color to use for the specified color slot. This may be in 6 digits (RRGGBB) or 8 digits (AARRGGBB). If the hexadecimal value is 8 digits, the first two digits represent the opacity level (00-FF, which maps to 0-255). If the hexadecimal value is 6 digits, the default opacity is 100% or FF. - - + + The color palette files are located in the Theme Gallery of the root site, in the site collection in the **15** folder (http:// _SiteCollectionName_/_catalogs/theme/15/). To access the Theme Gallery from the SharePoint user interface, on the **Site Settings** page, under **Web Designer Galleries**, select **Themes**, and then select **15**. - - + + - **Master page preview file (.preview)** - + Master page preview files are used to generate thumbnail images and preview images when you use the **Change the look** wizard. A master page must have a corresponding preview file to be used in the **Change the look** wizard. A preview file is a specially formatted file that has sections for the default color palette, default font scheme, tokenized CSS, and tokenized HTML. It uses string tokens to get the value of color slots, font names, and localized UI strings. The following example shows color slots being used in the master page preview file. - + ```HTML - + [ID] #dgp-pageContainer { background-color: [T_THEME_COLOR_PAGEBACKGROUND]; color: [T_THEME_COLOR_BODYTEXT]; width: 100%; - height:100%; - background-image: url('[T_IMAGE]'); + height:100%; + background-image: url('[T_IMAGE]'); background-size: cover; - font-family: [T_BODY_FONT]; + font-family: [T_BODY_FONT]; } ``` For more information, see [How to: Create a master page preview file in SharePoint](how-to-create-a-master-page-preview-file-in-sharepoint.md) - - -> **Tip:** -> You can use the SharePoint color palette tool to help you create SharePoint designs. You can [download the SharePoint color palette tool](https://www.microsoft.com/download/details.aspx?id=38182) from the Microsoft Download Center. - - - ### Color slot mapping Table 1 describes the color slots that are available and where color slots are used in a SharePoint site. - + > [!NOTE] > When discussing navigation items,pressed applies to when a user clicks or touches a navigation item.Selected applies to when a user is navigated to the page.> The following summarizes a normal flow of actions and the color slot that applies to the navigation item link at each step:> The base text of a navigation item link: HeaderNavigationText> A user hovers the cursor over the navigation item link: HeaderNavigationHoverText> A user clicks, touches, or chooses the navigation item link: HeaderNavigationPressedText> The user is navigated to the chosen page. The color slot that applies to the navigation item for the page the user is now on: HeaderNavigationSelectedText - - - + + + **Table 1. Color slots** @@ -192,19 +187,19 @@ Table 1 describes the color slots that are available and where color slots are u |ContentAccent4
|The fourth accent color that a user can select from the Rich Text Editor color picker.
|[T_THEME_COLOR_CONTENTACCENT4]
| |ContentAccent5
|The fifth accent color that a user can select from the Rich Text Editor color picker.
|[T_THEME_COLOR_CONTENTACCENT5]
| |ContentAccent6
|The sixth accent color that a user can select from the Rich Text Editor color picker.
|[T_THEME_COLOR_CONTENTACCENT6]
| - + ## Font schemes Fonts are defined in the font scheme (.spfont file) and the master page preview (.preview file) for a given SharePoint site. The font scheme defines the fonts that are used in four areas: title, navigation, heading, and body. Seven font schemes are included in SharePoint. You can create additional font schemes. The font scheme files are located in the **15** subfolder of the Theme Gallery of the root site of the site collection (http:// _SiteCollectionName_/_catalogs/theme/15/). To access the Theme Gallery from the SharePoint user interface, on the **Site Settings** page, under **Web Designer Galleries**, select **Themes**, and then select **15**. - - - + + + The following example describes the format for an .spfont file. - - - + + + @@ -225,42 +220,42 @@ The following example describes the format for an .spfont file. ``` In an .spfont file, the following placeholders are replaced: - - - + + + - _FontSchemeName_ is the name of the font scheme. - - + + - _Slot1_ is the name of the font slot that you want to use as the first block of the font icon in the font scheme picker in the **Change the look** wizard. - - + + - _Slot2_ is the name of the font slot that you want to use as the second block of the font icon in the font scheme picker in the **Change the look** wizard. - - + + - _FontSlotName_ is the name of the font slot that you are defining (for example, title). - - + + - _LatinScriptFont_ is the font to use for Latin scripts. This font is also the fallback font. That is, this is the font that is used for a language that does not have a script that is explicitly set in the font scheme. - + > [!NOTE] > You must provide additional information to use web fonts in your font scheme. For more information, see the [Web fonts](#webFont) section in this article. - _EAScriptFont_ is the font to use for East Asia scripts. The **** element is not currently used by SharePoint. But, the **** element is still required in the font scheme. - - + + - _CSFont_ is the font to use for complex scripts. The **** element is not currently used by SharePoint. But, the **** element is still required in the font scheme. - - + + - _Language_ is the language script. - - + + - _ScriptFont_ is the font to use for the specified language script. - - + + The following example shows a portion of an .spfont file. - - - + + + @@ -306,17 +301,17 @@ The following example shows a portion of an .spfont file. ``` SharePoint includes support for web fonts. You must provide additional information to use web fonts in your font scheme. For more information, see the [Web fonts](#webFont) section in this article. - - - + + + ### Web-safe fonts Web-safe fonts are a set of fonts that are widely used and available on most devices by default. To specify a web-safe font in the font scheme, include the name of the font in the **typeface** attribute of the font slot. The following example shows a web-safe font used in a font scheme. - - - + + + ```xml @@ -331,13 +326,13 @@ Web-safe fonts are a set of fonts that are widely used and available on most dev Web fonts are fonts that are available on the Internet. When a user views a site that uses web fonts, the web browser downloads the necessary font files along with the rest of the page. To specify a web font, you must provide the URL to your web font files in four font formats (for support across browsers), and a small and large thumbnail image to use to render the font names in the font scheme picker. - - - + + + The following example describes the information that is required to use a web font in an **** element. - - - + + + @@ -354,41 +349,41 @@ The following example describes the information that is required to use a web fo ``` In this example of using a web font, the following placeholders would be replaced: - - - + + + - _FontName_ is the name of the web font. - - + + - _EotFile_ is the relative URL to the Embedded Open Type font file. - - + + - _WoffFile_ is the relative URL to the Web Open Font Format font file. - - + + - _TtfFile_ is the relative URL to the TrueType font file. - - + + - _SvgFile_ is the relative URL to the Scalable Vector Graphics font file. - - + + - _LargeImgFile_ is the relative URL to the large thumbnail image that you want to use in the font scheme picker. - - + + - _SmallImgFile_ is the relative URL to the small thumbnail image that you want to use in the font scheme picker. - + > [!NOTE] - > The paths to the files have to be the full URL (i.e. https://tenant.sharepoint.com/sites/sitename/_catalogs/theme/15/fontfile.wof) + > The paths to the files have to be the full URL (i.e. `https://tenant.sharepoint.com/sites/sitename/_catalogs/theme/15/fontfile.wof`) > The LargeImgFile and SmallImgFile attributes have to be present in the Latin tag even if given empty values. ### Font slots Table 1 describes the available font slots and where they are used in a page. - - - + + + **Table 1. Font slots** @@ -402,32 +397,32 @@ Table 1 describes the available font slots and where they are used in a page. |small-heading
|Used for H4 headings.
| |large-body
|Used for large body text (15 pixels and 19 pixels).
| |body
|The base font that is used everywhere else on the page.
| - + ## See also - [Themes overview for SharePoint](themes-overview-for-sharepoint.md) - - + + - [How to: Deploy a custom theme in SharePoint](how-to-deploy-a-custom-theme-in-sharepoint.md) - - + + - [Upgrade custom themes and CSS to SharePoint](upgrade-custom-themes-and-css-to-sharepoint.md) - - + + - [How to: Create a master page preview file in SharePoint](how-to-create-a-master-page-preview-file-in-sharepoint.md) - - -- [SharePoint Team Blog: Show off your style with SharePoint theming](https://blogs.office.com/b/sharepoint/archive/2012/10/29/show-off-your-style-with-sharepoint-theming.aspx) - - + + +- [SharePoint Team Blog: Show off your style with SharePoint theming](https://www.microsoft.com/microsoft-365/blog/2012/10/29/show-off-your-style-with-sharepoint-theming) + + - [SharePoint Design Manager branding and design capabilities](sharepoint-design-manager-branding-and-design-capabilities.md) - - - - - + + + + + diff --git a/docs/general-development/common-error-messages-in-sharepoint-workflow-development.md b/docs/general-development/common-error-messages-in-sharepoint-workflow-development.md index 838508f8c..a0766bcf6 100644 --- a/docs/general-development/common-error-messages-in-sharepoint-workflow-development.md +++ b/docs/general-development/common-error-messages-in-sharepoint-workflow-development.md @@ -1,19 +1,23 @@ --- title: Common error messages in SharePoint workflow development +description: A listing of common error messages that you might encounter while developing SharePoint workflows and guidance for solving the underlying problem. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: e9bf6878-c722-4b1f-b5b5-b302ae0ea4da -localization_priority: Priority +ms.localizationpriority: high --- # Common error messages in SharePoint workflow development A listing of common error messages that you might encounter while developing SharePoint workflows and guidance for solving the underlying problem. + +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). + ## Common SharePoint workflow errors Although this list doesn't cover every possible error you may encounter when developing SharePoint workflows, it does cover those that you are most likely to face. - + - [Timeout while waiting for sandboxed code execution request to complete within the worker process](#bkmk_error01) @@ -37,7 +41,7 @@ Although this list doesn't cover every possible error you may encounter when dev - [The e-mail message cannot be sent. Make sure the outgoing e-mail settings for the server are configured correctly](#bkmk_error07) -- [The e-mail message cannot be sent. Email non-delivery reports in Exchange Online](https://docs.microsoft.com/Exchange/mail-flow-best-practices/non-delivery-reports-in-exchange-online/non-delivery-reports-in-exchange-online) +- [The e-mail message cannot be sent. Email non-delivery reports in Exchange Online](/exchange/mail-flow-best-practices/non-delivery-reports-in-exchange-online/non-delivery-reports-in-exchange-online) - [The workflow could not update the item, possibly because one or more columns for the item require a different type of information](#bkmk_error08) @@ -147,7 +151,7 @@ Errors sending e-mail can also happen because of Exchange non-delivery. Review -- [Email non-delivery reports in Exchange Online](https://docs.microsoft.com/Exchange/mail-flow-best-practices/non-delivery-reports-in-exchange-online/non-delivery-reports-in-exchange-online) +- [Email non-delivery reports in Exchange Online](/exchange/mail-flow-best-practices/non-delivery-reports-in-exchange-online/non-delivery-reports-in-exchange-online) ### The workflow could not update the item, possibly because one or more columns for the item require a different type of information diff --git a/docs/general-development/configuration-administration-and-resources-in-sharepoint.md b/docs/general-development/configuration-administration-and-resources-in-sharepoint.md index bae6b0c9b..c35d5e9ad 100644 --- a/docs/general-development/configuration-administration-and-resources-in-sharepoint.md +++ b/docs/general-development/configuration-administration-and-resources-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Configuration, administration, and resources in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Article with links to learn about the configuration, administration and resources in SharePoint. +ms.date: 06/07/2022 ms.assetid: e7d8c919-7aa6-466a-acb0-27366129061c -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/configure-search-in-sharepoint.md b/docs/general-development/configure-search-in-sharepoint.md index 12365e657..08992c761 100644 --- a/docs/general-development/configure-search-in-sharepoint.md +++ b/docs/general-development/configure-search-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Configure search in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article about configuring search in SharePoint. +ms.date: 06/07/2022 ms.assetid: e447127c-2b11-4d65-b46e-01a18cdcdee5 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/content-management-interoperability-services-cmis-in-sharepoint.md b/docs/general-development/content-management-interoperability-services-cmis-in-sharepoint.md index 3035ba961..c3d42c9d5 100644 --- a/docs/general-development/content-management-interoperability-services-cmis-in-sharepoint.md +++ b/docs/general-development/content-management-interoperability-services-cmis-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Content Management Interoperability Services (CMIS) in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about the SharePoint implementation of version 1.0 of the OASIS Content Management Interoperability Services (CMIS) standard. +ms.date: 06/07/2022 ms.assetid: a1def24c-b2db-4bf9-8d2c-02f5628832f8 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/content-search-web-part-in-sharepoint.md b/docs/general-development/content-search-web-part-in-sharepoint.md index c90d8bd9a..3d8aa8b79 100644 --- a/docs/general-development/content-search-web-part-in-sharepoint.md +++ b/docs/general-development/content-search-web-part-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Content Search web part in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about the Content Search web part (CSWP) in SharePoint. +ms.date: 06/07/2022 ms.assetid: 6fb4bf41-0846-4dca-ad9e-906afdfd3d2b -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/create-a-map-view-for-the-geolocation-field-in-sharepoint.md b/docs/general-development/create-a-map-view-for-the-geolocation-field-in-sharepoint.md index e313deb9d..1b6f5da34 100644 --- a/docs/general-development/create-a-map-view-for-the-geolocation-field-in-sharepoint.md +++ b/docs/general-development/create-a-map-view-for-the-geolocation-field-in-sharepoint.md @@ -1,262 +1,146 @@ --- title: Create a map view for the Geolocation field in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to display location information by using a map view in SharePoint lists. +ms.date: 06/09/2022 ms.assetid: 0cd8ba27-3326-4b60-a2d0-d289a94f11bb -localization_priority: Priority +ms.localizationpriority: high --- - # Create a map view for the Geolocation field in SharePoint Learn how to display location information by using a map view in SharePoint lists. You can create a map view manually via the SharePoint user interface (UI) or programmatically by using the new **Geolocation** field type. + SharePoint introduces a new field type named **Geolocation** that enables you to annotate SharePoint lists with location information. For example, you can now make lists "location-aware" and display latitude and longitude coordinates through Bing Maps. An entry is typically seen as a pushpin on a map view. - - - To display a map view in a SharePoint list, you must use the Bing Maps services. The **Geolocation** field is not available when you create a list by using the UI. Instead, this field must be inserted programmatically. For information about how to render and work with this data type programmatically, see [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md). + The **Geolocation** field and the map view enable you to give spatial context to any information by integrating data from SharePoint into a mapping experience in web and mobile apps. This article does not explain how to render the **Geolocation** field or provide developer guidance for creating a location-based mobile application; it does provide instruction for creating map views programmatically and from the SharePoint UI by using Bing Maps. - - - -An MSI package named SQLSysClrTypes.msi must be installed on every SharePoint front-end web server to view the **Geolocation** field value or data in a list. This package installs components that implement the new geometry, geography, and hierarchy ID types in SQL Server 2008. By default, this file is installed for SharePoint Online. However, it is not installed for an on-premises deployment of SharePoint. You must be a member of the Farm Administrators group to perform this operation. To download SQLSysClrTypes.msi, see [Microsoft SQL Server 2008 R2 SP1 Feature Pack](https://www.microsoft.com/download/details.aspx?id=26728) for SQL Server 2008, or [Microsoft SQL Server 2012 Feature Pack](https://www.microsoft.com/download/details.aspx?id=29065) for SQL Server 2012 in the Microsoft Download Center. -## Prerequisites for creating a map view - +An MSI package named SQLSysClrTypes.msi must be installed on every SharePoint front-end web server to view the **Geolocation** field value or data in a list. This package installs components that implement the new geometry, geography, and hierarchy ID types in SQL Server 2008. By default, this file is installed for SharePoint Online. However, it is not installed for an on-premises deployment of SharePoint. You must be a member of the Farm Administrators group to perform this operation. To download SQLSysClrTypes.msi, see [Microsoft SQL Server 2008 R2 SP1 Feature Pack](https://www.microsoft.com/download/details.aspx?id=30437) for SQL Server 2008, or [Microsoft SQL Server 2012 Feature Pack](https://www.microsoft.com/download/details.aspx?id=29065) for SQL Server 2012 in the Microsoft Download Center. +## Prerequisites for creating a map view - Access to a SharePoint list, with sufficient privileges to create a view. - - - A SharePoint list that contains a **Geolocation** column - - - A valid Bing Maps key set at the farm or web level, which can be obtained from the [Bing Maps Account Center](http://www.bingmapsportal.com/) - - > **Important:** - > You are responsible for compliance with terms and conditions applicable to your use of the Bing Maps key, and any necessary disclosures to users of your application regarding data passed to the Bing Maps service. + + > [!IMPORTANT] + > You are responsible for compliance with terms and conditions applicable to your use of the Bing Maps key, and any necessary disclosures to users of your application regarding data passed to the Bing Maps service. + - Visual Studio 2012 or Visual Studio 2010 - - ## What is a map view? - A map view is a SharePoint view that displays a map (with data obtained from the Bing Maps service), using longitude and latitude entries from the **Geolocation** field type. When the **Geolocation** field type is available on the SharePoint list, a map view can be created either programmatically or from the SharePoint UI. In the list, SharePoint displays the location on a map powered by Bing Maps. In addition, a new view type named **Map View** displays the list items as pushpins on a Bing Maps Ajax control V7 with the list items as cards on the left pane. - + > [!NOTE] > Any SharePoint list can have maximum of two **Geolocation** columns in it; you won't be able to add a third **Geolocation** column in the same list. A map view can have only one **Geolocation** column. You can create multiple map views with different **Geolocation** columns. - - - - ## Create a map view from the SharePoint UI - The following steps demonstrate how to create a map view from the SharePoint UI. - - - 1. Open the SharePoint list with **Geolocation** column. - - -2. Choose **Create view** from the ECB (Edit Control Block) menu, as shown in Figure 1. - - **Figure 1.Creating a view from the ECB menu** - - - - ![Edit Control Box menu for SharePoint list](../images/SPCon15_CreateMapView_ECB_Menu__fig1.png) - +1. Choose **Create view** from the ECB (Edit Control Block) menu, as shown in Figure 1. - + ![Edit Control Box menu for SharePoint list](../images/SPCon15_CreateMapView_ECB_Menu__fig1.png) - -3. On the **Choose a view type** page, choose **Map View**, as shown in Figure 2. - - **Figure 2. Choosing a view type** + **Figure 1.Creating a view from the ECB menu** - +1. On the **Choose a view type** page, choose **Map View**, as shown in Figure 2. - ![Choose Map View from the list of view types](../images/SPCon15_CreateMapView_ChooseViewType__fig2.png) - + ![Choose Map View from the list of view types](../images/SPCon15_CreateMapView_ChooseViewType__fig2.png) - + **Figure 2. Choosing a view type** - -4. After you choose a view type, you can select various fields to display in the map view, as shown in Figure 3. - - **Figure 3. Choosing fields for a map view** +1. After you choose a view type, you can select various fields to display in the map view, as shown in Figure 3. - + ![Select fields to appear in the view](../images/SPCon15_CreateMapView_SelectFieldsForView__fig3.png) - ![Select fields to appear in the view](../images/SPCon15_CreateMapView_SelectFieldsForView__fig3.png) - + **Figure 3. Choosing fields for a map view** - > [!NOTE] > At least one **Geolocation** field is required to create a map view. You cannot select multiple **Geolocation** fields for a map view, although you can create two different map views that use two different **Geolocation** fields. -5. After you add the required **Geolocation** field and any other field you need, choose **OK**. A map view is created, as shown in Figure 4. - - **Figure 4. Completed map view** - - - ![Completed map view](../images/SPCon15_CreateMapView_MyMapView__fig4.png) - +1. After you add the required **Geolocation** field and any other field you need, choose **OK**. A map view is created, as shown in Figure 4. - + ![Completed map view](../images/SPCon15_CreateMapView_MyMapView__fig4.png) - + **Figure 4. Completed map view** ## Create a map view programmatically - Follow these steps to create a map view for a SharePoint list programmatically. - - - 1. Start Visual Studio. - - -2. On the menu bar, choose **File, New Project**. The **New Project** dialog box opens. - - -3. In the **New Project** dialog box, choose **C#** in the **Installed Templates** box, and then choose the **Console Application** template. - - -4. Give the project a name, and then choose the **OK** button. - - -5. Visual Studio creates the project. Add a reference to the following assemblies, and choose **OK**. - - - Microsoft.SharePoint.Client.dll - - - - Microsoft.SharePoint.Client.Runtime.dll - - -6. In the default .cs file, add a **using** directive as follows. - - `using Microsoft.SharePoint.Client;` - - -7. Add the following code to the **Main** method in the .cs file. - +1. On the menu bar, choose **File, New Project**. The **New Project** dialog box opens. +1. In the **New Project** dialog box, choose **C#** in the **Installed Templates** box, and then choose the **Console Application** template. +1. Give the project a name, and then choose the **OK** button. +1. Visual Studio creates the project. Add a reference to the following assemblies, and choose **OK**. + + - Microsoft.SharePoint.Client.dll + - Microsoft.SharePoint.Client.Runtime.dll + +1. In the default .cs file, add a **using** directive as follows. + + ```csharp + using Microsoft.SharePoint.Client; + ``` + +1. Add the following code to the **Main** method in the .cs file. + > [!NOTE] - > The JSLink property is not supported on Survey or Events lists. A SharePoint calendar is an Events list. + > The JSLink property is not supported on Survey or Events lists. A SharePoint calendar is an Events list. -```cs - -class Program + ```csharp + class Program { - static void Main(string[] args) - { - CreateMapView (); - Console.WriteLine("A map view is created successfully"); - } - private static void CreateMapView() - { - // Replace and with valid values. - ClientContext context = new ClientContext(""); - List oList = context.Web.Lists.GetByTitle(""); - ViewCreationInformation viewCreationinfo = new ViewCreationInformation(); - // Replace with the name you want for your map view. - viewCreationinfo.Title = ""; - viewCreationinfo.ViewTypeKind = ViewType.Html; - View oView = oList.Views.Add(viewCreationinfo); - oView.JSLink = "mapviewtemplate.js"; - oView.Update(); - context.ExecuteQuery(); - } + static void Main(string[] args) + { + CreateMapView (); + Console.WriteLine("A map view is created successfully"); + } + private static void CreateMapView() + { + // Replace and with valid values. + ClientContext context = new ClientContext(""); + List oList = context.Web.Lists.GetByTitle(""); + ViewCreationInformation viewCreationinfo = new ViewCreationInformation(); + // Replace with the name you want for your map view. + viewCreationinfo.Title = ""; + viewCreationinfo.ViewTypeKind = ViewType.Html; + View oView = oList.Views.Add(viewCreationinfo); + oView.JSLink = "mapviewtemplate.js"; + oView.Update(); + context.ExecuteQuery(); + } } -``` - -8. Replace __ and __ with valid values. - - -9. Navigate to the list. You should be able to see a newly created view that has the name you specified in the preceding code. + ``` - +1. Replace `` and `` with valid values. +1. Navigate to the list. You should be able to see a newly created view that has the name you specified in the preceding code. ## Understand color-coded pushpins in a map view - -A map view providesthree colors of pushpins (as shown in Figure 5), each of which provides a difference user experience. A pushpin on the map has the same color as the pushpin of the matching item in the left pane. - - - +A map view provides three colors of pushpins (as shown in Figure 5), each of which provides a difference user experience. A pushpin on the map has the same color as the pushpin of the matching item in the left pane. - **Orange** Indicates that the **Geolocation** field for the item is mapped with the Bing Maps services. - - - **Grey** Indicates that the **Geolocation** field for the item is empty. The item cannot be mapped with Bing Maps services, so no pushpin for this item appears on the map. - - - **Blue** When a user hovers over a list item, the pushpin color changes from orange to blue. Both the pushpin in the left pane and the matching pushpin on the map change color - - - -**Figure 5. A map view with different pushpin colors** - - - - - - - ![Different colors of pushpins in a map view](../images/SPCon15_CreateMapView_DifferentPushPinsOnMapView__fig5.png) - - - -After you create a map view, all items appear as pushpins. The user can get more information about an item by hovering over a pushpin, as shown in Figure 6. - - - -**Figure 6. User experience of pushpins in a map view** +**Figure 5. A map view with different pushpin colors** - - - +After you create a map view, all items appear as pushpins. The user can get more information about an item by hovering over a pushpin, as shown in Figure 6. - - - ![User experience of pusphins on a map view](../images/SPCon15_CreateMapView_PushPinsOnMapView__fig6.png) - - - - - - - - - - +**Figure 6. User experience of pushpins in a map view** ## See also - - - -- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) - - -- [How to: Add a Geolocation column to a list programmatically in SharePoint](how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md) - - -- [How to: Set the Bing Maps key at the web and farm level in SharePoint](how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md) - - -- [How to: Integrate maps with Windows Phone apps and SharePoint lists](how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md) - - -- [Use the SharePoint location field type in mobile applications](https://technet.microsoft.com/library/fp161355%28v=office.15%29.aspx) - - +- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) +- [How to: Add a Geolocation column to a list programmatically in SharePoint](how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md) +- [How to: Set the Bing Maps key at the web and farm level in SharePoint](how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md) +- [How to: Integrate maps with Windows Phone apps and SharePoint lists](how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md) +- [Use the SharePoint location field type in mobile applications](https://technet.microsoft.com/library/fp161355%28v=office.15%29.aspx) diff --git a/docs/general-development/create-a-sharepoint-workflow-app-using-visual-studio-2012.md b/docs/general-development/create-a-sharepoint-workflow-app-using-visual-studio-2012.md index 438a70eb3..6e650bcf0 100644 --- a/docs/general-development/create-a-sharepoint-workflow-app-using-visual-studio-2012.md +++ b/docs/general-development/create-a-sharepoint-workflow-app-using-visual-studio-2012.md @@ -1,559 +1,270 @@ --- title: Create a SharePoint workflow app using Visual Studio 2012 -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Walk through the process of creating a workflow SharePoint Add-in using Microsoft Visual Studio 2012. +ms.date: 12/22/2020 ms.assetid: 7923d60d-84b9-44d6-8185-e5236efaf502 -localization_priority: Priority +ms.localizationpriority: high --- - - # Create a SharePoint workflow app using Visual Studio 2012 + Walk through the process of creating a workflow SharePoint Add-in using Microsoft Visual Studio 2012. + +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). + ## Prerequisites - This development scenario presumes that a SharePoint farm and a Workflow Manager 1.0 farm are installed and paired. These two farms can be located on the same or on separate server computers. The scenario further presumes that workflow development is taking place remotely - that is, on a computer separate from either of the server computers - and is using Microsoft Visual Studio 2012 or later. - - - - On the server platforms: - - Windows Server 2008 R2. - - - Microsoft SharePoint - - - Workflow Manager 1.0 - - - On the development platform: - - Microsoft Visual Studio 2012 or later. - - - Office Developer Tools for Visual Studio 2013. - + > [!NOTE] - > Office Developer Tools for Visual Studio 2013 is only required when using Visual Studio 2012. Later versions of Visual Studio include the Office Developer Tools. + > Office Developer Tools for Visual Studio 2013 is only required when using Visual Studio 2012. Later versions of Visual Studio include the Office Developer Tools. + For assistance setting up and configuring your SharePoint workflow development environment, see the following: - - - - -- [Prepare to set up and configure a SharePoint workflow development environment](prepare-to-set-up-and-configure-a-sharepoint-workflow-development-environment.md) - - -- [Configure workflow in SharePoint](https://technet.microsoft.com/library/jj658586%28v=office.15%29) - - -- [Video series: Install and configure Workflow in SharePoint](https://technet.microsoft.com/library/dn201724%28v=office.15%29) - - + +- [Prepare to set up and configure a SharePoint workflow development environment](prepare-to-set-up-and-configure-a-sharepoint-workflow-development-environment.md) +- [Configure workflow in SharePoint](https://technet.microsoft.com/library/jj658586%28v=office.15%29) +- [Video series: Install and configure Workflow in SharePoint](https://technet.microsoft.com/library/dn201724%28v=office.15%29) ## Get started - A common workflow scenario in business settings is the document review and approval process. In this walkthrough, we create an SharePoint Add-in that automates the routing, notifications, and approval (or rejection) of a document using a SharePoint workflow. We create this workflow using the SharePoint workflow designer in Microsoft Visual Studio 2012. - - - -Here's a flowchart that depicts the course of the workflow we're going to create. - - - - -**Figure 1. Flowchart depicting the document approval workflow.** - - - - - - - - + +Here's a flowchart that shows the course of the workflow we're going to create. + +**Figure 1. Flowchart showing the document approval workflow.** + ![Flowchart depicting the document approval workflow](../images/ngGK_Flowchart.png) - - - -In summary, the workflow does the following: - - - - - - - + +In summary, the workflow does the following: 1. A document change event associated with a specific document library launches the workflow instance. - - -2. If the document's status is set to "Ready For Review," the workflow assigns a task to a prearranged reviewer, then sends the reviewer an email notification about the task. - - -3. If the reviewer fails to approve the document, the document file remains in the Draft Documents library; however, the document status is set to "Rejected." - - -4. If the reviewer approves the document, the workflow copies the document into a Published Documents library. The original file remains in the Draft Documents library, but its status is set to "Published." - - - - -> **Important:** -> Before you start this walkthrough, ensure that you have a properly installed and configured workflow development environment. For more information, see [Prepare to set up and configure a SharePoint workflow development environment](prepare-to-set-up-and-configure-a-sharepoint-workflow-development-environment.md). Also, ensure that you have a SharePoint instance that you can develop your workflow against. For more information, see [Install SharePoint](https://technet.microsoft.com/library/cc303424.aspx). - - - +1. If the document's status is set to "Ready For Review," the workflow assigns a task to a prearranged reviewer, then sends the reviewer an email notification about the task. +1. If the reviewer fails to approve the document, the document file remains in the Draft Documents library; however, the document status is set to "Rejected." +1. If the reviewer approves the document, the workflow copies the document into a Published Documents library. The original file remains in the Draft Documents library, but its status is set to "Published." +> [!IMPORTANT] +> Before you start this walkthrough, ensure that you have a properly installed and configured workflow development environment. For more information, see [Prepare to set up and configure a SharePoint workflow development environment](prepare-to-set-up-and-configure-a-sharepoint-workflow-development-environment.md). Also, ensure that you have a SharePoint instance that you can develop your workflow against. For more information, see [Install SharePoint](https://technet.microsoft.com/library/cc303424.aspx). ## Prepare your environment - The first step is preparing our SharePoint site with document libraries that our workflow will use. - - - -1. Launch Visual Studio 2012 and create a new project using the **App for SharePoint** template, as depicted in Figure 2. - +1. Launch Visual Studio 2012 and create a new project using the **App for SharePoint** template, as shown in Figure 2. + > [!NOTE] - > In this walkthrough, the solution file is named "DocApprovalWorkflow1". It is recommended that you use the same name. However, if you name your solution differently, be sure that you make necessary adjustments in the instructions that follow. + > In this walkthrough, the solution file is named "DocApprovalWorkflow1". It is recommended that you use the same name. However, if you name your solution differently, be sure that you make necessary adjustments in the instructions that follow. **Figure 2. Create new project in Visual Studio 2012** - + ![New project dialog in Visual Studio 2012](../images/ngGK_Fig02.png) - ![New project dialog in Visual Studio 2012](../images/ngGK_Fig02.png) - +1. On your associated SharePoint site, create two new document libraries by doing the following: - + - In **Solution Explorer**, right-click on the "DocApprovalWorkflow1" icon and select **Add** > **New Item** and then select **List**. + - In the resulting **SharePoint Customization Wizard**, enter "Draft Documents" in the name field; then select "Document Library" in the drop-down under the first radio button, as shown in Figure 3. + - Click **Next**, then take default settings, and then click **Finish**. - -2. On your associated SharePoint site, create two new document libraries by doing the following: - - - In **Solution Explorer**, right-click on the "DocApprovalWorkflow1" icon and select **Add** > **New Item** and then select **List**. - - - - In the resulting **SharePoint Customization Wizard**, enter "Draft Documents" in the name field; then select "Document Library" in the drop-down under the first radio button, as depicted in Figure 3. - - - - Click **Next**, then take default settings, and then click **Finish**. - **Figure 3. SharePoint customization wizard for List settings.** - - - ![Create new document library wizard](../images/ngGK_Fig03.png) - - - - - -3. Create the second document library using the same steps as above, except name this second library "Published Documents". - - -4. Add two custom columns to **both** of the new document libraries that you just created: - - - Create a custom column named "Approver" and make it a **Person or Group** list column type. - - - - Create a custom column named "Document Status" and make it a **Choice** list column type (see Figure 4). - - -5. On the **Document Status** column, add five choices by expanding the **Type** property in the property grid, then clicking the ellipsis button ( **…**) on the **Items** property. Enter the choice values in the dialog box that appears, as shown in Figure 4. - - - Draft in Progress - - - - Ready for Review - - - - Approved for Publishing - - - - Rejected - - - - Published - - - - - - - - ![Set custom column properties](../images/ngGK_Fig04.png) - - - - - + ![Create new document library wizard](../images/ngGK_Fig03.png) + +1. Create the second document library using the same steps as above, except name this second library "Published Documents". +1. Add two custom columns to **both** of the new document libraries that you created: + - Create a custom column named "Approver" and make it a **Person or Group** list column type. + - Create a custom column named "Document Status" and make it a **Choice** list column type (see Figure 4). +1. On the **Document Status** column, add five choices by expanding the **Type** property in the property grid, then clicking the ellipsis button (**…**) on the **Items** property. Enter the choice values in the dialog box that appears, as shown in Figure 4. + - Draft in Progress + - Ready for Review + - Approved for Publishing + - Rejected + - Published + + ![Set custom column properties](../images/ngGK_Fig04.png) ## Create the basic workflow - Now we're ready to create the workflow itself. - - - 1. In Visual Studio, create a new workflow by right-clicking on the **DocApprovalWorkflow1** icon (in **Solution Explorer**) and selecting **Add** > **New Item**, and then selecting **Workflow** (see Figure 5). - - **Figure 5. Add New Item > Workflow wizard.** - + **Figure 5. Add New Item > Workflow wizard.** - ![Add new workflow item](../images/ngGK_Fig05.png) - + ![Add new workflow item](../images/ngGK_Fig05.png) - +1. When prompted, name the workflow "DocumentApprovalWorkflow" and select **List Workflow** as the workflow type (see Figure 6). - -2. When prompted, name the workflow "DocumentApprovalWorkflow" and select **List Workflow** as the workflow type (see Figure 6). - - **Figure 6. Specify workflow name and type.** + **Figure 6. Specify workflow name and type.** - + ![Specify workflow name and type](../images/ngGK_Fig06.png) - ![Specify workflow name and type](../images/ngGK_Fig06.png) - +1. In the **SharePoint Customization Wizard**, associate the new workflow with the Draft Document library; then, opt to create a new history list and a new workflow task list, as shown in Figure 7. Then click **Next**. - + **Figure 7. Completing the SharePoint Customization Wizard for the new workflow.** - -3. In the **SharePoint Customization Wizard**, associate the new workflow with the Draft Document library; then, opt to create a new history list and a new workflow task list, as shown in Figure 7. Then click **Next**. - - **Figure 7. Completing the SharePoint Customization Wizard for the new workflow.** + ![Completing the SharePint Customization Wizard](../images/ngGK_Fig07.png) - +1. Set the workflow to start automatically when an item in the Draft Documents library is changed. You can also leave the check box for manually starting the workflow selected; this allows you to easily test the workflow without needing to change a document. See Figure 8. - ![Completing the SharePint Customization Wizard](../images/ngGK_Fig07.png) - + **Figure 8. Set the activation parameters for the workflow.** - + ![Set activation parameters for the workflow](../images/ngGK_Fig08.png) - -4. Set the workflow to start automatically when an item in the Draft Documents library is changed. You can also leave the check box for manually starting the workflow selected; this allows you to easily test the workflow without needing to change a document. See Figure 8. - - **Figure 8. Set the activation parameters for the workflow.** - - - - ![Set activation parameters for the workflow](../images/ngGK_Fig08.png) - - - > [!NOTE] - > You can change the workflow association type after the workflow has been created by using the property grid with the workflow selected in **Solution Explorer** (see Figure 9). Then click **Finish**. - - **Figure 9. The workflow property grid.** + > You can change the workflow association type after the workflow has been created by using the property grid with the workflow selected in **Solution Explorer** (see Figure 9). Then click **Finish**. - + **Figure 9. The workflow property grid.** - ![Workflow property grid](../images/ngGK_Fig09.png) - + ![Workflow property grid](../images/ngGK_Fig09.png) - - - -5. Finally, configure your SharePoint Server to manage outgoing email using the SMTP service. For instructions, see [Configure outgoing email for a SharePoint farm](https://technet.microsoft.com/library/cc263462.aspx). This is necessary to allow the workflow to send email notifications related to workflow tasks. - - +1. Finally, configure your SharePoint Server to manage outgoing email using the SMTP service. For instructions, see [Configure outgoing email for a SharePoint farm](https://technet.microsoft.com/library/cc263462.aspx). This is necessary to allow the workflow to send email notifications related to workflow tasks. ## Implement the workflow logic - Now that we have our SharePoint Server set up and our basic workflow created, we can now design the workflow logic. - - - - -1. Open the workflow designer by double-clicking on the workflow project item in **Solution Explorer**. You will see the workflow designer surface (and the workflow toolbox); the designer is populated with an initial workflow stage named **Sequence**. - - -2. Our first step is to grab the **LookupSPListItem** activity from the toolbox (see Figure 10) and drop it in the **Sequence** stage on the designer surface. We use this activity to get the status of the document at any given time, which the **LookupSPListItem** activity returns as a [DynamicValue](https://msdn.microsoft.com/library/windowsazure/microsoft.activities.dynamicvalue%28v=azure.10%29.aspx) object that contains a set of SharePoint list item properties as key-value pairs. - - **Figure 10. LookupSPListItem activity selector.** - - - ![LookupSPListItem activity selector](../images/ngGK_Fig10.png) - +1. Open the workflow designer by double-clicking on the workflow project item in **Solution Explorer**. You'll see the workflow designer surface (and the workflow toolbox); the designer is populated with an initial workflow stage named **Sequence**. +1. Our first step is to grab the **LookupSPListItem** activity from the toolbox (see Figure 10) and drop it in the **Sequence** stage on the designer surface. We use this activity to get the status of the document at any given time, which the **LookupSPListItem** activity returns as a [DynamicValue](https://msdn.microsoft.com/library/windowsazure/microsoft.activities.dynamicvalue%28v=azure.10%29.aspx) object that contains a set of SharePoint list item properties as key-value pairs. - + **Figure 10. LookupSPListItem activity selector.** + ![LookupSPListItem activity selector](../images/ngGK_Fig10.png) 1. To configure the **LookupSPListItem** activity, first click on it in the designer to select it. This activates the property grid for the activity. - - -2. Use the combo boxes in the property grid to configure the **LookupSPListItem** activity to use "current item" for **ItemId** and "current list" as **ListId**, as shown in Figure 11. - - **Figure 11. Configuring LookupSPListItem properties.** +1. Use the combo boxes in the property grid to configure the **LookupSPListItem** activity to use "current item" for **ItemId** and "current list" as **ListId**, as shown in Figure 11. - + **Figure 11. Configuring LookupSPListItem properties.** - ![Setting properties for LookupSPListItem](../images/ngGK_Fig11.png) - + ![Setting properties for LookupSPListItem](../images/ngGK_Fig11.png) - +1. On the **LookupSPListItem** activity tile, click the **Get Properties** link. This completes two important steps for you: - -3. On the **LookupSPListItem** activity tile, click the **Get Properties** link. This completes two important steps for you: - -1. First, it creates a variable of type **DynamicValue** and binds it to the out-argument (named _Result_) of the of the **LookupSPListItem** activity. Properties of the list item are stored in this variable. - - -2. Second, it adds a new activity named **GetDynamicValueProperties** (see Figure 12) and sets the newly created **DynamicValue** variable as the in-argument of this new activity. This activity lets you extract the list item properties from the **DynamicValue** variable. - - -4. On the **GetDynamicValueProperties** activity, click on *Define…* to open a dialog box that lets you pick the properties you wish to extract. In selecting properties, refer to Figure 12, which shows a portion of the designer surface merged with the open **Properties** dialog box. - - **Figure 12. Selecting the DynamicValue properties that you wish to extract.** + 1. First, it creates a variable of type **DynamicValue** and binds it to the out-argument (named _Result_) of the **LookupSPListItem** activity. Properties of the list item are stored in this variable. + 1. Second, it adds a new activity named **GetDynamicValueProperties** (see Figure 12) and sets the newly created **DynamicValue** variable as the in-argument of this new activity. This activity lets you extract the list item properties from the **DynamicValue** variable. - +1. On the **GetDynamicValueProperties** activity, click on *Define…* to open a dialog box that lets you pick the properties you wish to extract. In selecting properties, refer to Figure 12, which shows a portion of the designer surface merged with the open **Properties** dialog box. - ![Setting property values to extract](../images/ngGK_Fig12.png) - + **Figure 12. Selecting the DynamicValue properties that you wish to extract.** - + ![Setting property values to extract](../images/ngGK_Fig12.png) 1. For **Entity Type**, select **List Item of Draft Documents**. - - -2. In the data grid, in the **Path** column, click *Create Property* to open a combo box that contains available properties for list items in the Draft Documents library. Select **Document Status** from the combo box. - - -3. On the next row in the data grid, click *Create Property* again; this time, select **Approver** from the combo box. - - -4. Now click the **Populate Variables** link on the dialog box. This creates a variable of the appropriate data type for each row and assigns it in the **Assign To** column of the data grid, as shown in Figure 13. - - **Figure 13. Get Document Status and Approver properties.** - - - - ![Get document status and approver properties](../images/ngGK_Fig13.png) - - - - - -5. We now have the list item values that we need. Next step is to set up the workflow to check whether the document is "ready for review" and to take the appropriate action when it is. - -1. From the toolbox, drag the **If** activity onto the workflow designer surface. (You'll find the **If** activity in the **Control Flow** section of the toolbox.) - - -2. Set the **If** condition to `DocumentStatus.Equals("Ready for Review")`, as shown in Figure 14. - - **Figure 14. Creating an If/Then clause to trigger a task.** +1. In the data grid, in the **Path** column, click *Create Property* to open a combo box that contains available properties for list items in the Draft Documents library. Select **Document Status** from the combo box. +1. On the next row in the data grid, click *Create Property* again; this time, select **Approver** from the combo box. +1. Now click the **Populate Variables** link on the dialog box. This creates a variable of the appropriate data type for each row and assigns it in the **Assign To** column of the data grid, as shown in Figure 13. + + **Figure 13. Get Document Status and Approver properties.** - + ![Get document status and approver properties](../images/ngGK_Fig13.png) - ![Creating an If/Then clause to trigger a task](../images/ngGK_Fig14.png) - +1. We now have the list item values that we need. Next step is to set up the workflow to check whether the document is "ready for review" and to take the appropriate action when it is. +1. From the toolbox, drag the **If** activity onto the workflow designer surface. (You'll find the **If** activity in the **Control Flow** section of the toolbox.) +1. Set the **If** condition to `DocumentStatus.Equals("Ready for Review")`, as shown in Figure 14. - + **Figure 14. Creating an If/Then clause to trigger a task.** - -3. Next, from the **SP - Task** section of the toolbox, drag a **SingleTask** activity and drop it in the **Then** box of your **If** activity. In effect, you have configured the workflow such that **If** the document is ready for review, **Then** it will then complete this task. - - -6. Our next step is to configure the task that we just created using the configuration dialog box, shown in Figure 15. - - **Figure 15. Task configuration dialog box.** + ![Creating an If/Then clause to trigger a task](../images/ngGK_Fig14.png) - +1. Next, from the **SP - Task** section of the toolbox, drag a **SingleTask** activity and drop it in the **Then** box of your **If** activity. In effect, you've configured the workflow such that **If** the document is ready for review, **Then** it will then complete this task. +1. Our next step is to configure the task that we just created using the configuration dialog box, shown in Figure 15. - ![Task configuration dialog box](../images/ngGK_Fig15.png) - + **Figure 15. Task configuration dialog box.** - + ![Task configuration dialog box](../images/ngGK_Fig15.png) 1. First, we assign the task to an approver. To do this, click the **Configure** link in the **SingleTask** activity tile. - - -2. Set the **Assigned to:** field to "Approver". - - -3. Notice that the **Task title:** field is automatically populated with "Workflow task". - - -4. In the **Body:** field, enter a simple message with instructions for the approver, such as "Please review this document for approval to publish." - - -5. Click **OK** to save. - - +1. Set the **Assigned to:** field to "Approver". +1. Notice that the **Task title:** field is automatically populated with "Workflow task". +1. In the **Body:** field, enter a message with instructions for the approver, such as "Please review this document for approval to publish." +1. Click **OK** to save. Notice that at this point you have a validation error on the **SingleTask** activity. With the **SingleTask** tile selected, look at the **AssignedTo** property in the property grid and note that it has an error icon. Hover over the property name to see a tooltip that describes the problem. We see that the **AssignedTo** property expects a **String** value; however, the **Approver** variable is of **Int32** data type. - + To correct this error, cast the variable to a **String** data type by appending ".ToString()" to "Approver" in the **AssignedTo** row on the property grid, as shown in Figure 16. - - **Figure 16. Casting the "Approver" variable to string data type in the property grid.** + **Figure 16. Casting the "Approver" variable to string data type in the property grid.** + + ![Cast the "Approver" variable to string data type](../images/ngGK_Fig16.png) - + At the present point in this walkthrough, you have created and configured a workflow task that does two things: It sets a document to be reviewed, but also sends an email to the task assignee (the "Approver" in this case) notifying him or her that a task has been assigned and is waiting for actions. - ![Cast the "Approver" variable to string data type](../images/ngGK_Fig16.png) - +1. Let's look at the property grid for the **SingleTask** activity. Scroll to the bottom of the property grid and note in the **Output** section there are two properties, **Outcome** and **TaskItemId**, which are out-arguments. - At the present point in this walkthrough you have created and configured a workflow task that does two things: It sets a document to be reviewed, but also sends an email to the task assignee (the "Approver" in this case) notifying him or her that a task has been assigned and is waiting for actions. - - -7. Let's look at the property grid for the **SingleTask** activity. Scroll to the bottom of the property grid and note in the **Output** section there are two properties, **Outcome** and **TaskItemId**, which are out-arguments. - Note the name of the **Outcome** variable: _outcome_0_ (or similar). We use this variable to check the outcome of the task - that is, whether the approver has approved or rejected the document. - + > [!NOTE] > The **Outcome** out-argument returns an **Int32** value corresponding to the index of the outcome - that is, **0** for "Approved" and **1** for "Rejected". These integers are the default values provided in the out-of-the-box SharePoint site column named "Task Outcome." -8. Now, in order for the workflow to check the outcome of the task, we need to add another **If** activity and place it following the **SingleTask** activity, but inside the **Then** area, as shown in Figure 17. Setting the **If** condition to " `outcome_0 == 0`" tells us whether the document was approved. - - **Figure 17. Adding the IF activity to check the task status.** - +1. Now, in order for the workflow to check the outcome of the task, we need to add another **If** activity and place it following the **SingleTask** activity, but inside the **Then** area, as shown in Figure 17. Setting the **If** condition to " `outcome_0 == 0`" tells us whether the document was approved. - ![Using IF activity to check the task status](../images/ngGK_Fig17.png) - + **Figure 17. Adding the IF activity to check the task status.** - + ![Using IF activity to check the task status](../images/ngGK_Fig17.png) - -9. If the approver has set the task to "Approved," we update the document status to "Approved for Publishing," then copy the document file to the Published Documents library. Alternatively, if the approver has rejected the document, we need to set the document status to "Rejected." - +1. If the approver has set the task to "Approved," we update the document status to "Approved for Publishing," then copy the document file to the Published Documents library. Instead, if the approver has rejected the document, we need to set the document status to "Rejected." 1. In this new **If** activity, drag an **UpdateListItem** activity into the **Then** box. - - -2. Configure the **UpdateListItem** activity in its property grid such that **ItemId** is set to "(current item)" and **ListId** is set to "(current list)", as shown in Figure 18. - - -3. Next, with the **UpdateListItem** activity selected, click the ellipsis button ( **…**) adjacent to the **ListItemPropertiesDynamicValue** field in the property grid. This action opens a dialog box that allows you to specify which list item properties you want to update. - - **Figure 18. Setting the list item properties to update.** - - +1. Configure the **UpdateListItem** activity in its property grid such that **ItemId** is set to "(current item)" and **ListId** is set to "(current list)", as shown in Figure 18. +1. Next, with the **UpdateListItem** activity selected, click the ellipsis button (**…**) next to the **ListItemPropertiesDynamicValue** field in the property grid. This action opens a dialog box that allows you to specify which list item properties you want to update. - ![Specifying list item properties to update](../images/ngGK_Fig18.png) - + **Figure 18. Setting the list item properties to update.** - + ![Specifying list item properties to update](../images/ngGK_Fig18.png) - -4. In the dialog box, first use the combo box to set **Entity Type** to **List Item of Draft Documents** (shown in Figure 18). Then, in the data grid, click **Create Property** and from the drop-down list select "Document Status." Then, under the **Value** column, type "Approved for Publication" (including quotation marks) and click **OK**. - - -10. In the **Then** area of the current **If** activity, drag a **CopyItem** activity and place it directly below the **UpdateListItem** activity, as shown in Figure 19. - - **Figure 19. Adding a CopyItem activity to the workflow.** +1. In the dialog box, first use the combo box to set **Entity Type** to **List Item of Draft Documents** (shown in Figure 18). Then, in the data grid, click **Create Property** and from the drop-down list select "Document Status." Then, under the **Value** column, type "Approved for Publication" (including quotation marks) and click **OK**. +1. In the **Then** area of the current **If** activity, drag a **CopyItem** activity and place it directly below the **UpdateListItem** activity, as shown in Figure 19. - + **Figure 19. Adding a CopyItem activity to the workflow.** - ![Adding a CopyItem activity to the workflow](../images/ngGK_Fig19.png) - + ![Adding a CopyItem activity to the workflow](../images/ngGK_Fig19.png) - Then, configure properties of the **CopyItem** activity in the property grid as depicted in Figure 20. Property values are highlighted. - + Then, configure properties of the **CopyItem** activity in the property grid as shown in Figure 20. Property values are highlighted. - **Figure 20. Configuring the CopyItem activity.** - + **Figure 20. Configuring the CopyItem activity.** - ![Configuring properties of the CopyItem activity](../images/ngGK_Fig20.png) - + ![Configuring properties of the CopyItem activity](../images/ngGK_Fig20.png) - > [!NOTE] - > For the purpose of this walkthrough we are going to assume that all of our published documents come out of the Draft Documents library; therefore, we do not need to worry about controlling for duplicate file names. -11. Finally, we need to add an activity to handle the case where the reviewer rejects the document. We do this by adding an **UpdateListItem** activity to the **Else** area of our current **If** activity. Configure this **UpdateListItem** activity just as you did the prior one in step 9(c), except that now we want to set the document status to "Rejected," as shown in Figure 21. - - **Figure 21. Configuring properties of UpdateListItem activity for rejected documents.** + > For the purpose of this walkthrough we are going to assume that all of our published documents come out of the Draft Documents library; therefore, we do not need to worry about controlling for duplicate file names. - +1. Finally, we need to add an activity to handle the case where the reviewer rejects the document. We do this by adding an **UpdateListItem** activity to the **Else** area of our current **If** activity. Configure this **UpdateListItem** activity just as you did the prior one in step 9(c), except that now we want to set the document status to "Rejected," as shown in Figure 21. - ![Configuring UpdateListItem for rejected documents](../images/ngGK_Fig21.png) - + **Figure 21. Configuring properties of UpdateListItem activity for rejected documents.** - + ![Configuring UpdateListItem for rejected documents](../images/ngGK_Fig21.png) - This completes "Creating a SharePoint document approval workflow." The completed workflow is shown in Figure 22. - - - **Figure 22. Completed SharePoint document approval workflow.** - - - - - - - ![Completed document approval workflow](../images/ngGK_Fig22.png) - - - - - - - - - - - ## Package and deploy the workflow - Following are resources that provide guidance for packaging and deploying your workflow as an SharePoint Add-in: - - - - -- [Deploying and installing apps for SharePoint: methods and options](https://msdn.microsoft.com/library/fp179933.aspx) - - -- [Publish apps for SharePoint](https://msdn.microsoft.com/library/jj164070.aspx) - - -- [How to: Create and Deploy Declarative Workflows in Sandboxed Solutions](https://msdn.microsoft.com/library/gg615452%28v=office.14%29.aspx) (Using SharePoint Designer 2013) - - - -> **Caution:** -> SharePoint Add-ins that contain integrated workflows (which can be associated with lists on the parent web) are differentiated from normal workflow apps by changing the following tag to **true** in the `workflowmanifest.xml` file in the app package: - - - +- [Deploying and installing apps for SharePoint: methods and options](https://msdn.microsoft.com/library/fp179933.aspx) +- [Publish apps for SharePoint](https://msdn.microsoft.com/library/jj164070.aspx) +- [How to: Create and Deploy Declarative Workflows in Sandboxed Solutions](https://msdn.microsoft.com/library/gg615452%28v=office.14%29.aspx) (Using SharePoint Designer 2013) -```XML +> [!CAUTION] +> SharePoint Add-ins that contain integrated workflows (which can be associated with lists on the parent web) are differentiated from normal workflow apps by changing the following tag to **true** in the `workflowmanifest.xml` file in the app package: +```XML true - ``` - ## See also - - - -- [Workflows in SharePoint](workflows-in-sharepoint.md) - - -- [Prepare to set up and configure a SharePoint workflow development environment](prepare-to-set-up-and-configure-a-sharepoint-workflow-development-environment.md) - - -- [SharePoint workflow development best practices](sharepoint-workflow-development-best-practices.md) - - -- [Develop SharePoint workflows using Visual Studio](develop-sharepoint-workflows-using-visual-studio.md) - - - - - - +- [Workflows in SharePoint](workflows-in-sharepoint.md) +- [Prepare to set up and configure a SharePoint workflow development environment](prepare-to-set-up-and-configure-a-sharepoint-workflow-development-environment.md) +- [SharePoint workflow development best practices](sharepoint-workflow-development-best-practices.md) +- [Develop SharePoint workflows using Visual Studio](develop-sharepoint-workflows-using-visual-studio.md) diff --git a/docs/general-development/create-a-workflow-with-elevated-permissions-by-using-the-sharepoint-workflo.md b/docs/general-development/create-a-workflow-with-elevated-permissions-by-using-the-sharepoint-workflo.md index 5bea2b300..cf9ffd1c1 100644 --- a/docs/general-development/create-a-workflow-with-elevated-permissions-by-using-the-sharepoint-workflo.md +++ b/docs/general-development/create-a-workflow-with-elevated-permissions-by-using-the-sharepoint-workflo.md @@ -1,39 +1,36 @@ --- title: Create a workflow with elevated permissions by using the SharePoint Workflow platform description: Create SharePoint workflows that access objects in SharePoint that require elevated permissions. These solutions grant permissions to the workflow app and wrap actions with the App Step. -ms.date: 12/29/2017 -ms.prod: sharepoint +ms.date: 05/18/2023 ms.assetid: 4656f6a0-36fd-4b7d-898e-8cd4bdbbda57 -localization_priority: Priority +ms.localizationpriority: high --- - # Create a workflow with elevated permissions by using the SharePoint Workflow platform - - This article describes how to create SharePoint workflows that access objects in SharePoint that require elevated permissions. These solutions use two features: granting permissions to the workflow app and wrapping actions with the App Step. - -> [!IMPORTANT] -> This article assumes that the SharePoint Workflow platform has been installed and configured and that SharePoint has been configured for add-ins. For more information about SharePoint Workflows and SharePoint Add-ins, including installation and configuration, see [Workflows in SharePoint](workflows-in-sharepoint.md) and [Install and manage SharePoint Add-ins](../sp-add-ins/sharepoint-add-ins.md). + +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). + +> [!IMPORTANT] +> This article assumes that the SharePoint Workflow platform has been installed and configured and that SharePoint has been configured for add-ins. For more information about SharePoint Workflows and SharePoint Add-ins, including installation and configuration, see [Workflows in SharePoint](workflows-in-sharepoint.md) and [Install and manage SharePoint Add-ins](../sp-add-ins/sharepoint-add-ins.md). Imagine that as a SharePoint administrator, you would like to define some processes for managing user requests for purchases of add-ins from the Office Store. In the simplest case, you want to send an acknowledgment email when a user requests an add-in. In addition, you might also want to add structure to the request approval process. - -By default, workflow does not have permissions to access the app catalog. Catalog lists in SharePoint require owner (full control) permissions. Workflows generally run at a permission level equivalent to write. - + +By default, workflow does not have permissions to access the app catalog. Catalog lists in SharePoint require owner (full control) permissions. Workflows generally run at a permission level equivalent to write. + To solve this, you have to create a workflow with elevated permissions by doing the following in the Site Collection site: 1. Allow the workflow to use add-in permissions. - -2. Grant full control permission to the workflow. - -3. Develop the workflow to wrap actions inside an App Step. +1. Grant full control permission to the workflow. +1. Develop the workflow to wrap actions inside an App Step. ## Allow a workflow to use add-in permissions on a SharePoint site The first step is to allow the workflow to use add-in permissions. You configure a workflow to use add-in permissions on the **Site settings** page of the SharePoint site where the workflow runs. The following procedure configures the SharePoint site to allow the workflow to use add-in permissions. - -> [!IMPORTANT] + +> [!IMPORTANT] > The procedure must be completed by a user that has **Site Administrator** permissions. ### To allow workflow to use add-in permissions @@ -42,79 +39,71 @@ The first step is to allow the workflow to use add-in permissions. You configure ![Settings menu](../images/SPD15-WFAppPermissions1.png) -2. Go to **Site settings**. - -3. In the **Site Actions** section, select **Manage site features**. +1. Go to **Site settings**. +1. In the **Site Actions** section, select **Manage site features**. +1. Locate the feature called **Workflows can use app permissions**, as shown in the figure, and then select **Activate**. -4. Locate the feature called **Workflows can use app permissions**, as shown in the figure, and then select **Activate**. - - > [!WARNING] - > This feature will not activate unless you have properly configured the SharePoint Workflow platform and SharePoint Add-ins. + > [!WARNING] + > This feature will not activate unless you have properly configured the SharePoint Workflow platform and SharePoint Add-ins. - ![Workflow can use app permissions feature](../images/SPD15-WFAppPermissions2.png) - + ![Workflow can use app permissions feature](../images/SPD15-WFAppPermissions2.png) ## Grant full control permission to a workflow For the workflow to function properly, it must be granted full control on the site. The following procedure grants full control permission to the workflow. - -> [!IMPORTANT] + +> [!IMPORTANT] > The procedure must be completed by a user that has **Site Owner** permissions. The workflow must already be published to the SharePoint site. ### To grant full control permission to a workflow 1. Select the **Settings** icon. - + ![Settings menu](../images/SPD15-WFAppPermissions1.png) -2. Go to **Site settings**. - -3. In the **Users and Permissions** section, select **Site app permissions**. - -> [!IMPORTANT] -> In SharePoint Online, select **Site collection app permissions**. This option is only visible to **Site Collection Administrators**. - -4. Copy the **client** section of the **App Identifier**. This is the identifier between the last "|" and the "@" sign, as shown in the figure. - - ![Selecting App Identifier](../images/SPD15-WFAppPermissions3.png) - -5. Go to the **Grant permission to an app** page. This must be done by browsing to the appinv.aspx page of the site. - - Example: `http://{hostname}/{the Site Collection}/_layouts/15/appinv.aspx`. - - > [!NOTE] - > The 'app' in this step refers to the workflow add-in in general and not just a specific workflow. Individual workflows cannot be access controlled. When you enable add-in permissions, you are enabling for all workflows within the Site Collection. - - For more information about setting up a workflow, see the [Blog article from Sympraxis Consulting: Looping Through Content in a SharePoint Site Workflow](http://sympmarc.com/series/looping-through-content-in-a-sharepoint-2013-site-workflow/) - - The following figure shows an example. - - ![The appinv.aspx URL example and page.](../images/SPD15-WFAppPermissions4.png) - -6. Paste the client ID in the **App Id** field, and then select **Lookup**, as shown in the previous figure. - -7. Paste the following code in the **Permission Request XML** field to grant full control permission *(note: this code block was updated on 12/29/17 to include the `AllowAppOnlyPolicy`)*. - - ```XML +1. Go to **Site settings**. +1. In the **Users and Permissions** section, select **Site app permissions**. + + > [!IMPORTANT] + > In SharePoint Online, select **Site collection app permissions**. This option is only visible to **Site Collection Administrators**. + +1. Copy the **client** section of the **App Identifier**. This is the identifier between the last "|" and the "@" sign, as shown in the figure. + + ![Selecting App Identifier](../images/SPD15-WFAppPermissions3.png) + +1. Go to the **Grant permission to an app** page. This must be done by browsing to the appinv.aspx page of the site. + + Example: `http://{hostname}/{the Site Collection}/_layouts/15/appinv.aspx`. + + > [!NOTE] + > The 'app' in this step refers to the workflow add-in in general and not just a specific workflow. Individual workflows cannot be access controlled. When you enable add-in permissions, you are enabling for all workflows within the Site Collection. + + For more information about setting up a workflow, see the [Blog article from Sympraxis Consulting: Looping Through Content in a SharePoint Site Workflow](http://sympmarc.com/series/looping-through-content-in-a-sharepoint-2013-site-workflow/) + + The following figure shows an example. + + ![The appinv.aspx URL example and page.](../images/SPD15-WFAppPermissions4.png) + +1. Paste the client ID in the **App Id** field, and then select **Lookup**, as shown in the previous figure. +1. Paste the following code in the **Permission Request XML** field to grant full control permission *(note: this code block was updated on 12/29/17 to include the `AllowAppOnlyPolicy`)*. + + ```XML + ``` + + > [!WARNING] + > There are no placeholders in the **Scope** value. It is a literal value. Enter it exactly as it appears here. - ``` + The following figure shows an example of the completed page _(note that the code in the **Permission Request XML** area does not reflect the recent update to the code in Step 7)_. - > [!WARNING] - > There are no placeholders in the **Scope** value. It is a literal value. Enter it exactly as it appears here. + ![Looking up an App Id.](../images/SPD15-WFAppPermissions5.png) - The following figure shows an example of the completed page _(note that the code in the **Permission Request XML** area does not reflect the recent update to the code in Step 7)_. - - ![Looking up an App Id.](../images/SPD15-WFAppPermissions5.png) +1. Select **Create**. +1. You are then asked to trust the workflow add-in, as shown in the following figure. Select **Trust It**. -8. Select **Create**. - -9. You are then asked to trust the workflow add-in, as shown in the following figure. Select **Trust It**. - - ![Trust the Workflow app.](../images/SPD15-WFAppPermissions6.png) - + ![Trust the Workflow app.](../images/SPD15-WFAppPermissions6.png) ## Wrap actions inside an App Step @@ -122,73 +111,60 @@ Finally, you need to wrap the workflow actions inside an App Step. The following ### To wrap actions inside an App Step -1. Open the app catalog site in SharePoint Designer. - -2. Create a new Custom List on which to run the workflow. In this example, the list name is **App Demo**. - -3. Select **Workflows** in the navigation window. - -4. Create a new **List Workflow** for the **App Demo** list, as shown in the figure. +1. Open the app catalog site in SharePoint Designer. +1. Create a new Custom List on which to run the workflow. In this example, the list name is **App Demo**. +1. Select **Workflows** in the navigation window. +1. Create a new **List Workflow** for the **App Demo** list, as shown in the figure. + + ![Create a new List Workflow.](../images/SPD15-WFAppPermissions7.png) + +1. Insert an **App Step**, as shown in the figure. + + ![Adding an App Step.](../images/SPD15-WFAppPermissions8.png) + +1. Insert a **Send an Email** action in the **App Step**. +1. Select the **Address book** button. In the **To** field, select **Workflow Lookup for a User**, and then select **Add** as shown in the figure. - ![Create a new List Workflow.](../images/SPD15-WFAppPermissions7.png) + ![Select Workflow lookup for a user.](../images/SPD15-WFAppPermissions9.png) -5. Insert an **App Step**, as shown in the figure. - - ![Adding an App Step.](../images/SPD15-WFAppPermissions8.png) +1. Enter the **Created By** field as the lookup value, as shown in the figure. -6. Insert a **Send an Email** action in the **App Step**. - -7. Select the **Address book** button. In the **To** field, select **Workflow Lookup for a User**, and then select **Add** as shown in the figure. + ![Lookup for Person dialog.](../images/SPD15-WFAppPermissions10.png) - ![Select Workflow lookup for a user.](../images/SPD15-WFAppPermissions9.png) - -8. Enter the **Created By** field as the lookup value, as shown in the figure. +1. Enter **Email** from the **App Demo** list in the email message body. +1. Select **OK** to return to the workflow. The completed workflow is shown in the figure. - ![Lookup for Person dialog.](../images/SPD15-WFAppPermissions10.png) - -9. Enter **Email** from the **App Demo** list in the email message body. - -10. Select **OK** to return to the workflow. The completed workflow is shown in the figure. + ![Email action in App Step.](../images/SPD15-WFAppPermissions11.png) - ![Email action in App Step.](../images/SPD15-WFAppPermissions11.png) - -11. Select the **Workflow Settings** icon in the ribbon, as shown in the figure. - - ![Workflow Settings icon in ribbon.](../images/SPD15-WFAppPermissions12.png) +1. Select the **Workflow Settings** icon in the ribbon, as shown in the figure. -12. Clear the check box next to **Automatically update the workflow status to the current stage name**, and then select **Publish**. - - ![Clear automatic updates check mark and publish.](../images/SPD15-WFAppPermissions13.png) - + ![Workflow Settings icon in ribbon.](../images/SPD15-WFAppPermissions12.png) - +1. Clear the check box next to **Automatically update the workflow status to the current stage name**, and then select **Publish**. + + ![Clear automatic updates check mark and publish.](../images/SPD15-WFAppPermissions13.png) ## Understand how it works To understand why elevating permissions for a workflow is required, consider that workflows are fundamentally add-ins for SharePoint, and they follow the same authorization rules of the add-in model. The default configuration for workflow is that the effective permissions of the workflow are an intersection of user permissions and the add-in permissions, as shown in the figure. - + ![Permissions diagram.](../images/SPD15-WFAppPermissions14.png) - + Two reasons why it is necessary to elevate permissions to create a workflow in the App Request list are: - By default, workflow only has write permission. - - The user has no permissions. - -The first step to solve this problem is to allow the application to authorize by using only its identity and ignoring that of the user. This is done by enabling the App Step feature. The second step grants full control permission to the workflow. - + +The first step to solve this problem is to allow the application to authorize by using only its identity and ignoring that of the user. This is done by enabling the App Step feature. The second step grants full control permission to the workflow. + The following diagram illustrates the change in permissions. - + ![Permissions matrix.](../images/SPD15-WFAppPermissions15.png) - - ## See also - [Blog article from the SharePoint Designer team: Workflow package and deploy scenario](https://blogs.msdn.microsoft.com/sharepointdesigner/2012/08/29/packaging-sharepoint-2013-list-site-and-reusable-workflow-and-how-to-deploy-the-package/) - [What's new in workflow in SharePoint](what-s-new-in-workflows-for-sharepoint.md) -- [Getting started with SharePoint workflow](get-started-with-workflows-in-sharepoint.md) +- [Getting started with SharePoint workflow](get-started-with-workflows-in-sharepoint.md) - [Workflow actions and activities reference for SharePoint](workflow-actions-and-activities-reference-for-sharepoint.md) - [Workflow development in SharePoint Designer and Visio](workflow-development-in-sharepoint-designer-and-visio.md) - - diff --git a/docs/general-development/create-associations-in-sharepoint.md b/docs/general-development/create-associations-in-sharepoint.md index eecc62841..77deedd3e 100644 --- a/docs/general-development/create-associations-in-sharepoint.md +++ b/docs/general-development/create-associations-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Create associations in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This article contains links to create associations in SharePoint. +ms.date: 06/07/2022 ms.assetid: 202599e3-232e-4b3a-9da5-c11f6e972283 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/create-hybrid-connectivity-apps-for-sharepoint.md b/docs/general-development/create-hybrid-connectivity-apps-for-sharepoint.md index 45c8a3f3c..f88e805a7 100644 --- a/docs/general-development/create-hybrid-connectivity-apps-for-sharepoint.md +++ b/docs/general-development/create-hybrid-connectivity-apps-for-sharepoint.md @@ -1,231 +1,111 @@ --- title: Create hybrid connectivity apps for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about the process of developing and deploying apps for SharePoint hybrid connectivity solutions. +ms.date: 05/18/2023 ms.assetid: 311f036e-3442-4497-b35e-442b665462d3 -localization_priority: Normal +ms.localizationpriority: medium --- - # Create hybrid connectivity apps for SharePoint + Learn about the process of developing and deploying apps for SharePoint hybrid connectivity solutions. + ## Hybrid connectivity in SharePoint and SharePoint Online - As businesses move to using SharePoint Online, they need a way to expose large amounts of proprietary data safely and securely. To help solve this challenge, SharePoint introduced hybrid connectivity. - - - + The Business Connectivity Services (BCS) hybrid connectivity capability lets SharePoint consume data housed on-premises, inside corporate firewalls, and secured by various forms of authentication. With hybrid connectivity functionality, SharePoint Online can access this data securely over the web as if it was on the same internal network. Once hybrid connectivity is configured, users can work with data that is secured within the business' infrastructure. They can access and manipulate the data according to the permissions that they have been granted in SharePoint. - - - + For a complete description of how to configure a working hybrid solution, see [Hybrid for SharePoint](https://technet.microsoft.com/library/jj838715.aspx). This series of articles walks you through all the requirements of configuring data sources, reverse proxies, search, security, networking, and everything else needed to set up the end-to-end scenario. - - - -> **Caution:** -> To configure a hybrid SharePoint environment, you need a combination of expert skills and significant hands-on experience with SharePoint, SharePoint Online, and related products and technologies. We recommend that you engage Microsoft Consulting Services to provide technical guidance and support during the design and deployment of your hybrid environment. > For more information, see [Microsoft Services](https://www.microsoft.com/microsoftservices/deploy.aspx). - - - +> [!CAUTION] +> To configure a hybrid SharePoint environment, you need a combination of expert skills and significant hands-on experience with SharePoint, SharePoint Online, and related products and technologies. We recommend that you engage Microsoft Consulting Services to provide technical guidance and support during the design and deployment of your hybrid environment. > For more information, see [Microsoft Services](https://www.microsoft.com/en-us/microsoft-365/products-apps-services). For you to be able to create an app that consumes data from an internal data source through BCS and the hybrid connection, this article assumes that you have already followed the procedures to configure your hybrid environment. - - - ## Create hybrid connectivity apps - Creating a hybrid SharePoint Add-in is essentially the same as creating any SharePoint Add-in. - - - -Follow these steps to create a hybrid app: - - - - -- [Prepare the data source](#bkmk_PrepareDataSource) - - -- [Create an SharePoint Add-in](#bkmk_CreateAnApp) - - -- [Create an external content type](#bkmk_CreateECT) - - -- [Deploy the hybrid app](#bkmk_DeployHybridApp) - - + +Follow these steps to create a hybrid app + +- [Prepare the data source](#prepare-the-data-source) +- [Create an SharePoint Add-in](#create-an-sharepoint-add-in) +- [To add an external content ty](#to-add-an-external-content-type) +- [Deploy the hybrid app](#deploy-the-hybrid-app) ### Prepare the data source - - -Most of the time, the data source is already in place and is servicing any number of business applications. However, that data may only be available from inside the corporate security infrastructure. If your data does exist on a server located on the inside of a corporate firewall, or is secured by some other means, the next step is to expose that data to BCS, which is also housed inside the firewall. A network device is configured to translate calls from SharePoint Online to the internal SharePoint farm. This device is referred to as a "reverse proxy" and allows the SharePoint Add-in located in the cloud to call into BCS located inside the firewall. BCS handles all the data connectivity from there. - - - -To make this data available to BCS, you should expose it as an OData source. You do this by creating an Internet Information Services (IIS) website that will host the service and allow BCS to talk to the data source through OData and Representational State Transfer (REST) endpoints. - - - -To create an OData endpoint, you will need to follow these steps for creating a Windows Communication Foundation (WCF) data service. - - - -### To create a WCF data service +Most of the time, the data source is already in place and is servicing any number of business applications. However, that data may only be available from inside the corporate security infrastructure. If your data does exist on a server located on the inside of a corporate firewall, or is secured by some other means, the next step is to expose that data to BCS, which is also housed inside the firewall. A network device is configured to translate calls from SharePoint Online to the internal ShePoint farm. This device is referred to as a "reverse proxy" and allows the SharePoint Add-in located in the cloud to call into BCS located inside the firewall. BCS handles all the data connectivity from there. + +To make this data available to BCS, you should expose it as an OData source. You do this by creating an Internet Information Services (IIS) website that will host the service and allow BCS to talk to the data source through OData and Representational State Transfer (REST) endpoints +To create an OData endpoint, you will need to follow these steps for creating a Windows Communication Foundation (WCF) data service. 1. Create an IIS website running at least Microsoft .NET Framework 4. Secure the site using basic authentication. - + > [!NOTE] - > It's not necessary for SharePoint to be installed on this server. In fact, for the sake of simplicity and performance, it's better if SharePoint is not installed on the server that hosts the WCF data service. - -2. Create a new project in Visual Studio 2012 using the **ASP.NET Empty Web Application** template. - - -3. In **Solution Explorer** add a new **ADO.NET Entity Data Model**. - - -4. Choose the **Generate from database** option in the **Entity Data Model Wizard**. - - -5. Select an existing connection, or create a new one. - - -6. Provide the URL and connection security information. - - -7. Select the items that you want to include in the model, and choose **Finish**. - - -8. Again in **Solution Explorer**, add a new **WCF Data Service** using the Visual Studio template. - - -9. Name the data service, and choose **Next**. - + > It's not necessary for SharePoint to be installed on this server. In fact, for the sake of simplicity and performance, it's better if SharePoint is not installed on the server thathosts the WCF data service + +1. Create a new project in Visual Studio 2012 using the **ASP.NET Empty Web Application** template. +1. In **Solution Explorer** add a new **ADO.NET Entity Data Model**. +1. Choose the **Generate from database** option in the **Entity Data Model Wizard**. +1. Select an existing connection, or create a new one. +1. Provide the URL and connection security information. +1. Select the items that you want to include in the model, and choose **Finish**. +1. Again in **Solution Explorer**, add a new **WCF Data Service** using the Visual Studio template. +1. Name the data service, and choose **Next**. + At this point, the entity model will be created and the resulting classes will be included in your project. - - -10. Set the security to the entities created by replacing the `/* TODO: put your data source class name here */` with the class name of the entity model you just created and specifying which entities you want to grant permissions to. - - -For a complete tutorial of how to set this up, see the following: - - - - -- [Getting Started With OData Part 1: Building an OData Service](https://msdn.microsoft.com/data/gg601462) - - -- [Quickstart (WCF Data Services)](https://msdn.microsoft.com/library/cc668796.aspx) - - -### Create an SharePoint Add-in - +1. Set the security to the entities created by replacing the `/* TODO: put your data source class name here */` with the class name of the entity model you just created and specifying which entities you want to grant permissions to. -One of the assumptions we are making here is that you are developing your app inside the corporate firewall. This represents a scenario where a developer working for a company would have a computer located behind the protection of the security infrastructure, developing and testing the app until it is ready to be deployed. This simplifies the process of connecting to the data source from Visual Studio, and uses Office Developer Tools for Visual Studio 2013 to automatically generate the external content type in the next step. - - - +For a complete tutorial of how to set this up, see the following: -### To create a new app +- [Getting Started With OData Part 1: Building an OData Service](https://msdn.microsoft.com/data/gg601462) +- [Quickstart (WCF Data Services)](https://msdn.microsoft.com/library/cc668796.aspx) +### Create an SharePoint Add-in -1. Open Visual Studio 2012 on your development computer that has Office Developer Tools for Visual Studio 2013 and SharePoint installed. - - -2. Create a new app for SharePoint. - - -3. Specify the name of the app, the local SharePoint URL that will host your site for testing, and how you want the app to be hosted. Choose **Finish**. - - +One of the assumptions we are making here is that you are developing your app inside the corporate firewall. This represents a scenario where a developer working for a company would have a computer located behind the protection of the security infrastructure, developing and testing the app until it is ready to be deployed. This simplifies the process of connecting to the data source from Visual Studio, and uses Office Developer Tools for Visual Studio 2013 to automatically generate the external content type in e next step. -### Create an external content type - +### To create a new app + +1. Open Visual Studio 2012 on your development computer that has Office Developer Tools for Visual Studio 2013 and SharePoint stalled. +1. Create a new app for SharePoint. +1. Specify the name of the app, the local SharePoint URL that will host your site for testing, and ### Create an external content type To add a BDC model or external content type to your project, do the following. - - - ### To add an external content type - 1. With your new project still open, open the shortcut menu for the solution, and choose **Add**, **Content types for an External Data source**. - - -2. The first page of the wizard is used to specify the URL of the data service. On the **Specify OData Source** page, enter the URL of the OData service that you want to connect to. The URL should resemble the following: **http://services.odata.org/Northwind/Northwind.svc/**. - - -3. Choose a name for your OData source, and then choose **Next**. - - -4. A list of data entities that are being exposed by the OData service appears. Make sure that the **Create list instances for the selected data entities** check box is selected. - - -5. Select one or more of the entities, and choose **Finish**. - - -6. The last thing you have to do before deployment is modify the URL in your newly created external content type file. - - Open the .ect file in an XML editor. - - -7. Modify the `ODataServiceMetadataUrl` property to point to the URL that allows access through the reverse proxy. - - -8. Modify the `ODataServiceUrl` property with the URL that allows access through the reverse proxy. - - +1. The first page of the wizard is used to specify the URL of the data service. On the **Specify OData Source** page, enter the URL of the OData service that you want to connect to. The URL should resemble the following: `http://services.odata.org/Northwind/Northwind.svc/`. +1. Choose a name for your OData source, and then choose **Next**. +1. A list of data entities that are being exposed by the OData service appears. Make sure that the +1. The last thing you have to do before deployment is modify the URL in your newly created external content type file. + + Open the **\*.ect** file in an XML editor. + +1. Modify the `ODataServiceMetadataUrl` property to point to the URL that allows access through the reverse proxy. +1. Modify the `ODataServiceUrl` property with the URL that allows access through the reverse proxy. + For information about how to add an OData-based external content type, see [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md). - - - ### Deploy the hybrid app - When it is time to deploy your app, you have a couple of choices. You can deploy it directly to a tenancy using F5 deployment, or you can package it using the publishing features of Visual Studio to create an .app file. This file can then be given to the SharePoint Online tenant administrator and uploaded. - - - -For information about deploying SharePoint Add-ins, see the following: - - - - -- [Deploying and installing SharePoint Add-ins: methods and options](https://msdn.microsoft.com/library/d15a74a7-3c10-485a-9885-7ef11aaa0d90%28Office.15%29.aspx) - - -- [Publish SharePoint Add-ins by using Visual Studio](https://msdn.microsoft.com/library/8137d0fa-52e2-4771-8639-60af80f693bb%28Office.15%29.aspx) - - -You can also take the BDCM file created for the external content type and extract that to be used at any level above the app. This is demonstrated in [How to: Convert an add-in-scoped external content type to tenant-scoped](how-to-convert-an-add-in-scoped-external-content-type-to-tenant-scoped.md). - - - + +For information about deploying SharePoint Add-ins, see the following: + +- [Deploying and installing SharePoint Add-ins: methods and options](https://msdn.microsoft.com/library/d15a74a7-3c10-485a-9885-7ef11aaa0d90%28Office.15%29.aspx + +- [Publish SharePoint Add-ins by using Visual Studio](https://msdn.microsoft.com/library/8137d0fa-52e2-4771-8639-60af80f693bb%28Office.15%29.aspx) + +You can also take the BDCM file created for the external content type and extract that to be used at any level above the app. This is demonstrated in [How to: Convert an add-in-scoped external ## See also - - - -- [Hybrid for SharePoint](https://technet.microsoft.com/library/jj838715.aspx) - - -- [Business Connectivity Services in SharePoint](business-connectivity-services-in-sharepoint.md) - - -- [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md) - - -- [Publish SharePoint Add-ins by using Visual Studio](https://msdn.microsoft.com/library/8137d0fa-52e2-4771-8639-60af80f693bb%28Office.15%29.aspx) - - +- [Hybrid for SharePoint](https://technet.microsoft.com/library/jj838715.aspx) +- [Business Connectivity Services in SharePoint](business-connectivity-services-in-sharepoint.md) +- [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md) diff --git a/docs/general-development/create-sharepoint-no-code-solutions.md b/docs/general-development/create-sharepoint-no-code-solutions.md index 09cf487fc..746ba7d28 100644 --- a/docs/general-development/create-sharepoint-no-code-solutions.md +++ b/docs/general-development/create-sharepoint-no-code-solutions.md @@ -1,9 +1,9 @@ --- title: Create SharePoint no-code solutions -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about SharePoint Composites and creating no-code solutions. +ms.date: 06/07/2022 ms.assetid: 9511846c-d2c6-4f23-b5de-24be4749598a -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/creating-a-workflow-by-using-sharepoint-designer-and-the-sharepoint-wo.md b/docs/general-development/creating-a-workflow-by-using-sharepoint-designer-and-the-sharepoint-wo.md index 633d106e5..2a41cd9e9 100644 --- a/docs/general-development/creating-a-workflow-by-using-sharepoint-designer-and-the-sharepoint-wo.md +++ b/docs/general-development/creating-a-workflow-by-using-sharepoint-designer-and-the-sharepoint-wo.md @@ -1,209 +1,86 @@ --- title: Creating a workflow by using SharePoint Designer 2013 and the SharePoint Workflow platform -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article with links to learn about creating a workflow by using SharePoint Designer 2013 and the SharePoint Workflow platform. +ms.date: 05/09/2023 ms.assetid: c05e0127-c6f5-48b8-b8f2-cbcc30149c8b -localization_priority: Priority +ms.localizationpriority: high --- +# Creating a workflow by using SharePoint Designer 2013 and the SharePoint Workflow platform +Learn how to install, open, and create a workflow by using SharePoint Designer 2013 and the SharePoint Workflow platform. -# Creating a workflow by using SharePoint Designer 2013 and the SharePoint Workflow platform -Learn how to install, open, and create a workflow by using SharePoint Designer 2013 and the SharePoint Workflow platform. - +> [!CAUTION] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more information, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). + +> [!CAUTION] +> SharePoint 2013 workflows are scheduled for retirement in April 2024. For more information, see: [SharePoint 2013 workflow retirement](https://support.microsoft.com/office/sharepoint-2013-workflow-retirement-4613d9cf-69aa-40f7-b6bf-6e7831c9691e). ## Install SharePoint Designer 2013 - -SharePoint Designer 2013 is a free download. To download and install SharePoint Designer 2013 follow these steps: - - - +SharePoint Designer 2013 is a free download. To download and install SharePoint Designer 2013 follow these steps: ### To install SharePoint Designer 2013 - -1. Open your web browser and navigate to the Microsoft Download Center: [https://www.microsoft.com/download](https://www.microsoft.com/download). - - -2. Type SharePoint Designer 2013 in the search field. - - -3. Click the link for "SharePoint Designer 2013". - - -4. Read the overview, system requirements, and installation instructions. Make sure your system is compatible. - - -5. Select your platform type: 64-bit ( **x64**) or 32-bit ( **x86**) as shown in the figure. - - -6. Follow the instructions to install SharePoint Designer 2013. - - +1. Open your web browser and navigate to the Microsoft Download Center: [https://www.microsoft.com/download](https://www.microsoft.com/download). +1. Type SharePoint Designer 2013 in the search field. +1. Click the link for "SharePoint Designer 2013". +1. Read the overview, system requirements, and installation instructions. Make sure your system is compatible. +1. Select your platform type: 64-bit ( **x64**) or 32-bit ( **x86**) as shown in the figure. +1. Follow the instructions to install SharePoint Designer 2013. **Figure: SharePoint Designer 2013 download page** - - - - - - - ![The SharePoint Designer 2013 Download page.](../images/SPD15-install-connect-1.png) - - - - - - - - - - - ## Open SharePoint Designer 2013 and connect to a SharePoint site - -SharePoint Designer 2013 installs as an Office 2013 application. To open SharePoint Designer 2013 and connect to a SharePoint site follow these steps: - - - -2013 -### To open SharePoint Designer 2013 and connect to a SharePoint site +SharePoint Designer 2013 installs as an Office 2013 application. To open SharePoint Designer 2013 and connect to a SharePoint site follow these steps: +### To open SharePoint Designer 2013 and connect to a SharePoint site -1. Open SharePoint Designer 2013 by selecting it on the **Start** menu. Click **Start** icon, click **All Programs**, click **Microsoft Office 2013**, and then click **SharePoint Designer 2013**. - - -2. Click **Open Site** on the SharePoint Designer 2013 start page. - - -3. Enter the SharePoint site that you want to connect to. For example, http://www.contoso.com/sites/a-sharepoint-site. - - -4. Click **Open** to open the site. - - -5. Enter your credentials, if prompted. (If security is not integrated with the computer you signed in on then you are prompted to enter your credentials.) Make sure to use credentials that have access to the SharePoint site. - - +1. Open SharePoint Designer 2013 by selecting it on the **Start** menu. Click **Start** icon, click **All Programs**, click **Microsoft Office 2013**, and then click **SharePoint Designer 2013**. +1. Click **Open Site** on the SharePoint Designer 2013 start page. +1. Enter the SharePoint site that you want to connect to. For example, `https://www.contoso.com/sites/a-sharepoint-site`. +1. Click **Open** to open the site. +1. Enter your credentials, if prompted. (If security is not integrated with the computer you signed in on then you are prompted to enter your credentials.) Make sure to use credentials that have access to the SharePoint site. ## Create a List workflow based on the SharePoint Workflow platform - SharePoint Designer 2013 can be used for many important tasks. The navigational pane is used to switch between different aspects of SharePoint Designer 2013. To create a new List workflow based on the SharePoint Workflow platform, follow these steps: - - - ### To create a workflow based on the SharePoint Workflow platform - 1. Click the Workflows node in the Navigation pane. - - -2. Click the **List Workflow** drop-down in the **New** section of the ribbon, as shown in the figure. - - -3. Select the list that you want to associate with the new workflow. - - -4. On the **Create List Workflow** dialog box, enter a name and description for the workflow and then make sure that the **Platform Type** is set to **SharePoint 2013 Workflow**, as shown in the figure. - +1. Click the **List Workflow** drop-down in the **New** section of the ribbon, as shown in the figure. +1. Select the list that you want to associate with the new workflow. +1. On the **Create List Workflow** dialog box, enter a name and description for the workflow and then make sure that the **Platform Type** is set to **SharePoint 2013 Workflow**, as shown in the figure. + > [!NOTE] - > If you do not see SharePoint Workflow as an available platform type then Workflow Manager is not configured to work with the SharePoint farm. See [Configure Workflow Manager to work with the SharePoint Server 2013 Farm](https://technet.microsoft.com/library/jj658588.aspx#section5). + > If you do not see SharePoint Workflow as an available platform type then Workflow Manager is not configured to work with the SharePoint farm. See [Configure Workflow Manager to work with the SharePoint Server 2013 Farm](https://technet.microsoft.com/library/jj658588.aspx#section5). -5. Click **OK** to create the workflow. - - +1. Click **OK** to create the workflow. **Figure: The ribbon button for creating a new list workflow** - - - - - - - ![SharePoint Designer 2013 - New List Workflow](../images/SPD15-install-connect-2.png) - - - - - - - - - - - **Figure: Create List Workflow dialog box** - - - - - - - ![Workflow Creation Dialog](../images/SPD15-install-connect-3.png) - - - - - - - - - - - -Now that the workflow is created, you can add Actions, Conditions, Stages, Steps, and Loops to build your workflow. These workflow components are available in the ribbon of SharePoint Designer 2013, as shown in the figure. - - - -**Figure: Workflow items for the SharePoint Workflow platform** +Now that the workflow is created, you can add Actions, Conditions, Stages, Steps, and Loops to build your workflow. These workflow components are available in the ribbon of SharePoint Designer 2013, as shown in the figure. - - - +**Figure: Workflow items for the SharePoint Workflow platform** - - - ![Workflow items in the ribbon.](../images/SPD15-install-connect-4.png) - + > [!NOTE] > The previous procedure is used to create a List workflow. A Reusable workflow or Site workflow can be created using the same procedure with the following modification. Instead of selecting the List Workflow button in the ribbon select the **Reusable Workflow** or **Site Workflow** button when creating the workflow. - - - To learn more about the available components of workflow development, see [Workflow actions quick reference (SharePoint Workflow platform)](workflow-actions-quick-reference-sharepoint-workflow-platform.md). - - - ## See also - - - -- [What's new in workflow in SharePoint](https://msdn.microsoft.com/library/6ab8a28b-fa2f-4530-8b55-a7f663bf15ea.aspx) - - -- [Getting started with SharePoint workflow](https://msdn.microsoft.com/library/cc73be76-a329-449f-90ab-86822b1c2ee8.aspx) - - -- [Workflow development in SharePoint Designer and Visio](workflow-development-in-sharepoint-designer-and-visio.md) - - - - - - +- [What's new in workflow in SharePoint](https://msdn.microsoft.com/library/6ab8a28b-fa2f-4530-8b55-a7f663bf15ea.aspx) +- [Getting started with SharePoint workflow](https://msdn.microsoft.com/library/cc73be76-a329-449f-90ab-86822b1c2ee8.aspx) +- [Workflow development in SharePoint Designer and Visio](workflow-development-in-sharepoint-designer-and-visio.md) diff --git a/docs/general-development/cross-site-publishing-in-sharepoint.md b/docs/general-development/cross-site-publishing-in-sharepoint.md index d19f8e005..bb0aac128 100644 --- a/docs/general-development/cross-site-publishing-in-sharepoint.md +++ b/docs/general-development/cross-site-publishing-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Cross-site publishing in SharePoint +description: SharePoint introduces a cross-site publishing feature that enables you to reuse content across multiple site collections. It uses built-in search capabilities to enable publishing scenarios and architectures. For the first time, you can design sites that cross SharePoint farms—enabling your sites to span the boundary between intranets and the Internet. ms.date: 06/18/2019 -ms.prod: sharepoint ms.assetid: 33f49e69-c1d3-4a6e-8887-5df683cba022 -localization_priority: Normal +ms.localizationpriority: medium --- # Cross-site publishing in SharePoint @@ -11,29 +11,29 @@ localization_priority: Normal SharePoint introduces a cross-site publishing feature that enables you to reuse content across multiple site collections. It uses built-in search capabilities to enable publishing scenarios and architectures. For the first time, you can design sites that cross SharePoint farms—enabling your sites to span the boundary between intranets and the Internet. > [!IMPORTANT] -> This capability is not available in SharePoint Online. Cross-site publishing capability is only available in on-premises deployments. +> This capability is not available in SharePoint Online. Cross-site publishing capability is only available in on-premises deployments. Consider a site with one authoring site collection that feeds multiple publishing site collections, with different domains, all crawled by public search engines and optimized for search engine optimization (SEO). Cross-site publishing enables this scenario and others like it, without requiring you to use content deployment. Cross-site publishing was designed with some common scenarios in mind, including: - + - Share an item list or a page library as a publishing catalog - Consume a catalog from search - Combine cross-site publishing with the variations feature to enable authoring multilingual sites from a common authoring site collection - + ## Catalogs Catalogs, introduced in SharePoint, include a list or library that is shared out to search for consumption on publishing sites. Catalogs enable content to be published across site collections—the cross-site publishing features depend on catalogs. You can use catalogs to really reuse content across your sites and across the boundary between your intranet sites, extranet sites, and Internet sites. For predefined search queries, catalogs are flagged in search. You can surface content stored in catalogs across site collections by using the [Content Search web part in SharePoint](content-search-web-part-in-sharepoint.md). - + ## When should I use cross-site publishing? There are some cases where cross-site publishing is not efficient or appropriate. Whether you have external data sources and how you connect to them, variations, site type, search database implementation, and use of the product catalog are all factors that should influence your decision. Table 1 provides more information about these design considerations. - - - + + + **Table 1. Design considerations for cross-site publishing** @@ -45,126 +45,126 @@ There are some cases where cross-site publishing is not efficient or appropriate |**Variations implementation**
|If you are implementing a basic variations site that makes a pages library, document library, and general lists available in a few languages, cross-site publishing makes sense. The same is true if you choose to implement managed navigation or structured navigation on a variations site.
Cross-site publishing works for some architectures but not others. For example, you can use cross-site publishing to publish content from a variations **SPSite** to a publishing site with variations enabled if the source **SPSite** is not consuming data from another variations site or site collection.
| |**Catalog implementation**
|Whether you implement the product catalog into your site architecture and how you implement it may affect whether cross-site publishing is the most effective or appropriate choice. If you are using the product catalog to support a multilingual variations site configuration and are publishing to an Internet site, you can implement cross-site publishing.
| |**Managed navigation**
|Cross-site publishing works with most implementations of managed navigation and the term store. In some implementations, navigation metadata transfer may not work as expected. For example, when one variations site depends on metadata from another variations site to drive site navigation, and you use cross-site publishing to publish content to the target site, navigation metadata transfer may not work as expected.
| - + ## How can I set up a catalog? -Category pages and catalog item pages are page layouts that you can use to show structured catalog content consistently across a site. SharePoint enables you to create and customize page layouts for SharePoint and above. For more information, see [Customize page layouts for a catalog-based site in SharePoint](https://msdn.microsoft.com/library/office/dn144674.aspx +Category pages and catalog item pages are page layouts that you can use to show structured catalog content consistently across a site. SharePoint enables you to create and customize page layouts for SharePoint and above. For more information, see [Customize page layouts for a catalog-based site in SharePoint](https://msdn.microsoft.com/library/office/dn144674.aspx ). - - - + + + ## Cross-site publishing APIs SharePoint introduces classes that you can use to support cross-site publishing implementation in your code. These APIs are available in the .NET server publishing library. Use them to customize how SharePoint shares lists as catalogs for content reuse or consumes a catalog from search. You can use the members of the following classes in custom code to support cross-site publishing tasks: - - - + + + - Use the **PublishingCatalogUtility** class to retrieve a list of available catalogs, get information about catalogs and their statuses, get information about lists and libraries that can be connected to catalogs, and start or stop sharing catalogs. - - - -```cs - + + + +```csharp + /// Retrieve available catalogs. public static List GetPublishingCatalogs(SPSite site, int startRow, int numberOfRows, string filterText, out int totalNumberOfCatalogs) ``` - - -```cs - + + +```csharp + ///Get catalog information that is saved for a list. public static bool GetCatalogConfiguration(SPList list, out CatalogShareSettings catalogSettings, out string selectedTaxonomyField) ``` - - -```cs - + + +```csharp + ///Stop sharing a list or library as a publishing catalog for cross-publishing content reuse. public static void UnPublishCatalog(SPList list) ``` - Use the **CatalogCollectionManager** class to consume catalogs from search. Learn about the connection that a catalog has to search, and get information about it. Add or remove a catalog from the internal collection of catalogs, and queue an operation to queue up a connection that is configured to rewrite URLs when the **Update** method is called. - - - -```cs - + + + +```csharp + /// Add catalog or site source into the internal CatalogInfo collection, but the source is not persisted into the property bag. public void AddCatalogConnection(CatalogConnectionSettings catalogInfo) ``` - - -```cs - + + +```csharp + /// Queues an Add operation to add a connection configured to rewrite URLs. The connection is added to the store when the Update method is called. -public void AddCatalogConnection(CatalogConnectionSettings catalogInfo, +public void AddCatalogConnection(CatalogConnectionSettings catalogInfo, string[] orderedPropertiesForUrlRewrite, -string webUrl, +string webUrl, string catalogTaxonomyManagedProperty, bool isManualRule) ``` - - -```cs - + + +```csharp + /// Update existing catalog/site source in the internal CatalogInfo collection. Edits are not committed until the Update method is called. public void UpdateCatalogConnection(CatalogConnectionSettings catalogInfo) ``` - - -```cs - + + +```csharp + /// Remove a catalog or site source. Deletion is not committed until the Update method is called. public void DeleteCatalogConnection(string catalogPath) ``` - - -```cs - + + +```csharp + /// Determine whether a connection exists to this source from the site. public bool Contains(string catalogPath) ``` - - -```cs - + + +```csharp + /// Get the settings for a catalog connected to this site. public CatalogConnectionSettings GetCatalogConnectionSettings(string catalogPath) ``` diff --git a/docs/general-development/custom-content-processing-with-the-content-enrichment-web-service-callout.md b/docs/general-development/custom-content-processing-with-the-content-enrichment-web-service-callout.md index e97ef5e14..7c4275829 100644 --- a/docs/general-development/custom-content-processing-with-the-content-enrichment-web-service-callout.md +++ b/docs/general-development/custom-content-processing-with-the-content-enrichment-web-service-callout.md @@ -1,177 +1,96 @@ --- title: Custom content processing with the Content Enrichment web service callout -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This is an article to learn about custom content processing with the Content Enrichment web service callout. +ms.date: 05/18/2023 ms.assetid: bdda92c8-9c8d-416e-9a6b-4a9373686fa0 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Custom content processing with the Content Enrichment web service callout + Learn about the content enrichment web service callout in SharePoint that enables developers to create an external web service to modify managed properties for crawled items during content processing. + Search in SharePoint enables users to modify the managed properties of crawled items before they are indexed by calling out to an external content enrichment web service. The ability to modify managed properties for items during content processing is helpful when performing tasks such as data cleansing, entity extraction, classification, and tagging. - - - +![Content enrichment within content processing](../images/SP15_Content_Enrichment.gif) **Figure 1. Content enrichment within content processing** - - - - - - - -![Content enrichment within content processing](../images/SP15_Content_Enrichment.gif) - - - -Figure 1 shows a part of the process that takes place in the content processing component. The content enrichment web service is a SOAP-based service that you can create to receive a callout from the web service client inside the content processing component. Based on Figure 1, the web service client refers to the Content Enrichment operator inside the content processing component; theweb service refers to the SOAP web service that you implement.The web service receives a configurable payload from the content processing component. Then, the resulting response from the web service is merged into the crawled item before it is added to the search index. The web service client works with managed properties that you can configure as input properties or as output properties. Input properties are sent to the web service; output properties are returned by the web service. Certain managed properties are hidden or are read-only and can't be sent to the web service or received from the web service. See [How to list all read-only managed properties for the Content Enrichment web service](#SP15contentprocess_read-only_managed_properties) for information about how to verify which managed properties are read-only. - -> **Important:** -> The content enrichment callout step can only be configured with a single web service endpoint. Any kind of fault tolerance, or routing capabilities to support multiple implementations must be handled by the developer implementing the web service. In addition, the developer may have various web service implementations hosted at different endpoints; however, at any given time, only one of these endpoints can be used in the configuration. - - - +Figure 1 shows a part of the process that takes place in the content processing component. The content enrichment web service is a SOAP-based service that you can create to receive a callout from the web service client inside the content processing component. Based on Figure 1, the web service client refers to the Content Enrichment operator inside the content processing component; the web service refers to the SOAP web service that you implement.The web service receives a configurable payload from the content processing component. Then, the resulting response from the web service is merged into the crawled item before it is added to the search index. The web service client works with managed properties that you can configure as input properties or as output properties. Input properties are sent to the web service; output properties are returned by the web service. Certain managed properties are hidden or are read-only and can't be sent to the web service or received from the web service. See [How to list all read-only managed properties for the Content Enrichment web service](#how-to-list-all-read-only-managed-properties-for-the-content-enrichment-web-service) for information about how to verify which managed properties are read-only. +> [!IMPORTANT] +> The content enrichment callout step can only be configured with a single web service endpoint. Any kind of fault tolerance, or routing capabilities to support multiple implementations must be handled by the developer implementing the web service. In addition, the developer may have various web service implementations hosted at different endpoints; however, at any given time, only one of these endpoints can be used in the configuration. ## Content enrichment web service contract - The web service client is a SOAP (version 1.1) RPC client with a predefined behavior. The web service contract has the following characteristics: - - - - The content processing component sends a SOAP RPC call to a configurable endpoint over HTTP. - - - The payload contains an array of property objects. - - - The web service performs some custom logic on the array of property objects, and returns an array of modified or new property objects. - - - The web service must send a response to the web service client within a given timeout. - - - No specific authentication or encryption mechanisms are supported as part of the contract. You can, however, apply your own security on the transport mechanism. - - ## Configuring the Content Enrichment web service client - To configure the web service client, you use the following Windows PowerShell cmdlets: - - - - -- [Get-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219783%28office.15%29.aspx) - - -- [Set-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219659%28office.15%29.aspx) - - -- [Remove-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219742%28office.15%29.aspx) - - -- [New-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219502%28office.15%29.aspx) - - + +- [Get-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219783%28office.15%29.aspx) +- [Set-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219659%28office.15%29.aspx) +- [Remove-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219742%28office.15%29.aspx) +- [New-SPEnterpriseSearchContentEnrichmentConfiguration](https://technet.microsoft.com/library/jj219502%28office.15%29.aspx) + Table 1 lists the properties you can configure through the Windows PowerShell cmdlets mentioned previously. - - - **Table 1. Properties that are configurable for the client by using Windows PowerShell cmdlets** - -|**Configuration property**|**Description**|**Default value**| -|:-----|:-----|:-----| -|**Endpoint**
|Specifies the URL of the external web service.
|Empty.
| -|**InputProperties**
|The managed properties that the external web service receives.
|Empty.
| -|**OutputProperties**
|The managed properties that the external web service returns.
|Empty.
| -|**Timeout**
|The amount of time until the web service times out in milliseconds.
Depending on **FailureMode**, the item fails to be processed or a warning is written to the ULS log.
|5000 milliseconds; Valid range [100, 30000].
| -|**SendRawData**
|Enables or disables sending raw data to the web service.
|False.
| -|**MaxRawDataSize**
|The maximum size of raw data sent to the web service in kilobytes (KB). If the binary data of an item exceeds this limit, the item is not sent. This does not prevent the **InputProperties** from being sent, and the **OutputProperties** from being received.
|5120 kilobytes.
| -|**FailureMode**
|Controls the behavior of the web service client when errors occur. When **FailureMode** is set to **ERROR**, any problems that occur during content enrichment processing send a failed callback for that particular item.
When **FailureMode** is set to **WARNING**, the item is indexed, without any modifications by the web service and a warning is written to the ULS log.
|Error.
| -|**DebugMode**
|A mode that when set to **true** enables the content enrichment client to send all managed properties to the client without expecting any properties in return. Any configured **Trigger** property, **InputProperties** property, and **OutputProperties** property are ignored.
|False.
| -|**Trigger**
|A **Boolean** predicate that is executed on every crawled item. If the predicate evaluates to **true**, the record is sent to the web service. Otherwise, the item is passed through to the search index.
|Empty.
| - +| **Configuration property** | **Description** | **Default value** | +| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------- | +| **Endpoint** | Specifies the URL of the external web service. | Empty. | +| **InputProperties** | The managed properties that the external web service receives. | Empty. | +| **OutputProperties** | The managed properties that the external web service returns. | Empty. | +| **Timeout** | The amount of time until the web service times out in milliseconds. Depending on **FailureMode**, the item fails to be processed or a warning is written to the ULS log. | 5000 milliseconds; Valid range [100, 30000]. | +| **SendRawData** | Enables or disables sending raw data to the web service. | False. | +| **MaxRawDataSize** | The maximum size of raw data sent to the web service in kilobytes (KB). If the binary data of an item exceeds this limit, the item is not sent. This does not prevent the **InputProperties** from being sent, and the **OutputProperties** from being received. | 5120 kilobytes. | +| **FailureMode** | Controls the behavior of the web service client when errors occur. When **FailureMode** is set to **ERROR**, any problems that occur during content enrichment processing send a failed callback for that particular item. When **FailureMode** is set to **WARNING**, the item is indexed, without any modifications by the web service and a warning is written to the ULS log. | Error. | +| **DebugMode** | A mode that when set to **true** enables the content enrichment client to send all managed properties to the client without expecting any properties in return. Any configured **Trigger** property, **InputProperties** property, and **OutputProperties** property are ignored. | False. | +| **Trigger** | A **Boolean** predicate that is executed on every crawled item. If the predicate evaluates to **true**, the record is sent to the web service. Otherwise, the item is passed through to the search index. | Empty. | ### How to list all read-only managed properties for the Content Enrichment web service - Certain managed properties are read-only and cannot be output from the web service. These properties can be listed by using the [Get-SPEnterpriseSearchServiceApplication](https://technet.microsoft.com/library/ff608050%28office.15%29.aspx) and [Get-SPEnterpriseSearchMetadataManagedProperty](https://technet.microsoft.com/library/ff607560%28office.15%29.aspx)Windows PowerShell cmdlets, shown in the following example: - - - - -``` +```powershell $ssa = Get-SPEnterpriseSearchServiceApplication Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $ssa | ?{$_.IsReadOnly -or $_.MappingDisallowed -or $_.DeleteDisallowed} - ``` - ## About trigger conditions for configuring the web service callout - A trigger condition is an expression that is used to configure the web service callout. If a trigger condition evaluates to **true**, the web service client performs a callout for that record. If a trigger condition evaluates to **false**, the web service client does not perform a callout and passes the crawled item to the search index. Alternatively, if no trigger condition is configured; all items are sent to the web service. - - - -Trigger conditions use an expression language to refer to the values of managed properties. You can use the operators and functions in the expression language to build simple or complex trigger conditions so you can determine when to perform a web service callout. - - - + +Trigger conditions use an expression language to refer to the values of managed properties. You can use the operators and functions in the expression language to build simple or complex trigger conditions so you can determine when to perform a web service callout. + Table 2 lists examples of trigger conditions. - - - **Table 2. Trigger condition examples for configuring the Content Enrichment web service callout** +| **Expression** | **Description** | **Requirements** | +| :-------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------- | +| MP1 > 2 | Returns **true** if the value of the managed property named MP1 is greater than 2. | MP1 must have a numeric type. | +| IsNull(MP2) | Returns **true** if the managed property named MP2 is not present for the crawled item or is empty/null. | MP2 can be of any type. | +| StartsWith(MP1, "sample") AND MP2 != 18 | Returns **true** if the value in the managed property MP1 starts with "sample" and the value of managed property MP2 is not 18. | MP1 must be of type **string** and MP2 must be a numeric type. | +| IsDay(MP1, 2009, 12, 24) | Checks whether the managed property MP1 contains a **DateTime** that falls on December 24, 2009. | MP1 must be of type **DateTime**. | -|**Expression**|**Description**|**Requirements**| -|:-----|:-----|:-----| -|MP1 > 2
|Returns **true** if the value of the managed property named MP1 is greater than 2.
|MP1 must have a numeric type.
| -|IsNull(MP2)
|Returns **true** if the managed property named MP2 is not present for the crawled item or is empty/null.
|MP2 can be of any type.
| -|StartsWith(MP1, "sample") AND MP2 != 18
|Returns **true** if the value in the managed property MP1 starts with "sample" and the value of managed property MP2 is not 18.
|MP1 must be of type **string** and MP2 must be a numeric type.
| -|IsDay(MP1, 2009, 12, 24)
|Checks whether the managed property MP1 contains a **DateTime** that falls on December 24, 2009.
|MP1 must be of type **DateTime**.
| - -See [Trigger expressions syntax in SharePoint](trigger-expressions-syntax-in-sharepoint.md) for the elements that can be used in a trigger expression and a list of supported functions. - - - +See [Trigger expressions syntax in SharePoint](trigger-expressions-syntax-in-sharepoint.md) for the elements that can be used in a trigger expression and a list of supported functions. ## Implementing the Content Enrichment external web service - -For a basic implementation, do the following: - - - +For a basic implementation, do the following: 1. Include the **Microsoft.Office.Server.Search.ContentProcessingEnrichment.dll** located in `C:\\Program Files\\Microsoft Office Servers\\15.0\\Search\\Applications\\External` in your project as a reference. - - -2. Implement **IContentProcessingEnrichmentService** as a web service. - - +1. Implement **IContentProcessingEnrichmentService** as a web service. ## See also - - - -- [Configure search in SharePoint](configure-search-in-sharepoint.md) - - -- [Custom content processing with the Content Enrichment web service callout](custom-content-processing-with-the-content-enrichment-web-service-callout.md) - - +- [Configure search in SharePoint](configure-search-in-sharepoint.md) +- [Custom content processing with the Content Enrichment web service callout](custom-content-processing-with-the-content-enrichment-web-service-callout.md) diff --git a/docs/general-development/custom-security-trimming-for-search-in-sharepoint-server.md b/docs/general-development/custom-security-trimming-for-search-in-sharepoint-server.md index c92b32cfd..dba0ab609 100644 --- a/docs/general-development/custom-security-trimming-for-search-in-sharepoint-server.md +++ b/docs/general-development/custom-security-trimming-for-search-in-sharepoint-server.md @@ -1,9 +1,9 @@ --- title: Custom security trimming for Search in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn about the two kinds of custom security trimmer interfaces, ISecurityTrimmerPre and ISecurityTrimmerPost, and the steps you must take to create a custom security trimmer. +ms.date: 06/09/2022 ms.assetid: fbbf0cc4-e135-426a-9996-34eb954dbd5a -localization_priority: Normal +ms.localizationpriority: medium --- @@ -11,192 +11,192 @@ localization_priority: Normal # Custom security trimming for Search in SharePoint Learn about the two kinds of custom security trimmer interfaces, **ISecurityTrimmerPre** and **ISecurityTrimmerPost**, and the steps you must take to create a custom security trimmer. At query time, Search in SharePoint performs security trimming of search results that are based on the identity of the user submitting the query, by using the security information obtained from the crawl component. - - - + + + You might have certain scenarios, however, in which the built-in security trimming results aren't sufficient for your requirements. In such scenarios, you need to implement custom security trimming. Search in SharePoint provides support for custom security trimming through the [ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) interface, [ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) interface, and [ISecurityTrimmer2](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmer2.aspx) interface (deprecated) in the [Microsoft.Office.Server.Search.Query](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.aspx) namespace. > [!NOTE] > Custom pre-trimmers don't support Windows SIDs in ACLs, only claims. If any of the SID claim types are returned from a custom pre-trimmer, the resulting ACEs in the index will be encoded as a claim, not as SID. Hence they do not match Windows user identities that are based on SIDs. - - - + + + ## Implementing the interfaces for custom security trimming The **ISecurityTrimmerPre** interface carries out pre-trimming, or pre-query evaluation, where the search query is rewritten to add security information before the search query is matched to the search index. The **ISecurityTrimmerPost** interface carries out post-trimming, or post-query evaluation, where the search results are pruned before they are returned to the user. - - - + + + We recommend the use of pre-trimming for performance and general correctness; pre-trimming prevents information leakage for refiner data and hit count instances. Post-trimmers can be used in cases where the security trimming cannot be represented accurately with query filters; for example, if there is a need to filter away documents depending on the local time of the user issuing the query, such as during official business hours only. - - - + + + ### Implementing the ISecurityTrimmerPre interface To create a custom security pre-trimmer for search results, you must create a component that implements the **ISecurityTrimmerPre** interface. - - - + + + The **ISecurityTrimmerPre** interface contains two methods that you must implement: [Initialize(NameValueCollection, SearchServiceApplication)](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.Initialize.aspx) and [AddAccess(Boolean, Claims)](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.AddAccess.aspx) . - - - + + + #### Initialize Method The **Initialize** method is executed when the security pre-trimmer is loaded into the worker process, and does not execute again until the worker process is recycled. Two parameters are passed into the method: - - - + + + - _staticProperties_: A [NameValueCollection](https://msdn.microsoft.com/library/System.Collections.Specialized.NameValueCollection.aspx) object containing the configuration properties that are specified for the security trimmer when it is registered with the Search service application. - - + + - _searchApplication_: A [SearchServiceApplication](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.SearchServiceApplication.aspx) object that represents the Search service application. - - + + #### AddAccess Method The **AddAccess** method is executed once per pre-trimmer, for each incoming query before the query is evaluated. - - - -Two parameters are passed into this method: - - - + + + +Two parameters are passed into this method: + + + - _sessionProperties_: A **[T:System.Collections.Generic.IDictionary]** object that contains the properties of the query. - - + + - _userIdentity_: A [IIdentity](https://msdn.microsoft.com/library/System.Security.Principal.IIdentity.aspx) object that contains the user identity. - - + + ### Implementing the ISecurityTrimmerPost interface To create a custom security post-trimmer for search results, you must create a component that implements the **ISecurityTrimmerPost** interface. - - - -The **ISecurityTrimmerPost** interface contains two methods that you must implement: [Initialize(NameValueCollection, SearchServiceApplication)](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.Initialize.aspx) and **CheckAccess(IList, IList, IDictionary, IIdentity)**. - - - + + + +The **ISecurityTrimmerPost** interface contains two methods that you must implement: [Initialize(NameValueCollection, SearchServiceApplication)](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.Initialize.aspx) and **CheckAccess(IList\, IList\, IDictionary\, IIdentity)**. + + + #### Initialize method The **Initialize** method is executed when the security trimmer is loaded into the worker process, and does not execute again until the worker process is recycled. Two parameters are passed into the method:and - - - + + + - _staticProperties_: A [NameValueCollection](https://msdn.microsoft.com/library/System.Collections.Specialized.NameValueCollection.aspx) object containing the configuration properties specified for the security trimmer when it is registered with the Search service application. - - + + - _searchApplication_: A [SearchServiceApplication](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.SearchServiceApplication.aspx) object that represents the Search service application. - - + + #### CheckAccess method The **CheckAccess** method is executed once per post-trimmer, for each result set query, after the query is evaluated. - - - + + + Four parameters are passed into this method: - - - + + + - _documentUrls_: A [IList\](https://msdn2.microsoft.com/library/5y536ey6) object that contain the URLs for each content item from the search results that match the crawl rule. - - + + - _documentAcls_: A [IList\](https://msdn2.microsoft.com/library/5y536ey6) object containing item ACLs for each content item whose access is to be determined by the security trimmer implementation. - - + + - _sessionProperties_: A [IDictionary\](https://msdn2.microsoft.com/library/s4ys34ea) object containing the transient property bag. - - + + - _userIdentity_: An [IIdentity](https://msdn.microsoft.com/library/System.Security.Principal.IIdentity.aspx) object from which implementers can retrieve the user's identity. - - + + The **CheckAccess** method returns a [BitArray](https://msdn.microsoft.com/library/System.Collections.BitArray.aspx) object that represents an array of **true** or **false** values, one for each content item URL in the **IList** object that is passed as the first parameter of the method. The query processing component uses these values to perform the security post-trimming of the results. If the array value for a particular content item is **true**, the item is included in the returned results; if the array value is **false**, the item is removed. - - - + + + When implementing the **CheckAccess** method, you can use two pieces of information for each item to determine whether to return **true** or **false** for the item: the identity of the user who submitted the query and the URL of the content item. Alternatively, you can also pass custom document ACL information from the connector to the **CheckAccess** method. - - - + + + #### Retrieving the user identity for your security trimmer You can retrieve the user's identity by accessing the thread's current principal, as shown in the following code example. - - - -```cs + + + +```csharp IIdentity userIdentity = System.Threading.Thread.CurrentPrincipal.Identity; ``` You must also include the following namespace directive. - - - -```cs + + + +```csharp using System.Security.Principal; ``` You can also retrieve the identity of the user from the **CheckAccess** method's **passedUserIdentity** parameter. - - - + + + #### Passing document ACLs from the connector to your security trimmers A connector, as the name implies, is a communication bridge between SharePoint and the external system that hosts the external data. If you are working with custom connectors, you can pass the document's ACL information directly to the post-trimmer by setting the **docaclmeta** document property. As long as the configured connectors and post-trimmers have the same format and interpretation of the field, you are free to use it to pass custom data. - - - + + + The strings stored in **docaclmeta** by the connector will surface in the _documentAcls_ parameter when the **CheckAccess** method of the custom security trimmer is invoked. The regular document ACLs in the **docacl** property are processed by basic security trimming and are not visible to the custom security trimmer. Similarly, the **docaclmeta** property does not have any effect on basic security trimming. - - - + + + #### Post-trimmers and their effect on refiner count for security trimmers When working with post-trimmers, it is important to notice that there are two types of result tables: **RelevantResults** and the **RefinementResults**. Post-trimmers are applied only to the result hits in the **RelevantResults**. Consequently, there may be refiners related to the post-trimmed hits and the **RefinementResults** count may be larger than or equal to the **RelevantResults**. You can address this behavior in two ways: - - - + + + - Exclude the sensitive refiners from the refinement panel in the default web part so that no information is leaked via the refiners. - - + + - Use a custom web part to display results or refiners when using post-trimmers so that the **RefinementResults** may be elegantly hidden in cases where the **RefinementResults** count exceeds the **RelevantResults** count. - - + + ### Retrieving individual configuration properties for your security trimmer You can access an individual configuration property by using the property name that was specified when the security post-trimmer was registered. For example, the following code retrieves the value for a configuration property named **CheckLimit**. - - - -```cs + + + +```csharp public void Initialize(NameValueCollection staticProperties, SearchServiceApplication searchApplication) { if (staticProperties["CheckLimitProperty"] != null) @@ -211,55 +211,55 @@ public void Initialize(NameValueCollection staticProperties, SearchServiceApplic After you create the custom security trimmer, you must deploy it to the global assembly cache on any server in the Query role. Step 2 in [How to: Use a custom security trimmer for SharePoint Server search results](how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md) describes the process for deploying the custom security trimmer to the global assembly cache. - - - + + + ## Registering the custom security trimmer For post-trimmers, you must associate a custom security trimmer registration with a specific Search service application and crawl rule; for pre-trimmers, this is optional. - - - + + + You use the **SPEnterpriseSearchSecurityTrimmer** cmdlet of the SharePoint Management Shell to register a custom security trimmer. - - - + + + The following table describes the parameters that the cmdlet uses. - - - + + + **Table 1. Parameters used by the SPEnterpriseSearchSecurityTrimmer cmdlet** -|**Parameter**|**Description**| +|Parameter|Description| |:-----|:-----| | _SearchApplication_
|Required. The name of the Search service application, for example "Search Service Application".
| | _typeName_
|Required. The strong name of the custom security trimmer assembly.
| | _RulePath_
|Required for post-trimmers; optional for pre-trimmers. The crawl rule for the security trimmer.
**Note**: We recommend using one crawl rule per content source. | | _id_
|Required. The security trimmer identifier (ID). This value is unique; if a security trimmer is registered with an ID that is already registered for another security trimmer, the registration for the first trimmer is overwritten with the registration for the second trimmer.
| | _properties_
|Optional. The name-value pairs specifying the configuration properties. Must be in the following format: `Name1~Value1~Name2~Value~???`
| - + For an example of a basic command for registering a custom security trimmer and a sample that specifies the configuration properties, see [How to: Use a custom security trimmer for SharePoint Server search results](how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md). - - - + + + ## See also - [How to: Use a custom security trimmer for SharePoint Server search results](how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md) - - + + - [ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) - - + + - [ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) - - + + - [Overview of Business Connectivity Services in SharePoint](https://technet.microsoft.com/library/ee661740.aspx) - - + + diff --git a/docs/general-development/custom-word-breakers-in-sharepoint-server.md b/docs/general-development/custom-word-breakers-in-sharepoint-server.md index 7e2ccff51..c4869dcbb 100644 --- a/docs/general-development/custom-word-breakers-in-sharepoint-server.md +++ b/docs/general-development/custom-word-breakers-in-sharepoint-server.md @@ -1,293 +1,99 @@ --- title: Custom word breakers in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes word breaking in SharePoint and provides steps on how to switch to a custom word breaker in SharePoint. +ms.date: 05/09/2023 ms.assetid: d18b48d4-987c-4228-9932-30d5b30f86a2 -localization_priority: Normal +ms.localizationpriority: medium --- - # Custom word breakers in SharePoint -Learn about word breaking in SharePoint. -Word breaking is one of the key Natural Language Processing (NLP) features that enable search and improve search results (or recall). Word breakers split a stream of text into individual words or tokens on which you can base additional language processing. Word breakers are language-specific. In addition to built-in word breakers, Search in SharePoint enables the use of custom word breakers so that users can tune word breaking behavior according to their needs. See [Supported languages for word breaker customizations in SharePoint](#SP15_SupportedLanguages) for a list languages supported for word breaker customization. - - - -For information on how to write a word breaker refer to the following articles -- [Implementing a Word Breaker](https://msdn.microsoft.com/library/ms693186%28v=vs.85%29.aspx) - - -- [IWordBreaker interface](https://msdn.microsoft.com/library/ms691079%28v=vs.85%29.aspx) - - +Word breaking is one of the key Natural Language Processing (NLP) features that enable search and improve search results (or recall). Word breakers split a stream of text into individual words or tokens on which you can base additional language processing. Word breakers are language-specific. In addition to built-in word breakers, Search in SharePoint enables the use of custom word breakers so that users can tune word breaking behavior according to their needs. See [Supported languages for word breaker customizations in SharePoint](#supported-languages-for-word-breaker-customizations-in-sharepoint) for a list languages supported for word breaker customization. -## How to switch to a custom word breaker in SharePoint - +For information on how to write a word breaker refer to the following articles + +- [Implementing a Word Breaker](https://msdn.microsoft.com/library/ms693186%28v=vs.85%29.aspx) +- [IWordBreaker interface](https://msdn.microsoft.com/library/ms691079%28v=vs.85%29.aspx) +## How to switch to a custom word breaker in SharePoint -> **Caution:** -> When you replace existing word breakers, you modify the registry at your own risk. Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. Microsoft cannot ensure that these problems can be solved. Switching to a different word breaker might also cause serious problems during indexing and querying. Before you modify the registry, back up the registry and ensure that you know how to restore the registry if a problem occurs. - - - +> [!CAUTION] +> When you replace existing word breakers, you modify the registry at your own risk. Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. Microsoft cannot ensure that these problems can be solved. Switching to a different word breaker might also cause serious problems during indexing and querying. Before you modify the registry, back up the registry and ensure that you know how to restore the registry if a problem occurs. Take the following steps to replace the existing word breaker with a custom word breaker or replace the existing word breaker with a word breaker in another language. - - - 1. Open the Registry Editor, as follows: - 1. Choose **Start**, and then choose **Run**. - - -2. In the **Open** dialog box, type **Regedit**, and then choose **OK**. - - -2. In Registry Editor, select the following registry subkey: - +1. In the **Open** dialog box, type **Regedit**, and then choose **OK**. +1. In Registry Editor, select the following registry subkey: + **HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Office Server\\15.0\\Search\\Setup\\ContentIndexCommon\\LanguageResources\\Default\\** _language from the list below_ - - -3. In the right pane, open the shortcut menu for the **WBDLLPathOverride** registry value, and then choose **Modify**. - - -4. In the **Edit String** dialog box, in the **Value data** box, type the path to your custom word breaker DLL, and then choose **OK**. The new DLL should be located in the same path as the existing DLL that is being replaced. - - -5. In the right pane, open the shortcut menu for the **WBreakerClass** registry value, and then choose **Modify**. - - -6. In the **Edit String** dialog box, in the **Value data** box, type the class ID of your custom word breaker, and then choose **OK**. - - -7. Restart the SharePoint Search Host Controller and SharePoint. - - -8. Do a full re-crawl. - - + +1. In the right pane, open the shortcut menu for the **WBDLLPathOverride** registry value, and then choose **Modify**. +1. In the **Edit String** dialog box, in the **Value data** box, type the path to your custom word breaker DLL, and then choose **OK**. The new DLL should be located in the same path as the existing DLL that is being replaced. +1. In the right pane, open the shortcut menu for the **WBreakerClass** registry value, and then choose **Modify**. +1. In the **Edit String** dialog box, in the **Value data** box, type the class ID of your custom word breaker, and then choose **OK** + + Restart the SharePoint Search Host Controller and SharePoint. + +1. Do a full re-crawl. ## Supported languages for word breaker customizations in SharePoint - The following languages are supported for word breaker customization: - - - -Arabic - - - -Bengali - - - -Bulgarian - - - -Catalan - - - -Chinese (People's Republic of China) - - - -Chinese (Taiwan) - - - -Croatian - - - -Czech - - - -Danish - - - -Dutch (Dutch) - - - -English (United States) - - - -Estonian - - - -Finnish - - - -French (Standard) - - - -German (Standard) - - - -Greek - - - -Gujarati - - - -Hebrew - - - -Hindi - - - -Hungarian - - - -Icelandic - - - -Indonesian - - - -Italian (Default) - - - -Japanese - - - -Kannada - - - -Kazakh - - - -Korean - - - -Latvian - - - -Lithuanian - - - -Malay - - - -Malayalam - - - -Marathi - - - -Norwegian - - - -Polish - - - -Portuguese (Portuguese) - - - -Punjabi - - - -Romanian - - - -Russian - - - -Serbian (Cyrillic) - - - -Slovak - - - -Slovenian - - - -Spanish (Modern Sort) - - - -Swedish - - - -Tamil - - - -Telugu - - - -Thai - - - -Turkish - - - -Ukrainian - - - -Urdu - - - -Vietnamese - - - -## See also - +- Arabic +- Bengali +- Bulgarian +- Catalan +- Chinese (People's Republic of China) +- Chinese (Taiwan) +- Croatian +- Czech +- Danish +- Dutch (Dutch) +- English (United States) +- Estonian +- Finnish +- French (Standard) +- German (Standard) +- Greek +- Gujarati +- Hebrew +- Hindi +- Hungarian +- Icelandic +- Indonesian +- Italian (Default) +- Japanese +- Kannada +- Kazakh +- Korean +- Latvian +- Lithuanian +- Malay +- Malayalam +- Marathi +- Norwegian +- Polish +- Portuguese (Portuguese) +- Punjabi +- Romanian +- Russian +- Serbian (Cyrillic) +- Slovak +- Slovenian +- Spanish (Modern Sort) +- Swedish +- Tamil +- Telugu +- Thai +- Ukrainian +- Urdu +- Vietnamese +## See also -- [Configure search in SharePoint](configure-search-in-sharepoint.md) - - -- [Implementing a Word Breaker](https://msdn.microsoft.com/library/ms693186%28v=vs.85%29.aspx) - - -- [IWordBreaker interface](https://msdn.microsoft.com/library/ms691079%28v=vs.85%29.aspx) - - - +- [Configure search in SharePoint](configure-search-in-sharepoint.md) +- [Implementing a Word Breaker](https://msdn.microsoft.com/library/ms693186%28v=vs.85%29.aspx) +- [IWordBreaker interface](https://msdn.microsoft.com/library/ms691079%28v=vs.85%29.aspx) diff --git a/docs/general-development/customizing-ranking-models-to-improve-relevance-in-sharepoint.md b/docs/general-development/customizing-ranking-models-to-improve-relevance-in-sharepoint.md index d68ef23fb..51c54d1a6 100644 --- a/docs/general-development/customizing-ranking-models-to-improve-relevance-in-sharepoint.md +++ b/docs/general-development/customizing-ranking-models-to-improve-relevance-in-sharepoint.md @@ -1,192 +1,115 @@ --- title: Customizing ranking models to improve relevance in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Improve search relevance by customizing ranking models to calculate rank scores (relevance rank) accurately using rank features in SharePoint. +ms.date: 07/15/2022 ms.assetid: c166ecdd-7f93-4bbb-b543-2687992dd2bc -localization_priority: Priority +ms.localizationpriority: high --- +# Customizing ranking models to improve relevance in SharePoint +**APPLIES TO:** ![Applies to SharePoint Server 2013](/sharepoint/sharepointserver/media/yes.png) 2013 ![Applies to SharePoint Server 2016](/sharepoint/sharepointserver/media/yes.png) 2016 ![Applies to SharePoint Server 2019](/sharepoint/sharepointserver/media/yes.png) 2019 ![Does not apply to SharePoint Online](/sharepoint/sharepointserver/media/no.png) SharePoint Online in Microsoft 365 -# Customizing ranking models to improve relevance in SharePoint Improve search relevance by customizing ranking models to calculate rank scores (relevance rank) accurately using rank features in SharePoint. + You can [sort search results in SharePoint](sorting-search-results-in-sharepoint.md) in four ways, one of which is by rank score. When you sort search results by rank score, SharePoint places the most relevant results on top in the search result set. - - - A search result is relevant if it receives a high rank score, which is a specific numeric score calculated by the search engine using a ranking model. A ranking model is a list of one or more rank stages that contain a set of rank features. The ranking model defines how the search engine calculates the relevance rank using various factors, which are represented in the ranking model as rank features. Factors used to calculate the relevance rank include, but are not limited to, the following: - - - - - The appearance of query terms in the full-text index, which includes information such as a document's title and body. - - - The metadata associated with a particular item, such as a document's file type or URL length. - - - The anchor text associated with URL links that point to a particular item. - - - The information about user clicks for each item. - - - The proximity of query terms in a document's body or title. - - ## Start your ranking model customization based on a SharePoint ranking model template - To make your customization easier, start by using one of the default ranking models in SharePoint as a template. Then, modify that ranking model to suit your data set. - - - + SharePoint provides 14 ranking models by default. See [What is a ranking model?](https://technet.microsoft.com/library/7c8ddec1-c8ff-4a90-afae-387b27a653f1.aspx#Ranking_Models) (on TechNet) for detailed information about these ranking models and their purpose. - - - -> **Important:** +> [!IMPORTANT] > If you install the SharePoint cumulative update of August 2013, we recommend using the **Search Ranking Model with Two Linear Stages** as the base model for your custom ranking model. The **Search Ranking Model with Two Linear Stages** is a copy of the **Default Search Model** with a linear second stage instead of a neural network second stage. - - - You use the following Windows PowerShell cmdlets to customize ranking models: - - - - -- [Get-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607990.aspx) - - -- [New-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607980.aspx) - - -- [Remove-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff608045.aspx) - - -- [Set-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607940.aspx) - - -### To list all available ranking models +- [Get-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607990.aspx) +- [New-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607980.aspx) +- [Remove-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff608045.aspx) +- [Set-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607940.aspx) +### To list all available ranking models 1. Open the SharePoint Management Shell as an Administrator. - - -2. Run the following sequence of Windows PowerShell cmdlets. - +1. Run the following sequence of Windows PowerShell cmdlets. + ```powershell - $ssa = Get-SPEnterpriseSearchServiceApplication -Identity "Search Service Application" $owner = Get-SPenterpriseSearchOwner -Level ssa Get-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner ``` - ### To retrieve a default ranking model to use as a template - 1. Open the SharePoint Management Shell as an Administrator. - - -2. Run the following sequence of Windows PowerShell cmdlets; *filename.xml* is the name of a file in which you want to save the ranking model. - +1. Run the following sequence of Windows PowerShell cmdlets; *filename.xml* is the name of a file in which you want to save the ranking model. + ```powershell - $ssa = Get-SPEnterpriseSearchServiceApplication $owner = Get-SPenterpriseSearchOwner -Level ssa $defaultRankingModel = Get-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner | Where-Object { $_.IsDefault -eq $True } $defaultRankingModel.RankingModelXML > filename.xml - ``` If you install the SharePoint cumulative update of August 2013, you can use the following procedure to retrieve the search ranking model with two linear stages to use as a template for your custom ranking model. - - - ### To retrieve the search ranking model with two linear stages to use as a template - 1. Open the SharePoint Management Shell as an Administrator. - - -2. Run the following sequence of Windows PowerShell cmdlets; *filename.xml* is the name of a file in which you want to save the ranking model. - +1. Run the following sequence of Windows PowerShell cmdlets; *filename.xml* is the name of a file in which you want to save the ranking model. + ```powershell - $ssa = Get-SPEnterpriseSearchServiceApplication -$owner = Get-SPenterpriseSearchOwner -Level ssa -$twoLinearStagesRankingModel = Get-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner -Identity 5E9EE87D-4A68-420A-9D58-8913BEEAA6F2 +$owner = Get-SPenterpriseSearchOwner -Level ssa +$twoLinearStagesRankingModel = Get-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner -Identity 5E9EE87D-4A68-420A-9D58-8913BEEAA6F2 $twoLinearStagesRankingModel.RankingModelXML > filename.xml - ``` - ### To deploy a custom ranking model +1. From the list of available ranking models, copy the GUID of the ranking model that you want to use as a template. (See [To list all available ranking models](#to-list-all-available-ranking-models) for the sequence of Windows PowerShell cmdlets to use.) +1. Run the following sequence of Windows PowerShell cmdlets using the GUID copied in step 1 for _\_. -1. From the list of available ranking models, copy the GUID of the ranking model that you want to use as a template. (See [To list all available ranking models](#sp15_list_available_ranking_models) for the sequence of Windows PowerShell cmdlets to use.) - - -2. Run the following sequence of Windows PowerShell cmdlets using the GUID copied in step 1 for __. - -```powershell - -$ssa = Get-SPEnterpriseSearchServiceApplication -$owner = Get-SPenterpriseSearchOwner -Level ssa -$rm = Get-SPEnterpriseSearchRankingModel -Identity -SearchApplication $ssa -Owner $owner -$rm.RankingModelXML > myrm.xml + ```powershell + $ssa = Get-SPEnterpriseSearchServiceApplication + $owner = Get-SPenterpriseSearchOwner -Level ssa + $rm = Get-SPEnterpriseSearchRankingModel -Identity -SearchApplication $ssa -Owner $owner + $rm.RankingModelXML > myrm.xml + ``` -``` - -3. Edit the `myrm.xml` file in an XML editor. You must use new GUID values for the **id** attributes in _RankModel2Stage_ element and all _RankingModel2NN_ elements. To get a new GUID value you can for example use the following Windows PowerShell command: `[guid]::NewGuid()` - - -4. Create a new ranking model with the [New-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607980.aspx) cmdlet by running the following commands. - -```powershell - -$myRankingModel = Get-Content .\\myrm.xml -$myRankingModel = [String]$myRankingModel -$ssa = Get-SPEnterpriseSearchServiceApplication -$owner = Get-SPenterpriseSearchOwner -Level ssa -$newrm = New-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner -RankingModelXML $myRankingModel -``` +1. Edit the `myrm.xml` file in an XML editor. You must use new GUID values for the **id** attributes in _RankModel2Stage_ element and all _RankingModel2NN_ elements. To get a new GUID value you can for example use the following Windows PowerShell command: `[guid]::NewGuid()` +1. Create a new ranking model with the [New-SPEnterpriseSearchRankingModel](https://technet.microsoft.com/library/ff607980.aspx) cmdlet by running the following commands. + ```powershell + $myRankingModel = Get-Content .\\myrm.xml + $myRankingModel = [String]$myRankingModel + $ssa = Get-SPEnterpriseSearchServiceApplication + $owner = Get-SPenterpriseSearchOwner -Level ssa + $newrm = New-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner -RankingModelXML $myRankingModel + ``` ### Rank detail +> [!IMPORTANT] +> We provide the rank detail and the accompanying ExplainRank page as a convenience and only to assist you in tuning and debugging your own custom ranking models. The contents of the rank detail and the accompanying ExplainRank page are not supported, and are subject to change without notice in future software patches and updates. -> **Important:** -> We provide the rank detail and the accompanying ExplainRank page as a convenience and only to assist you in tuning and debugging your own custom ranking models. The contents of the rank detail and the accompanying ExplainRank page are not supported, and are subject to change without notice in future software patches and updates. - - - +The rank detail is an XML document that provides detailed information about rank score calculation for a single item that matches a given user query. The rank detail is stored in a special managed property, called **rankdetail**. -The rank detail is an XML document that provides detailed information about rank score calculation for a single item that matches a given user query. The rank detail is stored in a special managed property, called **rankdetail**. - - - Each rank feature in a ranking model has a separate XML node in the rank detail that describes details of the rank score calculation. The rank detail is provided only for queries that have search results that don't exceed 100 items. - - - -Conceptually, the overall format of the rank detail looks like the following example. - - - - +Conceptually, the overall format of the rank detail looks like the following example. ```xml - @@ -205,155 +128,76 @@ Conceptually, the overall format of the rank detail looks like the following exa ``` To retrieve the rank detail, you need to be the administrator of the Search service application (SSA). - - - ### To retrieve the rank detail - 1. Open the SharePoint Management Shell as an Administrator. - - -2. Run the following sequence of Windows PowerShell cmdlets, and substitute __ and __ with actual values. - +1. Run the following sequence of Windows PowerShell cmdlets, and substitute _\_ and _\_ with actual values. + ```powershell - $app = Get-SPEnterpriseSearchServiceApplication $searchAppProxy = Get-spenterprisesearchserviceapplicationproxy | Where-Object { ($_.ServiceEndpointUri.PathAndQuery -like $app.Uri.PathAndQuery)} $request = New-Object Microsoft.Office.Server.Search.Query.KeywordQuery($searchAppProxy) $request.ResultTypes = [Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults $request.QueryText = " AND path:""""" $request.SelectProperties.Add("rankdetail") -$searchexecutor = new-Object Microsoft.Office.Server.Search.Query.SearchExecutor -$resultTables = $searchexecutor.ExecuteQuery($request) +$searchexecutor = new-Object Microsoft.Office.Server.Search.Query.SearchExecutor +$resultTables = $searchexecutor.ExecuteQuery($request) $resultTables[([Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults)].Table - ``` - ### Understanding the rank score calculation via the ExplainRank page SharePoint provides the **ExplainRank** page that is located in the layouts folder ( `/_layouts/15/`). This page contains detailed information on the rank score for each rank feature based on a given search query, a document ID, and an optional ranking model ID. The information is obtained and parsed from the rank detail. - - - -You can access the **ExplainRank** page with the following URL: - - - - `http:///_layouts/15/ExplainRank.aspx?q={x}&d={y}&rm={z}` - - - + +You can access the **ExplainRank** page with the following URL: **http://\/_layouts/15/ExplainRank.aspx?q={x}&d={y}&rm={z}** + Where: - - - - -- *x* is the search query. - - -- *y* is the document ID. - - -- *z* is the optional ranking model ID. If no ranking model ID is provided, the default ranking model is used. - - + +- *x* is the search query. +- *y* is the document ID. +- *z* is the optional ranking model ID. If no ranking model ID is provided, the default ranking model is used. + Just like with the rank detail, to view the **ExplainRank** page, you need to be the administrator of the Search service application (SSA). - - - ## Tune your ranking model with rank features - Rank features work like tuning dials for a ranking model. The following sections describe the rank features that are available in the default SharePoint ranking model and how they contribute to relevance rank calculation. - - - ### BM25 The BM25 rank feature ranks items based on the appearance of query terms in the full-text index. The input to BM25 can be any of the managed properties in the full-text index. - + > [!NOTE] -> The BM25 rank feature used in this context is the fielded version, BM25F. - - - +> The BM25 rank feature used in this context is the fielded version, BM25F. The BM25 rank feature calculates the relevance rank score using the following formula. - - - - - - ![BM25 formula for the BM25 rank feature](../images/sp15_BM25_formula.gif) - - - + Where: - - - - -- _D_ is a document, represented as a list of textual fields such as the title or body. - - -- _Q_ is the user query, represented as a list of query terms, _t_. - - -- _S_ defines the list of fields that contribute to relevance ranking; this list is defined by the ranking model. - - -- _w_f is a numeric value that defines the relative weight of the field _f_ ??? _S_; this value is defined by the ranking model. - - -- _b_f is a numeric value that defines the document length normalization for each field _f_ ??? _S_. - - -- _TF_f _(t,D)_ is the number of occurrences of query term _t_ in the field _f_ of document _D_. - - -- _DL_f _(D)_ is the total number of words in field _f_ of document _D_. - - -- _N_ is the total amount of documents in the index. - - -- _n_t is an amount of documents that have term _t_ in at least one of their properties. - - -- _AVDL_f is the average _DL_f _(D)_ across all indexed documents. - - -- _k_1 is a scalar parameter; this value is defined by the ranking model. - - + +- _D_ is a document, represented as a list of textual fields such as the title or body. +- _Q_ is the user query, represented as a list of query terms, _t_. +- _S_ defines the list of fields that contribute to relevance ranking; this list is defined by the ranking model. +- _w_f is a numeric value that defines the relative weight of the field _f_ ??? _S_; this value is defined by the ranking model. +- _b_f is a numeric value that defines the document length normalization for each field _f_ ??? _S_. +- _TF_f _(t,D)_ is the number of occurrences of query term _t_ in the field _f_ of document _D_. +- _DL_f _(D)_ is the total number of words in field _f_ of document _D_. +- _N_ is the total amount of documents in the index. +- _n_t is an amount of documents that have term _t_ in at least one of their properties. +- _AVDL_f is the average _DL_f _(D)_ across all indexed documents. +- _k_1 is a scalar parameter; this value is defined by the ranking model. + You must map the managed properties used for the BM25 rank feature to the default full-text index in the **Choose advanced searchable settings** UI. - - - -Within a user query, query terms that are part of the following operators are excluded from relevance rank calculations: `NOT(???)` in FQL, `NOT(???)` in KQL, and `FILTER(???)` in FQL. - - - -In addition, query terms that are under scope, for example, `title:apple AND body:orange`, are excluded from relevance rank calculations. - - - - **Example BM25 rank feature definition** - - - +Within a user query, query terms that are part of the following operators are excluded from relevance rank calculations: `NOT(???)` in FQL, `NOT(???)` in KQL, and `FILTER(???)` in FQL. +In addition, query terms that are under scope, for example, `title:apple AND body:orange`, are excluded from relevance rank calculations. -```xml +#### Example BM25 rank feature definition +```xml 0.26236235707678 @@ -370,15 +214,9 @@ In addition, query terms that are under scope, for example, `title:apple AND bo ``` - **Example rank detail for BM25 rank feature** - - - - - +#### Example rank detail for BM25 rank feature ```xml - @@ -415,98 +253,55 @@ In addition, query terms that are under scope, for example, `title:apple AND bo - ``` - #### Weight groups In a custom ranking model, you can have two or more managed properties that are mapped to the same weight group in the search schema. In such cases, content of these managed properties is combined in the full-text index and can't be ranked separately in BM25 calculation. This effect is the same as setting equal values for the _w_f and _b_f parameters within each group of managed properties, mapped to the same weight group in the search schema. To prevent this, map managed properties to one of the 16 different weight groups available in the search schema. - - - + Weight groups are also known as context. See [Influencing the ranking of search results by using the search schema](https://technet.microsoft.com/library/7c8ddec1-c8ff-4a90-afae-387b27a653f1.aspx#Ranking_Schema) (on TechNet) for more information about the relationship between a managed property and its context. - - - ### Static -The static rank feature ranks items based on numeric managed properties that are stored in the search index. The numeric managed properties used for relevance rank calculation in static rank features must be of type [Integer](https://docs.microsoft.com/dotnet/api/system.int32) and set to [Refinable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Refinable.aspx) or [Sortable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Sortable.aspx) in the search schema. You can't use multivalued managed properties in combination with the static rank feature. - - - +The static rank feature ranks items based on numeric managed properties that are stored in the search index. The numeric managed properties used for relevance rank calculation in static rank features must be of type [Integer](/dotnet/api/system.int32) and set to [Refinable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Refinable.aspx) or [Sortable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Sortable.aspx) in the search schema. You can't use multivalued managed properties in combination with the static rank feature. + Before the static rank feature can be aggregated with other rank features, each static rank feature is preprocessed via a single transformation. Table 1 lists all supported transform functions. - - - **Table 1. Supported transform functions for the static and proximity rank features** - - ![Transform functions supported for rank features](../images/sp15_transform_table_ranking_model.gif) - - - - **Example static rank feature definition** - - - - +#### Example static rank feature definition ```xml - 0.616326852981262 - ``` - **Example rank detail for a static rank feature** - - - - - +#### Example rank detail for a static rank feature ```xml - - ``` - ### Bucketed static The bucketed static rank feature ranks documents based on their file type and language. The definition of a bucketed static rank feature within a ranking model depends on whether the rank feature is part of a linear model or a neural network. The following examples apply only to linear models. For neural networks, the number of `` attributes for each bucket must match the number of hidden nodes in the neural network. - - - -The managed properties used for relevance rank calculation in bucketed static rank features must be of type [Integer](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/int) and set to [Refinable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Refinable.aspx) or [Sortable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Sortable.aspx) in the search schema. You can't use multivalued managed properties in combination with the bucketed static rank feature. - - - - **Example bucketed static rank feature definition for file type** - - - -Every document has an associated file type that the content processing component detects and stores in the search index as a zero-based integer value. When you use the bucketed static rank feature to rank documents based on their file types, each document type is associated with a specific relevance rank score. For example, in the following definition, the bucket **2** corresponds to a .ppt document; the node `0.680984743282165` defines additional rank points that are added to the relevance rank scores for all .ppt documents. - - - +The managed properties used for relevance rank calculation in bucketed static rank features must be of type [Integer](/dotnet/csharp/language-reference/keywords/int) and set to [Refinable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Refinable.aspx) or [Sortable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Sortable.aspx) in the search schema. You can't use multivalued managed properties in combination with the bucketed static rank feature. +#### Example bucketed static rank feature definition for file type -```xml +Every document has an associated file type that the content processing component detects and stores in the search index as a zero-based integer value. When you use the bucketed static rank feature to rank documents based on their file types, each document type is associated with a specific relevance rank score. For example, in the following definition, the bucket **2** corresponds to a .ppt document; the node `0.680984743282165` defines additional rank points that are added to the relevance rank scores for all .ppt documents. +```xml @@ -556,32 +351,19 @@ Every document has an associated file type that the content processing component ``` - **Example bucketed static rank feature definition for document language** - - - +#### Example bucketed static rank feature definition for document language + The content processing component detects the language for each document automatically before it's added to the search index. When you use the bucketed static rank feature to rank documents based on their language, you can define how to calculate the rank score based on whether the document's language that was automatically detected matches the query's language. - - - -At query time, information about the user's language is written to the search engine as a query property. - - - + +At query time, information about the user's language is written to the search engine as a query property. ### Proximity The proximity rank feature ranks items depending on the distance between query terms inside the full-text index. The rank score is boosted if two query terms appear in the same managed properties within the full-text index. Proximity calculations are expensive in terms of disk activity and CPU consumption; as a result, proximity boost is carried out only during the second stage of the default SharePoint rank model (if available). - - - -You can evaluate the proximity rank feature by using several different options, controlled by attributes described in Table 2. - - - -**Table 2. Attributes that control evaluation of proximity rank features** +You can evaluate the proximity rank feature by using several different options, controlled by attributes described in Table 2. +#### Table 2. Attributes that control evaluation of proximity rank features |**Attributes**|**Description**| |:-----|:-----| @@ -591,20 +373,12 @@ You can evaluate the proximity rank feature by using several different options, | `proximity="complete"`
|In this mode, the proximity rank feature only boosts documents where the whole user query text occurs within a specific managed property.
| | `proximity="perfect"`
|This mode is similar to `complete` mode, but is applied to short fields, such as **title**. The proximity rank feature only boosts documents where the whole user query text matches an exact **title** within a specific managed property. If the **title** contains additional terms outside of the user query, the item isn't considered by the proximity algorithm.
| | `default`
|This attribute applies only to single-term queries. For items that contain the query term, the `default` value is used as the rank score output by the proximity rank feature.
The `perfect` proximity is an exception to this rule. For `perfect` proximity, the default value is never used. Instead, single-term queries are processed in the same way as other queries.
| - - **Example proximity rank feature definition** - - - -The following example is an excerpt from the default SharePoint rank model. In this model, the proximity feature is only part of the second stage calculation, which involves a neural network. Therefore, the example contains multiple weight elements, ``, which correspond to the number of neurons in the hidden layer of the neural network. - - - +#### Example proximity rank feature definition +The following example is an excerpt from the default SharePoint rank model. In this model, the proximity feature is only part of the second stage calculation, which involves a neural network. Therefore, the example contains multiple weight elements, ``, which correspond to the number of neurons in the hidden layer of the neural network. ```xml - @@ -617,50 +391,30 @@ The following example is an excerpt from the default SharePoint rank model. In t 0.102859503886488 - ``` -You must map the managed properties used in proximity rank features to the default full-text index in search schema. - - - - **Example rank detail for proximity rank feature** - - - - +You must map the managed properties used in proximity rank features to the default full-text index in search schema. +#### Example rank detail for proximity rank feature ```xml - - ``` - ### Dynamic The dynamic rank feature ranks an item depending on whether the query property matches a given managed property. If there is a match, the item's rank score is multiplied with a specific value to distinguish that particular item. The weight attribute is used to control how much this feature affects the overall rank score. - -> [!NOTE] -> The dynamic rank feature is not customizable; it's for internal use only. However, if you install the SharePoint cumulative update of August 2013, the AnchortextComplete rank feature is a customizable dynamic rank feature that is part of the default ranking model. - - - - - **Example dynamic rank feature definition** - - - +> [!NOTE] +> The dynamic rank feature is not customizable; it's for internal use only. However, if you install the SharePoint cumulative update of August 2013, the AnchortextComplete rank feature is a customizable dynamic rank feature that is part of the default ranking model. +#### Example dynamic rank feature definition ```xml - @@ -669,48 +423,23 @@ The dynamic rank feature ranks an item depending on whether the query property m ``` - ### Freshness The default SharePoint ranking model doesn't boost the rank of search results based on their freshness. You can achieve this by adding a new static rank feature that combines information from the **LastModifiedTime** managed property with the **DateTimeUtcNow** query property, using the freshness transform function. The freshness transform function is the only transform that you can use for this freshness rank feature, because it converts the age of the item from an internal representation into days. - - - + The freshness transform is based on the following formula: - - - - - - ![Freshness formula for ranking models](../images/sp15_freshness_formula.gif) - - - + Where: - - - - -- _c_ and _y_future are defined in the ranking model. - - -- _x_ is the age of an item in days. - - -- The value of _y_future defines the freshness boost for items that have **LastModifiedTime** greater than the current date and time. - - - **Example freshness rank feature definition** - - - +- _c_ and _y_future are defined in the ranking model. +- _x_ is the age of an item in days. +- The value of _y_future defines the freshness boost for items that have **LastModifiedTime** greater than the current date and time. +#### Example freshness rank feature definition ```xml - @@ -719,219 +448,89 @@ Where: ``` - **Example rank detail for freshness rank feature using an old document (approximately 580 days old)** - - - - - +#### Example rank detail for freshness rank feature using an old document (approximately 580 days old) ```xml - - ``` - **Example rank detail for freshness rank feature using a new document (<1 day old)** - - - - - +#### Example rank detail for freshness rank feature using a new document (<1 day old) ```xml - - ``` - ## Aggregation of rank features - A ranking model consists of various rank features that are considered together to calculate a rank score. - - - ### Two-stage ranking models A ranking model can have two rank stages. In the first stage, the ranking model applies relatively inexpensive rank features to get a gross ranking of the results. In the second stage, the ranking model applies additional and more expensive rank features to the items with the highest rank scores. - - - + The SharePoint default ranking model is an example of two-stage ranking model. In this model, the second stage works with the top 1000 items with the highest rank score that result from the first stage. - - - + When the ranking process in the first stage is complete, the search engine re-sorts all of the items, including the items that were excluded from the second stage. This usually results in items from the second stage having a lower rank score when compared to items in the first stage. - - - + However, to ensure that the search engine re-sorts the items accurately, items from the second stage must have a higher rank score than items from the first stage. To solve this dilemma, the rank scores of the second stage are boosted. The search engine performs this calculation automatically, based on a combination of rank features. - + > [!NOTE] > If you install the SharePoint cumulative update of August 2013, the default ranking model uses a linear first stage and a neural network second stage. **The Search Ranking Model with Two Linear Stages** is a copy of the **Default Search Model** with two linear stages. We recommend using this model as the base model for your custom ranking model because it is easier to tune a linear model than a model containing a neural network. - - - - #### Linear model The liner model defines a linear combination of rank scores from rank features. - - - + The rank score provided by linear models is computed using the following formula: - - - - - - ![Linear model formula for ranking models](../images/sp15_linear_model_formula.gif) - - - - - - - - - - Where: - - - - -- _score_ is the output rank score produced by the linear model. - - -- _M_ is the number of rank features excluding bucketed static rank features. - - -- _K_ is the number of bucketed static rank features. - - -- _f_j is the value of _j_th feature after transformation. - - -- _w_j is the contribution weight of _j_th feature to the linear combination. - - + +- _score_ is the output rank score produced by the linear model. +- _M_ is the number of rank features excluding bucketed static rank features. +- _K_ is the number of bucketed static rank features. +- _f_j is the value of _j_th feature after transformation. +- _w_j is the contribution weight of _j_th feature to the linear combination. #### Neural network The neural network defines a nonlinear combination of rank scores from rank features. Currently, SharePoint supports neural networks that are limited to one hidden layer with up to eight neurons. - - - + The ranking score produced by a neural network is computed using the following formula: - - - - - - ![Neural network formula for ranking models](../images/sp15_neural_network_formula.gif) - - - - - - - - - - Where: - - - - -- _score_ is the output rank score produced by the neural network. - - -- _N_ is the number of neurons in the hidden layer of the neural network. - - -- _M_ is the number of rank features, excluding bucketed static rank features. - - -- _K_ is the number of bucketed static rank features. - - -- _W_i is the contribution weight of _i_th hidden neuron. - - -- _t_i is the threshold of _i_th hidden neuron. - - -- _W_i,j is the contribution weight of _j_th feature to _i_th hidden neuron. - - -- _b_i,k is the addition from the _k_th bucketed static feature to _i_th hidden neuron. - - -The overall schema of rank score computation with a two-layer neural network is represented in the following diagram. This diagram doesn't consider the bucketed static rank feature that contributes to neural networks by adding custom values directly into hidden nodes, without any transformation or normalization. - - - -**Figure 1. Overall schema of rank score computation with a two-layer neural network** +- _score_ is the output rank score produced by the neural network. +- _N_ is the number of neurons in the hidden layer of the neural network. +- _M_ is the number of rank features, excluding bucketed static rank features. +- _K_ is the number of bucketed static rank features. +- _W_i is the contribution weight of _i_th hidden neuron. +- _t_i is the threshold of _i_th hidden neuron. +- _W_i,j is the contribution weight of _j_th feature to _i_th hidden neuron. +- _b_i,k is the addition from the _k_th bucketed static feature to _i_th hidden neuron. - - - - - - - -![Neural network in ranking models](../images/sp15neuralnetworkinrankingmodels.gif) - - - +The overall schema of rank score computation with a two-layer neural network is represented in the following diagram. This diagram doesn't consider the bucketed static rank feature that contributes to neural networks by adding custom values directly into hidden nodes, without any transformation or normalization. - - - +#### Figure 1. Overall schema of rank score computation with a two-layer neural network - - - +![Neural network in ranking models](../images/sp15neuralnetworkinrankingmodels.gif) ## Precalculation in BM25 and static rank features - In a ranking model, BM25 and static rank features can benefit from precalculations to improve query latency for query terms that frequently occur in items. This query latency improvement is achieved with the cost of additional indexing, both in terms of disk space used by the search index and CPU consumption. - - - + You should use precalculation only in the first stage of a ranking model. Consequently, if precalculation is enabled, the rank detail of the first stage will not be complete. - - - -To enable precalculation, set the `precalcEnabled` attribute to **1** in the rank stage definition. You can only use precalculation once in a ranking model. - - - + +To enable precalculation, set the `precalcEnabled` attribute to **1** in the rank stage definition. You can only use precalculation once in a ranking model. ## Query properties - Query properties is a ranking mechanism that populates additional information useful for rank score calculation. For example, query properties can be the time and date when the query was run, which can be used by the freshness rank feature. Table 3 lists the query properties available for ranking. You can't configure query properties. - - - - -**Table 3. Query properties for ranking** +### Table 3. Query properties for ranking |**Query property**|**Description**| |:-----|:-----| @@ -940,18 +539,12 @@ Query properties is a ranking mechanism that populates additional information us |DetectedLanguageRanking
|ID of the query language. This query property is used by the **DetectedLanguageRanking** rank feature.
| |PersonalizationData
|Ranks personalized data.
| |RecommendedforQueryProperty
|Ranks recommendations.
| - ## Example 1: Basic ranking model with one linear stage containing a single static rank feature - -This ranking model assumes that the customer has created a managed property named **CustomRating**. The static rank feature requires **CustomRating** to be of [Integer](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/int) data type and to be configured as [Sortable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Sortable.aspx) or [Refinable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Refinable.aspx) in the search schema. For each document in the result set, the rank score produced by this ranking model is equal to the value of **CustomRating** for that document. The effect of this model is similar to sorting all search results, descending, with the **CustomRating** managed property. - - - +This ranking model assumes that the customer has created a managed property named **CustomRating**. The static rank feature requires **CustomRating** to be of [Integer](/dotnet/csharp/language-reference/keywords/int) data type and to be configured as [Sortable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Sortable.aspx) or [Refinable](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Administration.ManagedProperty.Refinable.aspx) in the search schema. For each document in the result set, the rank score produced by this ranking model is equal to the value of **CustomRating** for that document. The effect of this model is similar to sorting all search results, descending, with the **CustomRating** managed property. ```xml - ``` - ## Example 2: More complex ranking model with one linear stage and four rank features - - -This ranking model with one linear stage contains these four rank features: - - - - -- `BM25` This rank feature is based on managed properties **Title** and **body**; the `w` attribute for **title** is set so that hits of query terms in **Title** are two times (2x) more important than hits of query terms in **body**. - - -- `UrlDepth` This rank feature is based on the **UrlDepth** managed property, which is available by default in SharePoint installations. **UrlDepth** contains the number of backslashes (\\) in the URL of a document. The inverse rational ( `InvRational`) transform ensures that documents with shorter URLs receive higher rank scores. - - -- `TitleProximity` This rank feature boosts documents if some of the query terms occur close to each other in the **title** of these documents. - - -- `InternalFileType` This rank feature boosts documents of type HTML, DOC, XLS, or PPT. The names of the buckets in the definition of the rank model are provided for readability only. - + +This ranking model with one linear stage contains these four rank features: + +- `BM25` This rank feature is based on managed properties **Title** and **body**; the `w` attribute for **title** is set so that hits of query terms in **Title** are two times (2x) more important than hits of query terms in **body**. +- `UrlDepth` This rank feature is based on the **UrlDepth** managed property, which is available by default in SharePoint installations. **UrlDepth** contains the number of backslashes (\\) in the URL of a document. The inverse rational ( `InvRational`) transform ensures that documents with shorter URLs receive higher rank scores. +- `TitleProximity` This rank feature boosts documents if some of the query terms occur close to each other in the **title** of these documents. +- `InternalFileType` This rank feature boosts documents of type HTML, DOC, XLS, or PPT. The names of the buckets in the definition of the rank model are provided for readability only. + > [!NOTE] > The `InternalFileType` managed property, available by default, uses the value zero ( `0`) to encode HTML documents, value `1` for DOC, value `2` for XLS and so on. See the definition of the Default SharePoint rank model for a list of all file types used for the **FileType** managed property. ```xml - - ``` - ## See also - - - -- [Search in SharePoint](search-in-sharepoint.md) - - -- [Keyword Query Language (KQL) syntax reference](keyword-query-language-kql-syntax-reference.md) - - -- [FAST Query Language (FQL) syntax reference](fast-query-language-fql-syntax-reference.md) - - -- [Overview of search result ranking in SharePoint](https://technet.microsoft.com/library/7c8ddec1-c8ff-4a90-afae-387b27a653f1.aspx) - - -- [Create a custom ranking model by using the Ranking Model Tuning App](https://docs.microsoft.com/sharepoint/search/create-custom-ranking-model) - - - - - - +- [Search in SharePoint](search-in-sharepoint.md) +- [Keyword Query Language (KQL) syntax reference](keyword-query-language-kql-syntax-reference.md) +- [FAST Query Language (FQL) syntax reference](fast-query-language-fql-syntax-reference.md) +- [Overview of search result ranking in SharePoint](https://technet.microsoft.com/library/7c8ddec1-c8ff-4a90-afae-387b27a653f1.aspx) +- [Create a custom ranking model by using the Ranking Model Tuning App](/sharepoint/search/create-custom-ranking-model) diff --git a/docs/general-development/customizing-search-results-in-sharepoint.md b/docs/general-development/customizing-search-results-in-sharepoint.md index 200602632..9fcec7243 100644 --- a/docs/general-development/customizing-search-results-in-sharepoint.md +++ b/docs/general-development/customizing-search-results-in-sharepoint.md @@ -1,150 +1,91 @@ --- title: Customizing search results in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to group similar items or remove duplicate items in a search result set in SharePoint so you can display these results in a concise, readable way. +ms.date: 06/09/2022 ms.assetid: 1b30f6df-643a-4570-ae5c-d3d8df5609b8 -localization_priority: Priority +ms.localizationpriority: high --- - - # Customizing search results in SharePoint + Learn how to group similar items or remove duplicate items in a search result set in SharePoint so you can display these results in a concise, readable way. + In search results, grouping collapses two or more similar items in a search result set to make their display more readable for a user. Duplicate removal of search results is a part of grouping, where items that are identical or nearly identical are removed from the result set. Depending on the settings set by the SharePoint administrator, the user might be able to expand the search result set later and see the individual results that were collapsed. - - - The following are examples of ways to group search results: + - Duplicate detection, where nearly identical documents are removed from the result set. - - - Site collapsing, where only the most relevant item found in each site is shown in the result set. - - - Document set collapsing, where only one hit is displayed for each document library in SharePoint. - - + You can specify the criteria for collapsing or duplicate trimming programmatically by using the following [KeywordQuery](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.aspx) properties within the Query object model: -- [CollapseSpecification](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.CollapseSpecification.aspx) - - -- [TrimDuplicates](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.Query.TrimDuplicates.aspx) - - -- [TrimDuplicatesOnProperty](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.TrimDuplicatesOnProperty.aspx) - - -- [TrimDuplicatesKeepCount](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.TrimDuplicatesKeepCount.aspx) - - -- [TrimDuplicatesIncludeId](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.TrimDuplicatesIncludeId.aspx) - - + +- [CollapseSpecification](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.CollapseSpecification.aspx) +- [TrimDuplicates](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.Query.TrimDuplicates.aspx) +- [TrimDuplicatesOnProperty](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.TrimDuplicatesOnProperty.aspx) +- [TrimDuplicatesKeepCount](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.TrimDuplicatesKeepCount.aspx) +- [TrimDuplicatesIncludeId](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.TrimDuplicatesIncludeId.aspx) ## Collapse similar search results using the CollapseSpecification property - The **CollapseSpecification** property takes a _Spec_ parameter that can contain multiple fields separated either by a comma or a space, which evaluated together specify a set of criteria used for collapsing. - - - - **Syntax** - - - - `CollapseSpecification = Spec` - - - + +**Syntax** +`CollapseSpecification = Spec` + The following table lists the fields of the _Spec_ parameter. - - - **Table 1. Spec parameter fields** - -|**Element in parameter**|**Description**| +|Element in parameter|Description| |:-----|:-----| -| _Spec_
| `Subspec(Subspec)*`
| -| _Subspec_
| `Prop(','Prop)*[':'Dups]`
| -| _Prop_
|A valid managed property or an alias of a managed property. _Prop_ is case-insensitive. The managed property must be queryable and either sortable or refineable.
| -| _Dups_
|An integer specifying the number of items to retain. The default value is 1.
| -| __
|Properties are combined by using the **OR** operator.
| -| _,_
|Properties are combined by using the **AND** operator.
| -| _*_
|Indicates more items.
| -| _() or []_
|Indicates optional items.
| - +| _Spec_| `Subspec(Subspec)*`| +| _Subspec_| `Prop(','Prop)*[':'Dups]`| +| _Prop_|A valid managed property or an alias of a managed property. _Prop_ is case-insensitive. The managed property must be queryable and either sortable or refineable.| +| _Dups_|An integer specifying the number of items to retain. The default value is 1. | +| _\_|Properties are combined by using the **OR** operator.| +| _,_|Properties are combined by using the **AND** operator.| +| _*_|Indicates more items. | +| _() or []_|Indicates optional items. | + If the fields in _Spec_ are separated by commas, the fields are combined by using the **AND** operator. If all of the specified fields are matched, the items are collapsed. - - - + In contrast, if the fields in _Spec_ are separated by spaces, the fields (or _Subspecs_) are combined by using an expansion that includes both the **AND** operator and **OR** operator. For example, an expression such as `Category:3 Product:2` is internally transformed to the following expression `(Category AND Product) OR (Category)` with a counter for each; hence a maximum of two of the former and three of the latter. Items are collapsed if some of the specified fields are matched. - - - ### Examples of using CollapseSpecification The following table shows a product catalog from the Contoso company. The next set of examples use this catalog to show how the **CollapseSpecification** property works. - - - - -|**Category**|**Product**|**Variant**|**Title**| +|Category|Product|Variant|Title| |:-----|:-----|:-----|:-----| -|Laptops
|WWI
|19W X0196 Black
|Computer 1
| -|Laptops
|Adventure Works
|12 M1201 Red
|Computer 2
| -|Laptops
|Adventure Works
|15.4W M1548 White
|Computer 3
| -|Laptops
|Proseware
|19 X910 Black
|Computer 4
| -|Laptops
|Proseware
|Laptop19 X910 Black
|Computer 5
| -|Desktops
|Adventure Works
|2.33 XD233 Silver
|Computer 6
| -|Desktops
|WWI
|2.33 X2330 Black
|Computer 7
| -|Desktops
|Adventure Works
|1.60 ED160 White
|Computer 8
| -|Desktops
|WWI
|3.0 M0300 Silver
|Computer 9
| - - - - - +|Laptops |WWI |19W X0196 Black |Computer 1 | +|Laptops |Adventure Works |12 M1201 Red |Computer 2 | +|Laptops |Adventure Works |15.4W M1548 White |Computer 3 | +|Laptops |Proseware |19 X910 Black |Computer 4 | +|Laptops |Proseware |Laptop19 X910 Black |Computer 5 | +|Desktops |Adventure Works |2.33 XD233 Silver |Computer 6 | +|Desktops |WWI |2.33 X2330 Black |Computer 7 | +|Desktops |Adventure Works |1.60 ED160 White |Computer 8 | +|Desktops |WWI |3.0 M0300 Silver |Computer 9 | #### Example: group by Category First, group the items based on **Category** and show the top two (hence `"Category:2"`) for each group. Then, for each **Category**, show a corresponding number of unique (hence "Product:1") **Products**. - - - - **Syntax** - - - - `CollapseSpecification="Category:2 Product:1"` - - - -This should return the following results. - - - +**Syntax** +`CollapseSpecification="Category:2 Product:1"` -|**Category**|**Product**|**Variant**|**Title**| -|:-----|:-----|:-----|:-----| -|Laptops
|WWI
|19W X0196 Black
|Computer 1
| -|Laptops
|Adventure
|12 M1201 Red
|Computer 2
| -|Desktops
|Adventure Works
|2.33 XD233 Silver
|Computer 6
| -|Desktops
|WWI
|2.33 X2330 Black
|Computer 7
| - -Use the following code to collapse the search results by using the **CollapseSpecification** property. - - - - +This should return the following results. +|Category|Product|Variant|Title| +|:-----|:-----|:-----|:-----| +|Laptops |WWI |19W X0196 Black |Computer 1 | +|Laptops |Adventure |12 M1201 Red |Computer 2 | +|Desktops |Adventure Works |2.33 XD233 Silver |Computer 6 | +|Desktops |WWI |2.33 X2330 Black |Computer 7 | -```cs +Use the following code to collapse the search results by using the **CollapseSpecification** property. +```csharp using (var context = new ClientContext("http://localhost")) { var query = new KeywordQuery(context) @@ -163,131 +104,64 @@ using (var context = new ClientContext("http://localhost")) Console.WriteLine(result["Title"]); } } - ``` - #### Example: group by Category and Product First, group the items based on both **Category** and **Product**. Then, show each unique combination. - - - - **Syntax** - - - - `CollapseSpecification="Category,Product:1"` - - - -This should return the following results. - - - +**Syntax** +`CollapseSpecification="Category,Product:1"` + +This should return the following results. -|**Category**|**Product**|**Variant**|**Title**| +|Category|Product|Variant|Title| |:-----|:-----|:-----|:-----| -|Laptops
|WWI
|19W X0196 Black
|Computer 1
| -|Laptops
|Adventure Works
|12 M1201 Red
|Computer 2
| -|Laptops
|Proseware
|19 X910 Black
|Computer 4
| -|Desktops
|Adventure Works
|2.33 XD233 Silver
|Computer 6
| -|Desktops
|WWI
|2.33 X2330 Black
|Computer 7
| - +|Laptops |WWI |19W X0196 Black |Computer 1 | +|Laptops |Adventure Works |12 M1201 Red |Computer 2 | +|Laptops |Proseware |19 X910 Black |Computer 4 | +|Desktops |Adventure Works |2.33 XD233 Silver |Computer 6 | +|Desktops |WWI |2.33 X2330 Black |Computer 7 | ## Trim duplicate search results using the TrimDuplicates property - Use **TrimDuplicates** to specify whether to trim away the duplicate search results from the result set. **TrimDuplicates** is **true** by default. - - - + If you use **TrimDuplicates** with either **TrimDuplicatesOnProperty** or preferably **CollapseSpecification**, **TrimDuplicates** is set to **false**. - - - - **Syntax** - - - - `TrimDuplicates = <$true | $false>` - - - + +**Syntax** +`TrimDuplicates = <$true | $false>` ### Trim duplicate search results using the TrimDuplicatesOnProperty property - Use **TrimDuplicatesOnProperty** to specify whether to use a non-default managed property as the basis for duplicate trimming. The default value is the **DocumentSignature** managed property. The managed property must be of type **Integer** or **String**. By using a managed property that represents a grouping of items, you can use this feature for field collapsing. - - - - **Syntax** - - - - `TrimDuplicatesOnProperty = ` - + +**Syntax** +`TrimDuplicatesOnProperty = ` + > [!NOTE] > In SharePoint, use **CollapseSpecification** wherever possible. **TrimDuplicatesOnProperty** is available for backward compatibility only. - - - - ### Trim duplicate search results using the TrimDuplicatesKeepCount property - Use **TrimDuplicatesKeepCount** to specify the number of documents to retain when **TrimDuplicates** is **true**. If **TrimDuplicates** is based on a managed property that can be used as a group identifier, for example a site ID, you can control how many results are returned for each group. The items returned are those with the highest dynamic rank within each group. - - - - **Syntax** - - - - `TrimDuplicatesKeepCount = ` - - - + +**Syntax** +`TrimDuplicatesKeepCount = ` ### Retrieve duplicate search results using the TrimDuplicatesIncludeId property - Use **TrimDuplicatesIncludeId** to retrieve the duplicates of a document when **TrimDuplicates** is **true** and **TrimDuplicatesOnProperty** or **CollapseSpecification** is set to **false**. - - - + The document ID, _docid_, is used to retrieve the duplicates of a particular document. - - - - **Syntax** - - - - `TrimDuplicatesIncludeId = ` - + +**Syntax** +`TrimDuplicatesIncludeId = ` + > [!NOTE] > The _fcoid_ managed property in FAST Search Server 2010 for SharePoint has been replaced with the _docid_ managed property in SharePoint. - - - - ## See also - - - -- [KeywordQuery](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.aspx) - - -- [Overview of the search schema in SharePoint](https://technet.microsoft.com/library/jj219669%28office.15%29.aspx) - - - - - - +- [KeywordQuery](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.KeywordQuery.aspx) +- [Overview of the search schema in SharePoint](https://technet.microsoft.com/library/jj219669%28office.15%29.aspx) diff --git a/docs/general-development/debugging-sharepoint-server-workflows.md b/docs/general-development/debugging-sharepoint-server-workflows.md index d40ced1a0..9ae9d211d 100644 --- a/docs/general-development/debugging-sharepoint-server-workflows.md +++ b/docs/general-development/debugging-sharepoint-server-workflows.md @@ -1,271 +1,133 @@ --- title: Debugging SharePoint workflows -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Demonstrates how SharePoint now relies on Workflow Manager 1.0 for all workflow processing and management, and demonstrates debugging options. +ms.date: 10/15/2022 ms.assetid: a5adf39b-8640-4871-be60-b786dcf9fafc -localization_priority: Priority +ms.localizationpriority: high --- - # Debugging SharePoint workflows + Demonstrates how SharePoint now relies on Workflow Manager 1.0 for all workflow processing and management, and demonstrates debugging options. - **Provided by:** [Andrew Connell](https://social.msdn.microsoft.com/profile/andrew%20connell%20%5bmvp%5d/), [www.AndrewConnell.com](http://www.andrewconnell.com) - - - -Microsoft has taken a different approach to workflows in SharePoint than in previous versions of SharePoint. The workflow team worked with the Azure team to create a new product called Workflow Manager. Workflow Manager hosts the latest version of the Windows Workflow Foundation runtime and all the necessary services in an available and scalable way. It takes advantage of the Microsoft Azure Service Bus for performance and scalability, and when deployed, it runs exactly the same in an on-premises deployment as in the cloud, similar to Office 365. SharePoint is then connected and configured to hand off all workflow execution and related tasks to the Workflow Manager farm. - - - + +**Provided by:** [Andrew Connell](https://www.andrewconnell.com), [Voitanos](https://www.voitanos.io) + +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). + +The workflow team has worked with the Azure team to create a product called Workflow Manager. Workflow Manager hosts the latest version of the Windows Workflow Foundation runtime and all the necessary services in an available and scalable way. It takes advantage of the Microsoft Azure Service Bus for performance and scalability, and when deployed, it runs exactly the same in an on-premises deployment as in the cloud, similar to Office 365. SharePoint is then connected and configured to hand off all workflow execution and related tasks to the Workflow Manager farm. + This change in the architecture required some changes to the two primary workflow authoring tools (SharePoint Designer 2013 and Visual Studio 2012) customers used to create custom workflows. However, the debugging techniques employed by developers in SharePoint 2007 and SharePoint 2010 still apply. The new architecture allows for a new option for workflows created using either SharePoint Designer 2013 or Visual Studio 2012 in that Fiddler can be used to monitor traffic between SharePoint and Workflow Manager. - - - ## SharePoint workflow debugging overview Debugging custom workflows created for SharePoint resembles previous versions, including SharePoint 2010 and SharePoint 2007. Some debugging options available will depend on the tool that is used to create the workflow (SharePoint Designer 2013 or Visual Studio 2012) and the kind of SharePoint deployment, such as on-premises or Office 365 (hosted). - - - There are four workflow debugging techniques that can be leveraged by workflow authors: - - - - Logging to the workflow history list - - - Setting breakpoints - - - Sending debug messages to the console - - - Monitoring traffic between SharePoint and Workflow Manager with Fiddler - - -Each option has advantages and disadvantages. It helps to have an understanding of what is possible when using the two workflow authoring tools (SharePoint Designer 2013 or Visual Studio 2012), as well as the type of workflow deployment (on-premises or Office 365). The following table contains a matrix of authoring tools, deployment targets, and the options available in each scenario. - - - +Each option has advantages and disadvantages. It helps to have an understanding of what is possible when using the two workflow authoring tools (SharePoint Designer 2013 or Visual Studio 2012), as well as the type of workflow deployment (on-premises or Office 365). The following table contains a matrix of authoring tools, deployment targets, and the options available in each scenario. -||**SharePoint On-Premises**|**Office 365 SharePoint Online**| -|:-----|:-----|:-----| -|SharePoint Designer 2013, SharePoint Online
| Log to history list
Fiddler
| Log to history list
| -|Visual Studio 2012
| Log to history list
Breakpoints
Console debug messages
Fiddler
| Log to history list
Breakpoints
| - +| Product | SharePoint On-Premises | Office 365 SharePoint Online | +| :------------------------------------------ | :------------------------------------------------------------- | :------------------------------ | +| SharePoint Designer 2013, SharePoint Online | Log to history list Fiddler | Log to history list | +| Visual Studio 2012 | Log to history list Breakpoints Console debug messages Fiddler | Log to history list Breakpoints | ## Debugging with the workflow history list The only debugging option that is available in every type of SharePoint deployment is writing log messages to the workflow history list. By using this method, you can use either the **Log to History List** action in SharePoint Designer 2013 or the **WriteToHistory** activity in Visual Studio 2012 to write a string message as a new item to the list, specified in the workflow association, which is the container for all history logging messages. These can be simple strings or constructed by concatenating the contents of variables within the workflow. - - - + Using the history list as a debugging tool is not ideal because users can see the messages. Therefore, when the debugging session is complete and the workflow is used in production, the workflow developer will want to remove these messages, creating an additional step between debugging and deployment. Nonetheless, this is the only option available in any scenario, regardless of which tool is used to create the workflow or which type of SharePoint deployment. - - - ## Debugging using Visual Studio 2012 breakpoints Another debugging option is to take advantage of breakpoints. Breakpoints are available only for workflows created using Visual Studio 2012, since SharePoint Designer 2013 has no capability to set breakpoints or to attach a debugger to the running process. These are available in both SharePoint on-premises and hosted deployments such as Office 365. In this scenario, you would set a breakpoint on an activity within the workflow and then start the workflow in debug mode. - - - -**Figure 1. Start the workflow** +### Figure 1. Start the workflow - - - - - - - ![Figure 1 Starting workflow](../images/ngDebuggingSP2013Workflows01.png) - - - -Visual Studio will deploy the workflow to the target SharePoint environment and attach a debugger. When the workflow process reaches the activity the breakpoint is set on, Visual Studio regains focus and lets you examine the values of workflow variables and step through each activity from Visual Studio 2012, as shown in the following figure. - - - -**Figure 2. Workflow breakpoint** +Visual Studio will deploy the workflow to the target SharePoint environment and attach a debugger. When the workflow process reaches the activity the breakpoint is set on, Visual Studio regains focus and lets you examine the values of workflow variables and step through each activity from Visual Studio 2012, as shown in the following figure. - - - +### Figure 2. Workflow breakpoint - - - ![Figure 2. Workflow breakpoint](../images/ngDebuggingSP2013Workflows02.png) - - - - - - - - - - - ## Debugging workflows using debug messages and the test service host The introduction of Workflow Manager to the SharePoint workflow story introduces two new debugging opportunities available when you are creating custom workflows using Visual Studio 2012 and testing them in an on-premises deployment. Visual Studio 2012 includes a **WriteLine** activity that accepts a single string-based message as an input. - - - - -**Figure 3. WriteLine activity** - - - +### Figure 3. WriteLine activity - - - ![Figure 3. WriteLine activity](../images/ngDebuggingSP2013Workflows.png) - - - -This activity will write the message that resembles the **System.Diagnostics.Debug.WriteLine()** method in a standard .NET Windows Console Application. The Workflow Manager 1.0 development tool includes a console utility that is named the **Test Service Host** that Visual Studio 2012 will open when a new debugging session is started and when testing with an on-premises SharePoint deployment. This console utility, **Microsoft.Workflow.TestServiceHost.exe** found in **C:\\Program Files (x86)\\Workflow Manager Tools\\1.0**, attaches to the registered Workflow Manager instance and listens for messages written using the **WriteLine** activity, as shown in the following figure. - - - -**Figure 4. Messages for WriteLine activity** +This activity will write the message that resembles the **System.Diagnostics.Debug.WriteLine()** method in a standard .NET Windows Console Application. The Workflow Manager 1.0 development tool includes a console utility that is named the **Test Service Host** that Visual Studio 2012 will open when a new debugging session is started and when testing with an on-premises SharePoint deployment. This console utility, **Microsoft.Workflow.TestServiceHost.exe** found in **C:\\Program Files (x86)\\Workflow Manager Tools\\1.0**, attaches to the registered Workflow Manager instance and listens for messages written using the **WriteLine** activity, as shown in the following figure. - - - +### Figure 4. Messages for WriteLine activity - - - ![Figure 4. Messages for WriteLine activity](../images/ngDebuggingSP2013Workflows04.png) - - - + These messages resemble code comments or debug messages in a console application. Unlike writing to the workflow history list, you don't need to remove these before deploying the workflow to production. Unless the **Test Service Host** utility is connected to Workflow Manager, the messages are harmless. - - - + This debugging option is not available for workflows created using SharePoint Designer 2013, because there is no action that maps to the **WriteLine** activity. Unfortunately, this debugging option is available only to SharePoint on-premises installations, since the port used by the Test Service Host utility is typically not publically accessible outside an on-premises network. This is also true for Office 365. The ports SharePoint uses to connect to Workflow Manager are the same ones used by the Test Service Host, and those are only accessible within the trusted network. However, this does not mean that you need to change their workflows to remove any **WriteLine** activities before deployment to Office 365. These activities can be left in the workflow as they are not seen unless the **Test Service Host** is connected to Workflow Manager. - - - ## Debugging using Fiddler to monitor HTTP traffic The last debugging option for SharePoint workflows is a new addition for workflow developers due to the change in how workflows are handled in the current platform. Recall that in SharePoint, all workflow processing is handed off to an external product, Workflow Manager 1.0. When a workflow has to communicate with SharePoint, such as updating the current state of the workflow, collecting data from items or users in a SharePoint site, or when working with tasks, Workflow Manager's activities leverage the SharePoint REST API to perform these operations. SharePoint communicates with Workflow Manager using a client library that serves as a proxy to REST services exposed by Workflow Manager. Both SharePoint and Workflow Manager communicate with one another using the standard HTTP and HTTPS protocols. - - - + This architecture yields a new debugging option for workflow authors. By using the HTTP debugging proxy tool Fiddler, you can monitor every request and corresponding response between the two products. In addition, any custom services called by the custom workflows using the **HttpSend** activity in Visual Studio 2012 or corresponding **Call HTTP Web Service** action in SharePoint Designer 2013 can also be monitored and inspected by Fiddler. This debugging model is also available, regardless of the tool that you use to create custom workflows (SharePoint Designer 2013 or Visual Studio 2012). - - - + The only time this option is not available is when you are testing workflows using an Office 365 deployment of SharePoint. Since all traffic between SharePoint and Workflow Manager occurs server-side, it is not possible to connect to one of the servers in Office 365 and start Fiddler from the console. - - - -This new option gives you transparency and insight into the workflow engine that was not possible when developing workflows in previous versions of SharePoint before SharePoint. - - - -For example, you can see the raw responses coming back from Workflow Manager or SharePoint in a web service call. At times Workflow Manager may respond with a specific error message. SharePoint includes user-friendly error messages but these may not be sufficiently specific. Using Fiddler, you can see the exact error message returned to help troubleshoot the issue. - - - + +This new option gives you transparency and insight into the workflow engine that was not possible when developing workflows in previous versions of SharePoint before SharePoint. + +For example, you can see the raw responses coming back from Workflow Manager or SharePoint in a web service call. At times Workflow Manager may respond with a specific error message. SharePoint includes user-friendly error messages but these may not be sufficiently specific. Using Fiddler, you can see the exact error message returned to help troubleshoot the issue. + Another use case is examining the response from a successful web service call. When working with web services in workflows, regardless of the authoring tool, that you need to know the exact property name (and path if it is a complex response) for a value that is contained in a response. By using Fiddler, you can see the complete response data. - - - ### Understanding SharePoint and Workflow Manager for debugging with Fiddler To debug workflows in SharePoint and Workflow Manager 1.0 with Fiddler, some configuration and setup steps must be performed in a developer environment before debugging. Before completing the steps, it helps to have an understanding of how Fiddler works and how workflows work in SharePoint. - - - #### Fiddler can only inspect traffic from the local server -The only traffic Fiddler can intercept and inspect are requests originating from the local server where Fiddler was started. This can present a challenge when Fiddler is used as a debugging tool for SharePoint workflows. - - - +The only traffic Fiddler can intercept and inspect are requests originating from the local server where Fiddler was started. This can present a challenge when Fiddler is used as a debugging tool for SharePoint workflows. + If SharePoint and Workflow Manager 1.0 are installed on different servers and if Fiddler is started from SharePoint Server, the only traffic that Fiddler will display is the traffic where the request originated from SharePoint. None of the traffic originating from Workflow Manager 1.0, even if it is targeted to the SharePoint Server, will be intercepted. - - - + Therefore, when developing workflows, it is easier to debug them if both SharePoint and Workflow Manager 1.0 are installed on the same server. Note that this is not a requirement; you can start Fiddler on both the SharePoint Server and Workflow Manager servers, although it is more complex to monitor two instances on two servers for the same workflow process. - - - #### Fiddler can only inspect traffic from the current logged-on user - Fiddler can only intercept and inspect traffic from the current logged-on user. To view traffic that originated from SharePoint, you must log on to SharePoint Server using the Windows account that is configured as the identity of the application pool that hosts the web application for the SharePoint site initiating the workflow. - - - +Fiddler can only intercept and inspect traffic from the current logged-on user. To view traffic that originated from SharePoint, you must log on to SharePoint Server using the Windows account that is configured as the identity of the application pool that hosts the web application for the SharePoint site initiating the workflow. + The same is true with Workflow Manager. To intercept and inspect traffic that originates from Workflow Manager, you must log on to the server using the Windows identity configured during the provisioning of the Workflow Manager farm as the service account for Workflow Manager. - - - + When using Fiddler to debug workflows, it is easier to debug them if not only both Workflow Manager and SharePoint are installed and configured on the same server, but they also use the same Windows identity as the service account. All traffic from both Workflow Manager and SharePoint can then be intercepted and inspected by Fiddler. - - - #### SharePoint must trust Fiddler's certificate Before using Fiddler for debugging SharePoint workflows, you need to understand how encrypted traffic is handled. Encrypted traffic over HTTP, known as HTTPS, is implemented by using a certificate's private key to encrypt some data and then send it to another recipient. The recipient has the certificate's public key that is paired with the private key. When a request is received by the recipient, the recipient can validate that the request came from the sender because the encrypted content's signature matches the public key, which can only be true if it was encrypted with the certificate's private key. - - - + Fiddler can intercept HTTPS traffic and be configured to decrypt it so it is in a human-readable format for inspection in the tool. After displaying the request, Fiddler then uses its own certificate to re-encrypt the traffic and send it to the intended recipient. This can cause an issue, though, because now the recipient received the original response but it is not secured using the certificate from the original sender. This can be an issue when debugging SharePoint workflows because Fiddler's certificate is not trusted by SharePoint. Therefore, in order to use Fiddler to intercept and inspect HTTPS traffic between SharePoint and Workflow Manager, the Fiddler certificate must be trusted by SharePoint. - - - ### Configure SharePoint and Workflow Manager 1.0 for workflow debugging with Fiddler The following sections explain how to configure Fiddler and SharePoint for workflow debugging. - - - #### Configure the .NET Framework default proxy configuration The first step is to first define the default proxy configuration for .NET Framework. These changes will allow Fiddler to intercept the traffic coming from both SharePoint and the Workflow Manager. Open the **machine.config** file in both of the following locations: - - - - -- `%systemdrive%\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Config\\machine.config` - - -- `%systemdrive%\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Config\\machine.config` - - -Next, add the following markup to the bottom of each file, just before the closing **** element: - - - +- `%systemdrive%\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Config\\machine.config` +- `%systemdrive%\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Config\\machine.config` +Next, add the following markup to the bottom of each file, just before the closing **\** element: ```xml - @@ -274,293 +136,125 @@ Next, add the following markup to the bottom of each file, just before the closi ``` Save the changes and close the files. - - - #### Configure Fiddler to intercept and inspect HTTPS traffic The next step is to configure Fiddler to intercept encrypted traffic and decrypt it for configuration. - - - 1. Start Fiddler. - - -2. If you are using the local HOSTS file, ensure that the entries are included in Fiddler by selecting the **Tools -> HOSTS** menu option. - - -3. Check the **Enable remapping of requests for one host to a different host or IP, overriding DNS**, - - -4. Click the **Import Windows Hosts File**, and then click the **Save** button. - - - -**Figure 5. Host Remapping** - - - - - - - - +1. If you are using the local HOSTS file, ensure that the entries are included in Fiddler by selecting the **Tools -> HOSTS** menu option. +1. Check the **Enable remapping of requests for one host to a different host or IP, overriding DNS**, +1. Click the **Import Windows Hosts File**, and then click the **Save** button. + +##### Figure 5. Host Remapping + ![Figure 5. UI for utilizing local HOSTS file](../images/ngDebuggingSP2013Workflows05.png) - - - -Next, configure Fiddler's connection options. - - - - - - - + +Next, configure Fiddler's connection options. 1. Select the **Tools -> Fiddler Options** menu option. - - -2. Click the **Connections** tab. - - -3. Clear the **Chain to upstream gateway proxy** selection. - - -4. Select the **Act as system proxy on startup** and **Monitor all connections** options, as shown in the following figure. - - **Figure 6. Fiddler connection options.** - - - - ![Figure 6. Fiddler connection options](../images/ngDebuggingSP2013Workflows06.png) - - - - - -5. Select the **HTTPS** tab in the **Fiddler Options** dialog. - - -6. Check the **Capture HTTPS CONNECTs**. - - -7. Select **Decrypt HTTPS Traffic**. - - -8. Select **??? from all processes**. - - -9. Check **Ignore server certificate errors**. - - -10. Click the **Export Root Certificate to Desktop** button. - - -11. When prompted with a warning, click **Yes** to **Trust the Fiddler Root certificate**. - - -This process will configure Windows to trust the certificate, although SharePoint does not trust it yet. - - - +1. Click the **Connections** tab. +1. Clear the **Chain to upstream gateway proxy** selection. +1. Select the **Act as system proxy on startup** and **Monitor all connections** options, as shown in the following figure. + + ![Figure 6. Fiddler connection options](../images/ngDebuggingSP2013Workflows06.png) -**Figure 7. HTTPS tab** +1. Select the **HTTPS** tab in the **Fiddler Options** dialog. +1. Check the **Capture HTTPS CONNECTs**. +1. Select **Decrypt HTTPS Traffic**. +1. Select **??? from all processes**. +1. Check **Ignore server certificate errors**. +1. Click the **Export Root Certificate to Desktop** button. +1. When prompted with a warning, click **Yes** to **Trust the Fiddler Root certificate**. + +This process will configure Windows to trust the certificate, although SharePoint does not trust it yet. - - - +#### Figure 7. HTTPS tab - - - ![Figure 7. HTTPS tab](../images/ngDebuggingSP2013Workflows07.png) - + > [!NOTE] -> If a security WRning appears with a message instructing not to trust the Fiddler certificate, click **Yes** to continue installing the certificate. - - - +> If a security warning appears with a message instructing not to trust the Fiddler certificate, click **Yes** to continue installing the certificate. #### Configure SharePoint to trust the certificate -The last step is to configure SharePoint to trust the Fiddler certificate that was exported in the previous step. - - - +The last step is to configure SharePoint to trust the Fiddler certificate that was exported in the previous step. 1. Log on as a SharePoint farm administrator. - - -2. Start the SharePoint Management Shell. - - -3. Load the SharePoint Snap-In. - -```powershell - -PS C:\\> Add-PSSnapIn Microsoft.SharePoint.PowerShell -``` +1. Start the SharePoint Management Shell. +1. Load the SharePoint Snap-In. -4. Use the certificate utility to install the Fiddler certificate. - -```powershell - PS C:\\> $fidderCertificatePath = [full path to exported FiddlerRoot.cer certificate file] -PS C:\\> certutil.exe -addstore -enterprise -f -v root $fidderCertificatePath -PS C:\\> $fiddlerCertificate = Get-PfxCertificate -FilePath $fidderCertificatePath -PS C:\\> New-SPTrustedRootAuthority -Name "Fiddler" -Certificate $fiddlerCertificate + ```powershell + Add-PSSnapIn Microsoft.SharePoint.PowerShell + ``` -``` +1. Use the certificate utility to install the Fiddler certificate. + + ```powershell + $fidderCertificatePath = [full path to exported FiddlerRoot.cer certificate file] + certutil.exe -addstore -enterprise -f -v root $fidderCertificatePath + $fiddlerCertificate = Get-PfxCertificate -FilePath $fidderCertificatePath + New-SPTrustedRootAuthority -Name "Fiddler" -Certificate $fiddlerCertificate + ``` -5. Run IISRESET to make sure that SharePoint picks up the certificate trust change. - - +1. Run IISRESET to make sure that SharePoint picks up the certificate trust change. -### Walkthrough: Debugging a SharePoint workflow with Fiddler +### Walk-through: Debugging a SharePoint workflow with Fiddler -This simple walkthrough demonstrates using Fiddler to debug a SharePoint workflow authored using Visual Studio 2012. When the workflow starts, it retrieves a customer ID from a field in a custom list. This customer ID is used to query a publically accessible service to retrieve additional details about the customer. It then uses these values to update the original list item. The workflow can be found in the following MSDN code sample: [SharePoint Workflow: Call an External Web Service](https://code.msdn.microsoft.com/office/SharePoint-2013-workflow-48ea87d4). - - - -This walkthrough has the following prerequisites: - - - +This simple walk-through demonstrates using Fiddler to debug a SharePoint workflow authored using Visual Studio 2012. When the workflow starts, it retrieves a customer ID from a field in a custom list. This customer ID is used to query a publicly accessible service to retrieve additional details about the customer. It then uses these values to update the original list item. The workflow can be found in the following MSDN code sample: [SharePoint Workflow: Call an External Web Service](https://code.msdn.microsoft.com/office/SharePoint-2013-workflow-48ea87d4). + +This walk-through has the following prerequisites: - SharePoint and Workflow Manager 1.0 are installed on the same server. - - - The Windows identity **CONTOSO\\SP_Content** is configured for the application pool identity that hosts the web application serving the SharePoint site that starts the workflow. - - - The SharePoint site used to start the workflow is **http://intranet.contoso.com** - - - The Workflow Manager 1.0 farm endpoint is **w15sp.contoso.com**. - - - SharePoint and Workflow Manager 1.0 are configured to allow OAuth over HTTP. - - > **Caution:** - > This should never be done on the production server, but only for testing and debugging. + + > [!CAUTION] + > This should never be done on the production server, but only for testing and debugging. 1. Log on to the server where Workflow Manager and SharePoint are installed with the Windows identity configured as the Workflow Manager 1.0 farm account and SharePoint application pool identity. - - -2. Start Fiddler. While Fiddler will now intercept traffic from the current user, if there are any existing connections or processes running, Fiddler may miss those as it was not running when the connections were initially established. To force both Workflow Manager and SharePoint Server to recycle and have their traffic to each other get intercepted by Fiddler, recycle SharePoint by running an IISRESET and recycle Workflow Manager by stopping and starting the Windows service **Workflow Manager Backend**. This can be done with the following two commands at an administrative command prompt. - -```powershell -PS C:\\> IISRESET -PS C:\\> net stop WorkflowServiceBackend -PS C:\\> net start WorkflowServiceBackend -``` +1. Start Fiddler. While Fiddler will now intercept traffic from the current user, if there are any existing connections or processes running, Fiddler may miss those as it was not running when the connections were initially established. To force both Workflow Manager and SharePoint Server to recycle and have their traffic to each other get intercepted by Fiddler, recycle SharePoint by running an IISRESET and recycle Workflow Manager by stopping and starting the Windows service **Workflow Manager Backend**. This can be done with the following two commands at an administrative command prompt. -3. Start the workflow. - - -In the figure below, notice that sessions #18-36 originated from SharePoint and sessions #37-43 originated from Workflow Manager. - - - + ```powershell + IISRESET + net stop WorkflowServiceBackend + net start WorkflowServiceBackend + ``` + +1. Start the workflow. -**Figure 8. Starting the workflow** +In the figure below, notice that sessions #18-36 originated from SharePoint and sessions #37-43 originated from Workflow Manager. - - - +### Figure 8. Starting the workflow - - - ![Figure 8. Starting Workflow](../images/ngDebuggingSP2013Workflows08.png) - - - -Notice that in session #36, SharePoint is requesting that Workflow Manager start a workflow (indicated as [A] in the figure) and Workflow Manager responds (indicated as [B] in the figure) with a "Success" message: - - - -**Figure 9. "Success" message response** +Notice that in session #36, SharePoint is requesting that Workflow Manager start a workflow (indicated as [A] in the figure) and Workflow Manager responds (indicated as [B] in the figure) with a "Success" message: - - - +### Figure 9. "Success" message response - - - ![Figure 10. Success message](../images/ngDebuggingSP2013Workflows10.png) - - - -Session #40 is where Workflow Manager is retrieving the list item ID and GUID from SharePoint. - - - -**Figure 10. Retrieving item ID and GUID** +Session #40 is where Workflow Manager is retrieving the list item ID and GUID from SharePoint. - - - +### Figure 10. Retrieving item ID and GUID - - - ![Figure 10. Retrieving list item ID and GUID](../images/ngDebuggingSP2013Workflows11.png) - - - -Session #43 is where Workflow Manager is updating the list item in SharePoint with a new value for the announcement item's **Body** field by passing a JavaScript Object Notation (JSON) object (indicated as [A] in the figure) along as the payload. SharePoint responds with an HTTP status of 204, which indicates that it successfully processed the request, but there is no message in the response. - - - -**Figure 11. Updating the list item** +Session #43 is where Workflow Manager is updating the list item in SharePoint with a new value for the announcement item's **Body** field by passing a JavaScript Object Notation (JSON) object (indicated as [A] in the figure) along as the payload. SharePoint responds with an HTTP status of 204, which indicates that it successfully processed the request, but there is no message in the response. - - - +### Figure 11. Updating the list item - - - ![Figure 11. Updating the list item in SharePoint](../images/ngDebuggingSP2013Workflows12.png) - - - - - - - - - - - ## Conclusion The workflow story in the SharePoint release introduced a new layer of abstraction, Workflow Manager 1.0. This new architecture changed how workflows are processed. SharePoint now relies on Workflow Manager 1.0 for all workflow processing and management. - - - + One task you need to perform when creating custom applications and business processes in workflows is debugging your work. The new workflow architecture of SharePoint offers the same debugging options that existed in previous versions of SharePoint. However, the new architecture offers two new options when creating custom workflows using the new architecture. This article explained the legacy debugging options as well as the new options using the **WriteLine** activity and using Fiddler for intercepting and inspecting traffic between SharePoint and Workflow Manager 1.0. - - - ## See also - - - -- [Fiddler](http://fiddler2.com/home) - - - - - - +- [Fiddler](http://fiddler2.com/home) diff --git a/docs/general-development/deciding-between-sharepoint-add-ins-and-sharepoint-solutions.md b/docs/general-development/deciding-between-sharepoint-add-ins-and-sharepoint-solutions.md index d51e00d0b..3ae112357 100644 --- a/docs/general-development/deciding-between-sharepoint-add-ins-and-sharepoint-solutions.md +++ b/docs/general-development/deciding-between-sharepoint-add-ins-and-sharepoint-solutions.md @@ -1,9 +1,9 @@ --- title: Deciding between SharePoint Add-ins and SharePoint solutions -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Provides a link to the SharePoint Add-ins compared with SharePoint solutions topic for a modern solution. +ms.date: 06/09/2022 ms.assetid: 8459e265-b8fd-4bf8-911e-d63cae8bf96f -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/develop-access-web-apps.md b/docs/general-development/develop-access-web-apps.md index 7808170f4..bf36fae11 100644 --- a/docs/general-development/develop-access-web-apps.md +++ b/docs/general-development/develop-access-web-apps.md @@ -1,9 +1,9 @@ --- title: Develop Access web apps -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to develop web-based applications using Microsoft Access 2013 and provides information on Access 2013's new features. +ms.date: 06/09/2022 ms.assetid: 41131b27-d750-4d11-b3c7-c17ad4d666e2 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/develop-sharepoint-workflows-using-visual-studio.md b/docs/general-development/develop-sharepoint-workflows-using-visual-studio.md index 9f662a4ba..18e73ac33 100644 --- a/docs/general-development/develop-sharepoint-workflows-using-visual-studio.md +++ b/docs/general-development/develop-sharepoint-workflows-using-visual-studio.md @@ -1,213 +1,128 @@ --- title: Develop SharePoint workflows using Visual Studio -ms.date: 09/25/2017 -ms.prod: sharepoint +description: "SharePoint supports two primary workflow development environments for authoring workflows: SharePoint Designer and Visual Studio. This article summarizes both and discusses the advantages and disadvantages of each." +ms.date: 06/09/2022 ms.assetid: 28f5d3b1-6fe8-4b1f-8c4e-b11105fe6f46 -localization_priority: Priority +ms.localizationpriority: high --- +# Develop SharePoint workflows using Visual Studio +SharePoint supports two primary workflow development environments for authoring workflows: SharePoint Designer and Visual Studio. This article summarizes both and discusses the advantages and disadvantages of each. +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). -# Develop SharePoint workflows using Visual Studio -SharePoint supports two primary workflow development environments for authoring workflows: SharePoint Designer and Visual Studio. This article summarizes both and discusses the advantages and disadvantages of each. ## Authoring basics for SharePoint workflows - > [!NOTE] -> For guidance on setting up and configuring Microsoft SharePoint and the Workflow Manager Client 1.0 server, see [Set up and configure SharePoint Workflow Manager](set-up-and-configure-sharepoint-workflow-manager.md). - - - +> For guidance on setting up and configuring Microsoft SharePoint and the Workflow Manager Client 1.0 server, see [Set up and configure SharePoint Workflow Manager](set-up-and-configure-sharepoint-workflow-manager.md). As with previous versions, Microsoft SharePoint provides two primary workflow development environments for authoring workflows: Microsoft SharePoint Designer and Microsoft Visual Studio. However, what differs from previous versions is that using Visual Studio no longer provides a code-based authoring strategy. Instead, both SharePoint Designer and Visual Studio provide a fully declarative, no-code authoring environment regardless of the development tool you select. - -> [!NOTE] -> As a complement to authoring workflows in SharePoint Designer, you can also use Microsoft Visio 2013 to structure your workflow logic by using Visio 2013 shapes, and then import your logic into SharePoint Designer 2013. For information about using Visio 2013 to author your workflow logic, see [Workflow development in SharePoint Designer and Visio](workflow-development-in-sharepoint-designer-and-visio.md). - - - +> [!NOTE] +> As a complement to authoring workflows in SharePoint Designer, you can also use Microsoft Visio 2013 to structure your workflow logic by using Visio 2013 shapes, and then import your logic into SharePoint Designer 2013. For information about using Visio 2013 to author your workflow logic, see [Workflow development in SharePoint Designer and Visio](workflow-development-in-sharepoint-designer-and-visio.md). ### Declarative workflows Let's first be clear what is meant by "declarative" workflows. This term means that instead of being authored in code and then compiled into managed assemblies, the workflow is described (literally) in XAML and then executed interpretively at run time. - - - + The XAML is derived (or inferred) from the workflow building blocks that you manipulate in the Workflow Designer (if using Visual Studio) or SharePoint Designer workflow design surface (or Visio, but more about that later). The building blocks themselves are the visual workflow design objects in the designer toolbox—stages, conditions, actions, events, and so on. The set of tools in the respective toolboxes (Visual Studio or SharePoint Designer) differs somewhat, but the concept of the declarative workflow remains the same. - - - ## Decision tree: SharePoint Designer vs. Visual Studio - Among the greatest advantages of the workflow framework in SharePoint is the ease with which information workers can use the no-code environment of SharePoint Designer to create rich and powerful workflows. Additionally, a high degree of flexibility and customization is available in a declarative authoring environment such as Visual Studio. - - - + Both of these workflow authoring environments—SharePoint Designer and Visual Studio—offer specific advantages and disadvantages. In this section, we explore how to determine which authoring environment best suits your workflow development needs. - - - ### Using SharePoint Designer - - **Target users:** Information workers, business analysts, SharePoint developers. - - - **Difficulty level:** Familiarity with SharePoint Designer, including the core workflow components, such as stages, gates, actions, conditions, and loops. - - + + With SharePoint Designer, users can create a workflow that is attached to a list, library, or site using a no-code, text-based designer. Or, they can use the new visual design environment in which graphical elements are arranged on a design surface to represent the logical flow of a business process. SharePoint Designer excels at enabling rapid workflow development by non-technical workers. - - - ### Using Visual Studio - - **Target users:** Intermediate or advanced software developers. - - - **Difficulty level:** Familiarity with Visual Studio, including software development concepts such as event receivers, packaging and deployment, and security. - - + Authoring workflows in Visual Studio provides flexibility to create workflows to support virtually any business process, regardless of its complexity, and allows debugging and reuse of workflow definitions. Perhaps most important, Visual Studio lets developers include SharePoint workflows as part of a broader SharePoint solution or SharePoint Add-in. - - - + Visual Studio enables developers to create custom actions for consumption by SharePoint Designer, and provides the means to execute custom logic. With Visual Studio, developers can also create workflow templates, which can be deployed to multiple sites. - - - ## Comparing SharePoint Designer with Visual Studio - The following table provides a side-by-side comparison of the features and requirements for using SharePoint Designer and Visual Studio to create SharePoint workflows. - - - **Table 1. Workflow authoring tool comparison** - -|**Feature / Requirement**|**SharePoint Designer**|**Visual Studio**| -|:-----|:-----|:-----| -|Allows rapid workflow development
|Yes
|Yes
| -|Enables reuse of workflows
|A workflow can be used only by the list or library on which it was developed. However, SharePoint Designer provides reusable workflows that can be used multiple times within the same site.
|A workflow can be written as a template so that after it is deployed, it can be reused and associated with any list or library.
| -|Allows you to include a workflow as part of a SharePoint solution or SharePoint Add-in
|No
|Yes
| -|Allows you to create custom actions
|No. However, SharePoint Designer can consume and implement custom actions that are created and deployed by using Visual Studio.
|Yes. However, be aware that in Visual Studio, the underlying activities, not their corresponding actions, are used.
| -|Allows you to write custom code
|No
|No
**Note**: This is changed from previous versions. In SharePoint, workflows are declarative only and Visual Studio relies on the visual design surface for workflow development. | -|Can use Visio Professional to create workflow logic
|Yes
|No
| -|Deployment
|Deployed automatically to list, library, or site on which they were created.
|Create a SharePoint solution package (.wsp) file and deploy the solution package to the site (SPWeb).
| -|One-click publishing available for workflows
|Yes
|Yes
| -|Workflows can be packaged and deployed to a remote server
|Yes
|Yes
| -|Debugging
|Cannot be debugged.
|Workflow can be debugged by using Visual Studio.
| -|Can use only actions that are approved by site administrator
|Yes
|Yes
**Note**: This is changed from previous versions. Previously, workflows and actions that were authored by using Visual Studio were code-based and deployed at the farm scope, so administrator approval was not required. | - +| Feature / Requirement | SharePoint Designer | Visual Studio | +| :------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Allows rapid workflow development | Yes | Yes | +| Enables reuse of workflows | A workflow can be used only by the list or library on which it was developed. However, SharePoint Designer provides reusable workflows that can be used multiple times within the same site. | A workflow can be written as a template so that after it is deployed, it can be reused and associated with any list or library. | +| Allows you to include a workflow as part of a SharePoint solution or SharePoint Add-in | No | Yes | +| Allows you to create custom actions | No. However, SharePoint Designer can consume and implement custom actions that are created and deployed by using Visual Studio. | Yes. However, be aware that in Visual Studio, the underlying activities, not their corresponding actions, are used. | +| Allows you to write custom code | No | No **Note**: This is changed from previous versions. In SharePoint, workflows are declarative only and Visual Studio relies on the visual design surface for workflow development. | +| Can use Visio Professional to create workflow logic | Yes | No | +| Deployment | Deployed automatically to list, library, or site on which they were created. | Create a SharePoint solution package (.wsp) file and deploy the solution package to the site (SPWeb). | +| One-click publishing available for workflows | Yes | Yes | +| Workflows can be packaged and deployed to a remote server | Yes | Yes | +| Debugging | Cannot be debugged. | Workflow can be debugged by using Visual Studio. | +| Can use only actions that are approved by site administrator | Yes | Yes **Note**: This is changed from previous versions. Previously, workflows and actions that were authored by using Visual Studio were code-based and deployed at the farm scope, so administrator approval was not required. | ## Developing workflows using Visual Studio - Unlike earlier versions, workflows in SharePoint are entirely declarative. Built now on Windows Workflow Foundation 4, Visual Studio provides a visual workflow designer surface that lets you create custom workflows, workflow templates, forms, and custom workflow activities entirely in the designer environment. Your workflow is then packaged and deployed as a SharePoint Feature. For information about Feature packaging, see [Using Features in SharePoint Foundation](https://msdn.microsoft.com/library/ms461324.aspx). - - - -Perhaps the most significant change for Visual Studio developers is that custom workflows are no longer compiled and deployed as .NET Framework assemblies. Furthermore, SharePoint no longer uses Microsoft InfoPath forms; instead, forms generation relies on Microsoft ASP.NET forms. - - - + +Perhaps the most significant change for Visual Studio developers is that custom workflows are no longer compiled and deployed as .NET Framework assemblies. Furthermore, SharePoint no longer uses Microsoft InfoPath forms; instead, forms generation relies on Microsoft ASP.NET forms. + Finally, the Visual Studio workflow project templates have changed. Whereas formerly templates for state machine and sequential workflows were provided, these distinctions are no longer meaningful. Rather, Visual Studio project templates are available in the Visual Studio build provided on your virtual machine (VM). - - - ## Enabling on-premises workflow debugging - To debug on-premises workflows in Visual Studio, you need to temporarily allow the Workflow Manager Tools to access your system through the firewall. - - - 1. In **Control Panel**, choose **System and Security**, **Windows Firewall**. - - -2. In the **Control Panel Home** list, choose the **Advanced Settings** link. - - -3. In the left pane of Windows Firewall, choose **Inbound Rules**. - - -4. In the **Inbound Rules** list, choose **Workflow Manager Tools 1.0 for Visual Studio 2012 - Test Service Host**. - - -5. In the **Actions** list, choose **Enable Rule**. - - -6. On the properties page of your SharePoint project, choose the **SharePoint** tab, and then select the **Enable Workflow debugging** check box. - - +1. In the **Control Panel Home** list, choose the **Advanced Settings** link. +1. In the left pane of Windows Firewall, choose **Inbound Rules**. +1. In the **Inbound Rules** list, choose **Workflow Manager Tools 1.0 for Visual Studio 2012 - Test Service Host**. +1. In the **Actions** list, choose **Enable Rule**. +1. On the properties page of your SharePoint project, choose the **SharePoint** tab, and then select the **Enable Workflow debugging** check box. ## Debugging SharePoint Online workflows using Visual Studio - To debug SharePoint Online workflows in Visual Studio, perform the following steps: - - - - -1. If you're behind a firewall, you may need to install a proxy client (such as the [Forefront Threat Management Gateway (TMG) Client](https://www.microsoft.com/download/details.aspx?displaylang=en&id=10504)), depending on your company's network topology. - - -2. Register for a Microsoft Azure account if you haven't already, and then sign into that account. - - For information about how to register for a Microsoft Azure account, see [Microsoft Azure](http://www.windowsazure.com). - - -3. Create a Microsoft Azure Service Bus namespace, which you can use to debug remote workflows. You can do this on the [Microsoft Azure portal](https://ms.portal.azure.com). - - For more information about the Microsoft Azure Service Bus, see [Create a Service Bus namespace using the Azure portal](https://docs.microsoft.com/azure/service-bus-messaging/service-bus-create-namespace-portal). - + +1. If you're behind a firewall, you may need to install a proxy client (such as the [Forefront Threat Management Gateway (TMG) Client](/previous-versions/tn-archive/cc441520(v=technet.10))), depending on your company's network topology. +1. Register for a Microsoft Azure account if you haven't already, and then sign into that account. + + For information about how to register for a Microsoft Azure account, see [Microsoft Azure](https://azure.microsoft.com/). + +1. Create a Microsoft Azure Service Bus namespace, which you can use to debug remote workflows. You can do this on the [Microsoft Azure portal](https://ms.portal.azure.com). + + For more information about the Microsoft Azure Service Bus, see [Create a Service Bus namespace using the Azure portal](/azure/service-bus-messaging/service-bus-create-namespace-portal). + > [!NOTE] - > SharePoint Online workflow debugging uses the Relay Service component of the Microsoft Azure Service Bus, so you'll be charged for using the Service Bus. See [Service Bus Pricing FAQ](https://msdn.microsoft.com/library/hh667438.aspx). You get free access to Microsoft Azure each month that you subscribe to Visual Studio Professional with MSDN, Visual Studio Premium with MSDN, or Visual Studio Ultimate with MSDN. With this access, you can use the Service Bus relay for 1,500, 3,000, or 3,000 hours, depending on your MSDN subscription. See [Get some amount of Microsoft Azure Services each month at no additional charge](http://www.windowsazure.com/pricing/member-offers/msdn-benefits/). -4. In Microsoft Azure, choose your service namespace, choose the **Access Key** link, and then copy the text in the **Connection String** box. - - -5. On the properties page of your SharePoint Add-in project, choose the **SharePoint** tab, and then select the **Enable Workflow debugging** check box. - + > SharePoint Online workflow debugging uses the Relay Service component of the Microsoft Azure Service Bus, so you'll be charged for using the Service Bus. See [Service Bus Pricing FAQ](https://msdn.microsoft.com/library/hh667438.aspx). You get free access to Microsoft Azure each month that you subscribe to Visual Studio Professional with MSDN, Visual Studio Premium with MSDN, or Visual Studio Ultimate with MSDN. With this access, you can use the Service Bus relay for 1,500, 3,000, or 3,000 hours, depending on your MSDN subscription. See [Get some amount of Microsoft Azure Services each month at no additional charge](https://azure.microsoft.com/services/developer-tools/visual-studio-subscriptions/). + +1. In Microsoft Azure, choose your service namespace, choose the **Access Key** link, and then copy the text in the **Connection String** box. +1. On the properties page of your SharePoint Add-in project, choose the **SharePoint** tab, and then select the **Enable Workflow debugging** check box. + You must enable this feature to debug workflows in SharePoint Online. This property applies to all of your SharePoint projects in Visual Studio. Visual Studio automatically turns off workflow debugging if you package your app for distribution on the Office store. - - -6. Select the **Enable debugging via Microsoft Azure Service Bus** check box. Then, in the **Microsoft Azure Service Bus connection string** box, paste the connection string that you copied. - - + + +1. Select the **Enable debugging via Microsoft Azure Service Bus** check box. Then, in the **Microsoft Azure Service Bus connection string** box, paste the connection string that you copied. + After you enable workflow debugging and provide a valid connection string for the Microsoft Azure Service Bus, you can debug SharePoint Online workflows. - + > [!NOTE] > If you haven't disabled workflow debugging and don't want to receive a notification whenever your project contains a workflow, clear the **Notify me if Microsoft Azure Service Bus debugging is not configured** check box. - - - - ## See also - A great deal of developing SharePoint workflows remains unchanged for the Visual Studio developer. The key sections of the documentation for SharePoint 2010 remain relevant: - - - - For information about using the Visual StudioWorkflow Designer, see [Visual Studio Designer for Windows Workflow Foundation Overview](https://msdn.microsoft.com/library/ms441543.aspx). - - - For information about creating forms by using Microsoft ASP.NET, see [Workflow Forms Overview](https://msdn.microsoft.com/library/ms457061.aspx). - - - For information about Feature packaging, see [Using Features in SharePoint Foundation](https://msdn.microsoft.com/library/ms461324.aspx). - - diff --git a/docs/general-development/develop-the-site-design-in-sharepoint.md b/docs/general-development/develop-the-site-design-in-sharepoint.md index 6a2e5662f..65fe1a84b 100644 --- a/docs/general-development/develop-the-site-design-in-sharepoint.md +++ b/docs/general-development/develop-the-site-design-in-sharepoint.md @@ -1,17 +1,18 @@ --- title: Develop the site design in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to develop the site design in SharePoint using the Design Manager feature and provides links to other resources. +ms.date: 06/09/2022 ms.assetid: 4c061484-2ba5-45ea-9860-aec9d7c8f80e -localization_priority: Priority +ms.localizationpriority: high --- # Develop the site design in SharePoint Find links to information about using Design Manager and implementing a design for your SharePoint site. If you want your SharePoint site to represent your organization's brand and not "look like SharePoint," you can create a custom design and use Design Manager to achieve that goal. Design Manager is a feature in SharePoint that makes it easier to create a fully customized, pixel-perfect design while using the web-design tools that you're already familiar with. Design Manager is a publishing feature that is available in publishing sites in both SharePoint and Office 365. You can also use Design Manager to brand the public-facing website in Office 365. - - + +> [!IMPORTANT] +> This extensibility option is **only** available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. We do not recommend using classic experience or these branding techniques anymore. For more information about using Design Manager to customize your sites, see the following articles and their subtopics: diff --git a/docs/general-development/developing-with-duet-enterprise-2-0.md b/docs/general-development/developing-with-duet-enterprise-2-0.md index dfd236f27..1a9d4abed 100644 --- a/docs/general-development/developing-with-duet-enterprise-2-0.md +++ b/docs/general-development/developing-with-duet-enterprise-2-0.md @@ -1,172 +1,89 @@ --- title: Developing with Duet Enterprise 2.0 -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes Duet Enterprise 2.0's features and details how to set up the developer environment, how to add an external content type, and more. +ms.date: 05/09/2023 ms.assetid: c3ef38aa-559e-4832-95c7-75e222c77624 -localization_priority: Normal +ms.localizationpriority: medium --- - # Developing with Duet Enterprise 2.0 ## Overview - Duet Enterprise 2.0 is the latest version of a collaborative effort between Microsoft and SAP to give SharePoint users the ability to work with data from SAP systems.It combines components from SAP as well as SharePoint and SharePoint Online. It gives a developer the ability to create components that will allow users to bring data from SAP systems into the familiar SharePoint environment. - - - ## Features of Duet Enterprise 2.0 - When properly installed and configured, Duet Enterprise 2.0 will provide the following features: - - - - You can work with data in SAP systems within SharePoint using Business Data Web parts, External lists and custom components. - - - Use SAP data in SharePoint without code by using built-in components. - - - Use SAP reporting systems inside of an app. - - - Use special web parts installed with Duet Enterprise 2.0 to add SAP information to SharePoint pages - - - Use SAP workflow in an app. - - - Developers can use client-side JavaScript to interact with SAP external data. - - - Secure data using OAuth for authentication. - - ## Setting up the development environment - Developing SharePoint Add-ins using Duet Enterprise 2.0, for the most part, is exactly the same as creating standard SharePoint Add-ins. You can use Visual Studio to extend your apps and work within the robust framework of the Visual Studio integrated development environment. - - - ## Adding external content types - In order to access the external data housed on the SAP system, you will have to add an external content type. Since SAP data is exposed through OData endpoints, the auto-generation tools installed in Visual Studio can be used to [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md) that is scoped at the app level. - - - + Follow these steps to create an external content type: - - - ### Creating an external content type from an SAP OData endpoint 1. In **Solution Explorer**, open the shortcut menu for the project, and choose **Add**, **Content types for External Data source**. - - -2. On the **Specify OData Source** page, enter the URL of the Duet Enterprise Workflow Service. - - -3. Choose a name for your OData source. - - -4. Select the entities that are needed. - - -5. Choose **Finish**. - - +1. On the **Specify OData Source** page, enter the URL of the Duet Enterprise Workflow Service. +1. Choose a name for your OData source. +1. Select the entities that are needed. +1. Choose **Finish**. + Visual Studio will create a new folder named External Content Types where you will find the newly created BDC model. - - - ## Configuring the BDC model - The most important thing to make the project work, is to add the **ODataExtensionProvider** property to the BDC model. This property defines the extension provider that provides BCS with the SAP extensions needed for creating app code. - - - -This sample shows the properties added to the BDC model: - - - - - -```XML +This sample shows the properties added to the BDC model: +```xml - - - https://:443/sap/opu/odata/sap/ - ZANDY_PO_HEADER_SRV/$metadata - 2.0 - - OBA.Server.Canary.ObaOdataServerExtensionProvider, - OBA.Server.SSOProvider, - Version=15.0.0.0, - Culture=neutral, - PublicKeyToken=71e9bce111e9429c - SAP-PASSPORT - - + + + https://:443/sap/opu/odata/sap/ + ZANDY_PO_HEADER_SRV/$metadata + 2.0 + + OBA.Server.Canary.ObaOdataServerExtensionProvider, + OBA.Server.SSOProvider, + Version=15.0.0.0, + Culture=neutral, + PublicKeyToken=71e9bce111e9429c + SAP-PASSPORT + ``` - ## Using Duet starter services to develop custom apps - -Duet Enterprise 2.0 installs several starter services to the file system on the SharePoint server. In a default installation, the files are found at C:\\Program Files\\Duet Enterprise\\2.0\\Solutions\\Starter Services. Among these are: - - - +Duet Enterprise 2.0 installs several starter services to the file system on the SharePoint server. In a default installation, the files are found at **C:\\Program Files\\Duet Enterprise\\2.0\\Solutions\\Starter Services**. Among these are: - OBACustomerWorkspace - - - OBAOrderToCash - - - OBAPortal - - - OBAProductCenter - - + Each of these solutions contains WSP files, solution and other supporting files needed to implement them. - - - + These solutions can be used to see what can be done with Duet Enterprise 2.0 and what the development patterns are, but they are not supported for use in SharePoint Add-ins. - - - ## See also - - - -- [Duet Enterprise for Microsoft SharePoint and SAP Server 2.0](https://technet.microsoft.com/library/ff972436.aspx) - - -- [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md) - - -- [Visual Studio Developer Center](https://msdn.microsoft.com/vstudio/default) - - -- [Office Development with Visual Studio](https://msdn.microsoft.com/office/hh133430) - - +- [Duet Enterprise for Microsoft SharePoint and SAP Server 2.0](https://technet.microsoft.com/library/ff972436.aspx) +- [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md) +- [Visual Studio Developer Center](https://msdn.microsoft.com/vstudio/default) +- [Office Development with Visual Studio](https://msdn.microsoft.com/office/hh133430) diff --git a/docs/general-development/discovery-in-excel-services-rest-api.md b/docs/general-development/discovery-in-excel-services-rest-api.md index dfb344a93..8e8ef0626 100644 --- a/docs/general-development/discovery-in-excel-services-rest-api.md +++ b/docs/general-development/discovery-in-excel-services-rest-api.md @@ -1,153 +1,86 @@ --- title: Discovery in Excel Services REST API -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the discovery mechanisms built into the Excel Services REST API and provides code examples. +ms.date: 05/09/2023 ms.assetid: e3a8e057-f803-446d-81c9-4eb8ef3691e1 -localization_priority: Normal +ms.localizationpriority: medium --- - # Discovery in Excel Services REST API This topic discusses the discovery mechanisms built into the Excel Services REST API. - -> [!NOTE] -> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel -) endpoint. - - - +> [!NOTE] +> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](/graph/api/overview) endpoint. ## Discovery Base URL and Discovery Example -Discovery enables developers and users to discover information about and the content of a workbook manually or programmatically. The discovery mechanism supplies the [Atom](http://tools.ietf.org/html/rfc4287) feed that contains information about the resources in a workbook. By using discovery, you can explore and view the resources in the workbook. Resources that you can explore and access are ranges, charts, tables, and PivotTables. - - - -Following is the construct of the REST URL to a specific element in a workbook: - - - - - +Discovery enables developers and users to discover information about and the content of a workbook manually or programmatically. The discovery mechanism supplies the [Atom](http://tools.ietf.org/html/rfc4287) feed that contains information about the resources in a workbook. By using discovery, you can explore and view the resources in the workbook. Resources that you can explore and access are ranges, charts, tables, and PivotTables. -``` +Following is the construct of the REST URL to a specific element in a workbook: +```http http:///_vti_bin/ExcelRest.aspx/// ``` -As described in the [Basic URI Structure and Path](basic-uri-structure-and-path.md) topic, following is the REST URL to access a workbook named **sampleWorkbook.xlsx** and further view the chart called **SampleChart**: - - - +As described in the [Basic URI Structure and Path](basic-uri-structure-and-path.md) topic, following is the REST URL to access a workbook named **sampleWorkbook.xlsx** and further view the chart called **SampleChart**: - - -``` +```http http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model/Charts('SampleChart') ``` To start and explore the resources in the workbook and view the resources by using discovery, go to the model page by using a URI that follows this example: - - - - - -``` +```http http:///_vti_bin/ExcelRest.aspx///model ``` -Using the "sampleWorkbook.xlsx" example, following is the URI: - - - - +Using the **sampleWorkbook.xlsx** example, following is the URI: - -``` +```http http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model ``` Following is a screen shot of the model page. - - - **Excel Services REST model URL** - - - - - - - ![Excel Services REST model URL](../images/SharePointServer14Con_XLSvcs_RESTModel.gif) - - - + The URL to the model page is where you start the discovery. The model page displays four resource collections that the Excel Services REST API currently supports. The resource collections are ranges, charts, tables, or PivotTables. You can explore those resources in a particular workbook by clicking **Ranges**, **Charts**, **Tables**, or **PivotTables** on the model page. - - - -For example, to access the chart in the workbook by using discovery, do the following: - - - - - - - -1. On the model page, click **Charts**. Clicking the **Charts** link brings another Atom feed—this resulting feed lists all the charts that are available in the sampleWorkbook.xlsx workbook. The sampleWorkbook.xlsx workbook contains three charts named **Chart 1**, **Chart 3**, and **SampleChart**. Therefore, three chart names are listed, as seen in the following screen shot. - - **Excel Services REST discovery chart list** +For example, to access the chart in the workbook by using discovery, do the following: - +1. On the model page, click **Charts**. Clicking the **Charts** link brings another Atom feed—this resulting feed lists all the charts that are available in the sampleWorkbook.xlsx workbook. The sampleWorkbook.xlsx workbook contains three charts named **Chart 1**, **Chart 3**, and **SampleChart**. Therefore, three chart names are listed, as seen in the following screen shot. - ![Excel Services REST discovery chart list](../images/19126dce-b896-4623-8686-92f2fa807283.gif) - + **Excel Services REST discovery chart list** - + ![Excel Services REST discovery chart list](../images/19126dce-b896-4623-8686-92f2fa807283.gif) - -2. On the model page, click **SampleChart**. This displays the chart named **SampleChart** that resides in **sampleWorkbook.xlsx**, as shown in the following screen shot. - - **Viewing chart using REST** +1. On the model page, click **SampleChart**. This displays the chart named **SampleChart** that resides in **sampleWorkbook.xlsx**, as shown in the following screen shot. - + **Viewing chart using REST** - ![Viewing chart using REST](../images/11734dcf-1b57-40cc-b1e8-8b10b7e5d5cb.gif) - + ![Viewing chart using REST](../images/11734dcf-1b57-40cc-b1e8-8b10b7e5d5cb.gif) - - - -3. Similarly, clicking **Chart 1** or **Chart 3** displays the chart with the corresponding name. Clicking **SampleChart** navigates to the actual chart URL. Following is the URL to the **SampleChart** image (as can be seen in the screen shot): - -``` - http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model/Charts('SampleChart%20')?$format=image -``` +1. Similarly, clicking **Chart 1** or **Chart 3** displays the chart with the corresponding name. Clicking **SampleChart** navigates to the actual chart URL. Following is the URL to the **SampleChart** image (as can be seen in the screen shot): + ```http + http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model/Charts('SampleChart%20')?$format=image + ``` ## Atom Feed -Using the [Atom](http://tools.ietf.org/html/rfc4287) feed provided by the REST API gives you an easier way of getting to the data that you are interested in. If you view the source of the webpage, you get the XML. An example from the charts in **sampleWorkbook.xlsx** is shown below. - - - -As can be seen in the XML, the feed contains traversable elements that enable code to discover what elements exist in the workbook. Each Atom entry corresponds to a chart that can be accessed. This same mechanism applies to discovering ranges, tables, and PivotTables. - - - - +Using the [Atom](http://tools.ietf.org/html/rfc4287) feed provided by the REST API gives you an easier way of getting to the data that you are interested in. If you view the source of the webpage, you get the XML. An example from the charts in **sampleWorkbook.xlsx** is shown below. +As can be seen in the XML, the feed contains traversable elements that enable code to discover what elements exist in the workbook. Each Atom entry corresponds to a chart that can be accessed. This same mechanism applies to discovering ranges, tables, and PivotTables. -```XML +```xml - + Charts http://ServerName/_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model/Charts 2010-01-19T19:32:53Z @@ -191,14 +124,8 @@ As can be seen in the XML, the feed contains traversable elements that enable co ``` - ## See also - #### Concepts - - - - - [Resources URI for Excel Services REST API](resources-uri-for-excel-services-rest-api.md) +- [Resources URI for Excel Services REST API](resources-uri-for-excel-services-rest-api.md) diff --git a/docs/general-development/ediscovery-in-sharepoint.md b/docs/general-development/ediscovery-in-sharepoint.md index 85c23e308..357513132 100644 --- a/docs/general-development/ediscovery-in-sharepoint.md +++ b/docs/general-development/ediscovery-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: eDiscovery in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes eDiscovery features in SharePoint and provides details on prerequisites, site holds, the eDiscovery programming model, and eDiscovery types. +ms.date: 06/09/2022 ms.assetid: 45cb324a-75f5-444d-a0fa-5c223df19016 -localization_priority: Priority +ms.localizationpriority: high --- @@ -93,7 +93,7 @@ SharePoint provides a Microsoft .NET server programming model that you can use t **Table 1. eDiscovery types** -|**Type**|**Description**| +|Type|Description| |:-----|:-----| | [Case](https://msdn.microsoft.com/library/Microsoft.Office.Server.Discovery.Case.aspx)
|Represents an eDiscovery case. Associated with a specified [SPWeb](https://msdn.microsoft.com/library/Microsoft.SharePoint.SPWeb.aspx) object, a case can be closed by a specified date or as a specific action. Cases can contain source groups, locations, mailboxes, custodians, saved searches, exports, export configurations for specified IDs, queries, and lists of all of the source groups, custodians, and locations in this **Case** object.
| | [Custodian](https://msdn.microsoft.com/library/Microsoft.Office.Server.Discovery.Custodian.aspx)
|Represents the person who is responsible for keeping records for an eDiscovery case.
| diff --git a/docs/general-development/enhancing-the-bdc-model-file-for-search-in-sharepoint.md b/docs/general-development/enhancing-the-bdc-model-file-for-search-in-sharepoint.md index 4be73106e..d02762ca1 100644 --- a/docs/general-development/enhancing-the-bdc-model-file-for-search-in-sharepoint.md +++ b/docs/general-development/enhancing-the-bdc-model-file-for-search-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Enhancing the BDC model file for Search in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes enhancing the BDC model file for Search in Sharepoint and provides a table of search properties for BDC model files. +ms.date: 06/09/2022 ms.assetid: 3c67b1cf-5fca-4805-a1b5-c9ac1ff8aede -localization_priority: Normal +ms.localizationpriority: medium --- @@ -47,7 +47,7 @@ The following table describes the BDC model properties that are applicable to Se **Table 1. Search properties for BDC model files** -|**Name**|**Metadata Object**|**Description**| +|Name|Metadata Object|Description| |:-----|:-----|:-----| |ShowInSearchUI
|Model
|Specifies that an **LobSystemInstance** element in the model file should be displayed in the search user interface. This value is ignored for custom connectors.
| |InputUriProcessor
|LobSystem
|Specifies the name of the class that processes the input URL before passing it to the connector. Applies to .NET and custom BCS indexing connectors. For more information, see [Creating a Custom Indexing Connector](https://msdn.microsoft.com/library/ec2df34d-178c-4ae1-a2b0-a6af04ee57bd%28Office.15%29.aspx).
| diff --git a/docs/general-development/excel-services-alerts.md b/docs/general-development/excel-services-alerts.md index 4084c756c..0fe8939f2 100644 --- a/docs/general-development/excel-services-alerts.md +++ b/docs/general-development/excel-services-alerts.md @@ -1,12 +1,12 @@ --- title: Excel Services Alerts -ms.date: 09/25/2017 +description: Describes Excel service alerts and provides details on "stop" alerts, "continue" alerts, exceptions, and error codes. +ms.date: 06/09/2022 keywords: errors f1_keywords: - errors -ms.prod: sharepoint ms.assetid: a4e7030b-05c2-484e-b21f-46cba937b803 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/excel-services-architecture.md b/docs/general-development/excel-services-architecture.md index 0f5ec3552..9604e1dee 100644 --- a/docs/general-development/excel-services-architecture.md +++ b/docs/general-development/excel-services-architecture.md @@ -1,12 +1,12 @@ --- title: Excel Services Architecture -ms.date: 09/25/2017 +description: Describes the Excel Services architecture and provides details on web front-end and back-end application servers, Excel web access, and more. +ms.date: 06/09/2022 keywords: excel services design f1_keywords: - excel services design -ms.prod: sharepoint ms.assetid: e0349b4a-2d52-46c4-a167-801e9c24eaca -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/excel-services-best-practices.md b/docs/general-development/excel-services-best-practices.md index a049a1453..436f5ccbc 100644 --- a/docs/general-development/excel-services-best-practices.md +++ b/docs/general-development/excel-services-best-practices.md @@ -1,237 +1,124 @@ --- title: Excel Services Best Practices -ms.date: 09/25/2017 +description: Describes the best practices for working with Excel Services and provides general advice and details on mitigating threats. +ms.date: 05/09/2023 keywords: guidelines f1_keywords: - guidelines -ms.prod: sharepoint ms.assetid: 56fa3913-c156-49da-bed0-a6a106fc129f -localization_priority: Normal +ms.localizationpriority: medium --- - # Excel Services Best Practices This topic contains a list of best-practice recommendations for working with Excel Services. - - - - ## Mitigating Threats - ### Anonymous Access and Information Disclosure The following settings combination gives anonymous users access to any files in the share to which the process account has access. Therefore, the following combination of settings is not recommended, because of the possibility of information disclosure: - - - - Anonymous access to Microsoft SharePoint Foundation is turned on. - - - You have a UNC trusted location and the **Process account** is turned on. - + > [!NOTE] > The **Process account** is a global Excel Services setting that affects all trusted locations. - - - - ### To view the Process account option - 1. On the **Start** menu, click **All Programs**. - - -2. Point to **Microsoft SharePoint 2010 Products**, and then click **SharePoint Central Administration**. - - -3. Under **Application Management**, click **Manage service applications**. - - -4. On the Manage Service Applications page, click **Excel Services Application**. - - -5. On the **Excel Services Application** page, click **Global Settings**. - - -6. In the **Security** section, look under **File Access Method** for the **Process account** option. - - +1. Point to **Microsoft SharePoint 2010 Products**, and then click **SharePoint Central Administration**. +1. Under **Application Management**, click **Manage service applications**. +1. On the Manage Service Applications page, click **Excel Services Application**. +1. On the **Excel Services Application** page, click **Global Settings**. +1. In the **Security** section, look under **File Access Method** for the **Process account** option. ### Denial of Service Attack In a denial of service attack against a Web service, an attacker generates very large, individual requests against the Web service. The purpose is to attempt to exploit the limits of one or more Web service input values. - - - + We recommend that you use the Microsoft Internet Information Services (IIS) setting to set the maximum request size for the Web service. - - - + Use the **maxRequestLength** attribute in the **httpRuntime** element in the **system.web** element to prevent denial of service attacks that are caused by users posting large files to the server. The default size is 4096 KB (4 MB). - - - + For more information, see [\ Element](https://msdn.microsoft.com/library/e9b81350-8aaf-47cc-9843-5f7d0c59f369.aspx) and [\ Element](https://msdn.microsoft.com/library/fd52b2c5-5014-4e6f-b869-4ea666dc83d6.aspx). - - - ### Sniffing Between the Calling Application and the Web Service Computer If the calling application and Excel Web Services are deployed to different computers, an attacker can listen to the network traffic for data transfer between the calling application and the Web service. This threat is also called "sniffing" or "eavesdropping." - - - + To help mitigate this threat, we recommend that you: - - - - Use Secure Sockets Layer (SSL) to set up a secure channel to protect data transfer between the client and the server. The SSL protocol helps to protect data against packet sniffing by anyone with physical access to the network. - - - Physically protect the relevant network if a custom application using Excel Web Services is running in a confined network—for example, if Excel Web Services is deployed on a Web front-end computer within the enterprise. - - -For more information, see [Securing Your Network](https://msdn.microsoft.com/library/af62ece0-0dd7-4b8e-ad12-4d13f2d60816.aspx) and [SOAP Security](https://msdn.microsoft.com/library/aa912494.aspx). - - - + +For more information, see [Securing Your Network](https://msdn.microsoft.com/library/af62ece0-0dd7-4b8e-ad12-4d13f2d60816.aspx) and [SOAP Security](https://msdn.microsoft.com/library/aa912494.aspx). + For information about Excel Services topology, scalability, performance, and security, see the Microsoft SharePoint Server 2010 TechCenter. - - - ### Spoofing We recommend that you use SSL to help mitigate the threats of hijacked Web service Internet Protocol (IP) addresses and ports, and to help prevent attackers from receiving requests and replying on behalf of the Web service. - - - + The SSL certificate is matched against a few properties, one of which is the IP address from which the message is coming. The attacker cannot spoof the IP address if it does not have the Web service SSL certificate. - - - + For more information, see [Securing Your Network](https://msdn.microsoft.com/library/af62ece0-0dd7-4b8e-ad12-4d13f2d60816.aspx). - - - ## Excel Services User-Defined Functions (UDFs) - ### Strong Name Dependencies In some cases, a user-defined function (UDF) assembly depends on other assemblies that are deployed with it. These dependent DLLs load successfully if they are in the global assembly cache, or if they are located in the same folder as the UDF assembly. - - - + In the latter case, however, it is possible for the load to fail if Excel Calculation Services has already loaded another assembly with the same name. (It fails either because the assembly is not strongly named, or because another version with the same name has been deployed and loaded.) - - - + Consider the following scenario, with the following directory structure: - - - -1. C:\\Udfs\\Udf01 - +1. ***C:\\Udfs\\Udf01*** + The Udf01 folder contains: - - - Udf01.dll - - - - dependent.dll (not strongly named) - - + + - Udf01.dll + - dependent.dll (not strongly named) The Udf01.dll file has a dependency on the dependent.dll file. - - -2. C:\\Udfs\\Udf02 - + +1. **C:\\Udfs\\Udf02** + The Udf02 folder contains: - - - Udf02.dll (which depends on Interop.dll) - - - - dependent.dll (which is not strongly named) - - + + - Udf02.dll (which depends on Interop.dll) + - dependent.dll (which is not strongly named) The Udf02.dll file has a dependency on the dependent.dll file. Udf01.dll's dependency and Udf02.dll's dependency share the same name. But Udf02.dll's dependent.dll file is not the same as Udf01.dll's dependent.dll file. - - + Assume the following flow: - - - - -1. Udf01.dll is the first DLL to be loaded. Excel Calculation Services looks for dependent.dll and loads Udf01.dll's dependency, which in this case is dependent.dll. - - -2. Udf02.dll is loaded after Udf01.dll. Excel Calculation Services sees that Udf02.dll depends on dependent.dll. However, a DLL with the name "dependent.dll" is already loaded. Therefore, Udf02.dll's dependent.dll file is not loaded, and the currently loaded dependent.dll file is used as the dependency. - - + +1. Udf01.dll is the first DLL to be loaded. Excel Calculation Services looks for dependent.dll and loads Udf01.dll's dependency, which in this case is dependent.dll. +1. Udf02.dll is loaded after Udf01.dll. Excel Calculation Services sees that Udf02.dll depends on dependent.dll. However, a DLL with the name "dependent.dll" is already loaded. Therefore, Udf02.dll's dependent.dll file is not loaded, and the currently loaded dependent.dll file is used as the dependency. + As a result, the object—in this case, the dependent.dll file that Udf02.dll needs—is not loaded into memory. - - - + To avoid name collision, we recommend that you strongly name your dependencies, and name them uniquely. - - - ## General - ### Naming Managed-Code DLLs To ensure that your assembly names are unique, use the fully qualified class name, following the [Namespace Naming Guidelines](https://msdn.microsoft.com/library/c08bc0d8-9b3a-4564-9af6-71699f62e00d.aspx). - - - -For example, use CompanyName.Hierarchichal.Namespace.ClassName instead ofNamespace.ClassName. - - - -## See also +For example, use `CompanyName.Hierarchichal.Namespace.ClassName` instead of `Namespace.ClassName`. +## See also #### Tasks - - - - - [How to: Trust a Location](how-to-trust-a-location.md) +- [How to: Trust a Location](how-to-trust-a-location.md) #### Concepts - - - - - [Excel Services Architecture](excel-services-architecture.md) - - - - [Accessing the SOAP API](accessing-the-soap-api.md) - - - - [Excel Services Alerts](excel-services-alerts.md) - - - - [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) - - - - [Excel Services Blogs, Forums, and Resources](excel-services-blogs-forums-and-resources.md) +- [Excel Services Architecture](excel-services-architecture.md) +- [Accessing the SOAP API](accessing-the-soap-api.md) +- [Excel Services Alerts](excel-services-alerts.md) +- [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) +- [Excel Services Blogs, Forums, and Resources](excel-services-blogs-forums-and-resources.md) diff --git a/docs/general-development/excel-services-blogs-forums-and-resources.md b/docs/general-development/excel-services-blogs-forums-and-resources.md index d4ae8038c..f938e4ce4 100644 --- a/docs/general-development/excel-services-blogs-forums-and-resources.md +++ b/docs/general-development/excel-services-blogs-forums-and-resources.md @@ -1,83 +1,44 @@ --- title: Excel Services Blogs, Forums, and Resources -ms.date: 09/25/2017 +description: Provides links to Excel Services blogs, forums, and resources, as well as links to articles on Excel Services concepts. +ms.date: 06/27/2022 keywords: blogger f1_keywords: - blogger -ms.prod: sharepoint ms.assetid: c0b137cd-126d-4c74-a3f7-eb9debe3c35f -localization_priority: Normal +ms.localizationpriority: medium --- - - # Excel Services Blogs, Forums, and Resources The following are links to blogs, forums, and additional resources related to Excel Services and SharePoint: - - - - - -|**Blog Name**|**Links**| -|:-----|:-----| -|Cum Grano Salis
| [Home page](https://blogs.msdn.com/cumgranosalis/)
[Excel Services page](https://blogs.msdn.microsoft.com/cumgranosalis/tag/excel-services/)
| -|Microsoft Excel: The official blog of the Microsoft Excel product team
| [Home page](https://www.microsoft.com/microsoft-365/blog/excel)
| - +| Blog Name | Links | +| :--------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------- | +| Cum Grano Salis | [Home page](https://blogs.msdn.com/cumgranosalis/) [Excel Services page](/archive/blogs/cumgranosalis/#excel-services) | +| Microsoft Excel: The official blog of the Microsoft Excel product team | [Home page](https://www.microsoft.com/microsoft-365/blog/excel) | +| Forum Name | Links | +| :----------------------------------- | :------------------------------------------------------------------------------------------------------------------ | +| SharePoint - Excel Services | [Excel Services forum home page](/sharepoint/dev/general-development/excel-services-blogs-forums-and-resources) | +| SharePoint Products and Technologies | [List of SharePoint Products and Technologies forums](https://social.msdn.microsoft.com/forums/category/sharepoint) | -|**Forum Name**|**Links**| -|:-----|:-----| -|SharePoint - Excel Services
| [Excel Services forum home page](/sharepoint/dev/general-development/excel-services-blogs-forums-and-resources)
| -|SharePoint Products and Technologies
| [List of SharePoint Products and Technologies forums](https://social.msdn.microsoft.com/forums/category/sharepoint)
| - - - -|**Additional Resources**|**Links**| -|:-----|:-----| -|Excel Services Resource Center
| [Excel Services Resource Center on MSDN](https://msdn.microsoft.com/office/bb203828.aspx)
| -|IT Pro \\ Administration Documentation
| [TechNet](https://technet.microsoft.com/library/ee424401%28office.14%29.aspx)
| -|Microsoft Excel Online, part of Office Online, also supports Excel workbooks in the browser.
|For more information about Excel Online, see the [documentation](https://technet.microsoft.com/library/ee855124.aspx) on Technet.
| - +| Additional Resources | Links | +| :------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | +| IT Pro \\ Administration Documentation | [TechNet](https://technet.microsoft.com/library/ee424401%28office.14%29.aspx) | +| Microsoft Excel Online, part of Office Online, also supports Excel workbooks in the browser. | For more information about Excel Online, see the [documentation](https://technet.microsoft.com/library/ee855124.aspx) on Technet. | ## See also - #### Concepts +- [Excel Services Overview](excel-services-overview.md) +- [Excel Services Development Roadmap](excel-services-development-roadmap.md) +- [Excel Services Architecture](excel-services-architecture.md) +- [Excel Services Best Practices](excel-services-best-practices.md) +- [Excel Services Alerts](excel-services-alerts.md) +- [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) - - - - [Excel Services Overview](excel-services-overview.md) - - - - [Excel Services Development Roadmap](excel-services-development-roadmap.md) - - - - [Excel Services Architecture](excel-services-architecture.md) - - - - [Excel Services Best Practices](excel-services-best-practices.md) - - - - [Excel Services Alerts](excel-services-alerts.md) - - - - [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) #### Other resources - - - - - [Walkthrough: Developing a Custom Application Using Excel Web Services](walkthrough-developing-a-custom-application-using-excel-web-services.md) - - - - [Unsupported Features in Excel Services](https://msdn.microsoft.com/library/5868e672-4786-4fed-9168-07ff538f6f5c%28Office.15%29.aspx) +- [Walkthrough: Developing a Custom Application Using Excel Web Services](walkthrough-developing-a-custom-application-using-excel-web-services.md) +- [Unsupported Features in Excel Services](https://msdn.microsoft.com/library/5868e672-4786-4fed-9168-07ff538f6f5c%28Office.15%29.aspx) diff --git a/docs/general-development/excel-services-development-roadmap.md b/docs/general-development/excel-services-development-roadmap.md index cb0e00517..dc34273fa 100644 --- a/docs/general-development/excel-services-development-roadmap.md +++ b/docs/general-development/excel-services-development-roadmap.md @@ -1,12 +1,12 @@ --- title: Excel Services Development Roadmap -ms.date: 09/25/2017 +description: Provides a roadmap for developing with Excel Services, focusing on Excel Web Service and the REST API. +ms.date: 06/09/2022 keywords: roadmap f1_keywords: - roadmap -ms.prod: sharepoint ms.assetid: 5c789f58-9cdb-4601-9047-9c6f83f2fbba -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/excel-services-ecmascript-javascript-jscript.md b/docs/general-development/excel-services-ecmascript-javascript-jscript.md index 9f6937d3c..6df58ec48 100644 --- a/docs/general-development/excel-services-ecmascript-javascript-jscript.md +++ b/docs/general-development/excel-services-ecmascript-javascript-jscript.md @@ -1,9 +1,9 @@ --- title: Excel Services ECMAScript (JavaScript, JScript) -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes ECMAScript (JavaScript and JScript) in Excel Services and provides links to ECMAScript tutorials. +ms.date: 06/09/2022 ms.assetid: 2355ffd0-8190-4385-955c-3f72bce7efc6 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/excel-services-ecmascript-overview.md b/docs/general-development/excel-services-ecmascript-overview.md index 9cd373897..7e56e839e 100644 --- a/docs/general-development/excel-services-ecmascript-overview.md +++ b/docs/general-development/excel-services-ecmascript-overview.md @@ -1,9 +1,9 @@ --- title: Excel Services ECMAScript Overview -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Provides an overview on ECMAScript in Excel Services and describes how to use the ECMAScript object model. +ms.date: 06/09/2022 ms.assetid: f8c1be86-df19-44c3-a3bc-c0da2b80df10 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/excel-services-error-codes.md b/docs/general-development/excel-services-error-codes.md index 1497871f8..0d11ea32f 100644 --- a/docs/general-development/excel-services-error-codes.md +++ b/docs/general-development/excel-services-error-codes.md @@ -1,26 +1,26 @@ --- title: Excel Services error codes +description: Excel Services generates errors and error messages in the SOAP exception based on errors that occur in Excel Services. The following table shows the errors that are accessible when calls to the Excel Web Services methods throw a SOAP exception. ms.date: 09/25/2017 keywords: alerts f1_keywords: - alerts -ms.prod: sharepoint ms.assetid: ff128d67-f3ac-4a8f-ae8e-1e19e343014e -localization_priority: Priority +ms.localizationpriority: high --- # Excel Services error codes -Excel Services generates errors and error messages in the SOAP exception based on errors that occur in Excel Services. The following table shows the errors that are accessible when calls to the Excel Web Services methods throw a SOAP exception. +Excel Services generates errors and error messages in the SOAP exception based on errors that occur in Excel Services. The following table shows the errors that are accessible when calls to the Excel Web Services methods throw a SOAP exception. -You use the [SubCode](https://docs.microsoft.com/dotnet/api/system.web.services.protocols.soapexception.subcode?view=netframework-4.7.2) property of the **SoapException** class to capture the error codes. For more information about using the **SubCode** property to capture error codes, see [How to: Use the SubCode Property to Capture Error Codes](how-to-use-the-subcode-property-to-capture-error-codes.md) +You use the [SubCode](/dotnet/api/system.web.services.protocols.soapexception.subcode) property of the **SoapException** class to capture the error codes. For more information about using the **SubCode** property to capture error codes, see [How to: Use the SubCode Property to Capture Error Codes](how-to-use-the-subcode-property-to-capture-error-codes.md) For more information about Excel Services alerts, see [Excel Services Alerts](excel-services-alerts.md). ## Error codes -The following table lists the error codes for Excel Web Services alerts and the associated messages, explanation, and resolutions. - +The following table lists the error codes for Excel Web Services alerts and the associated messages, explanation, and resolutions. + |**Error Code**|**Message**|**Explanation**|**Resolution**| |:-----|:-----|:-----|:-----| |ApiInvalidArgument
|Invalid value to argument: {0}
|An invalid value for an argument was passed into the API call.
0 = name of the argument. Its value is invalid.
|Use a valid value for the argument.
| @@ -50,10 +50,10 @@ The following table lists the error codes for Excel Web Services alerts and the |SheetRangeMismatch
|The sheet provided as the sheet argument is not the same as the sheet specified in the range argument.
|The name of the sheet passed in for a _sheetName_ parameter does not match the sheet location specified in the _rangeName_ parameter.
|When specifying a sheet in both the range and sheet arguments, ensure that the sheet names are the same. For example, `Calculate(Sheet1, Sheet1!Range("A1"))`.
| |SpecifiedRangeNotFound
|The requested range does not exist in the sheet.
|The range that was passed into a method with the A1 suffix (**SetCellA1**, **SetRangeA1**, **GetCellA1**, and **GetRangeA1**) could not be found.
|Make sure the range specified exists in the sheet.
| |WorkbookNotSupported
|The file you selected cannot be opened because it contains feature(s) that are not supported by Excel Services. One or more of the following unsupported features were detected in the workbook:
{0}
|The workbook contains unsupported features.
0 = a \\n separated list of unsupported feature names.
|Make sure the workbook does not contain features that are not supported by Excel Services.
| - + ## See also - + - [How to: Use the SubCode Property to Capture Error Codes](how-to-use-the-subcode-property-to-capture-error-codes.md) - [Excel Services Alerts](excel-services-alerts.md) - [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) diff --git a/docs/general-development/excel-services-in-sharepoint.md b/docs/general-development/excel-services-in-sharepoint.md index c75fe3de1..907f02be8 100644 --- a/docs/general-development/excel-services-in-sharepoint.md +++ b/docs/general-development/excel-services-in-sharepoint.md @@ -1,89 +1,41 @@ --- title: Excel Services in SharePoint +description: Learn about the new capabilities in Excel Services in SharePoint and how you can use them in your own development efforts. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: f7e13fcb-a86a-4a1e-af59-3bace98ce9d7 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Excel Services in SharePoint + Learn about the new capabilities in Excel Services in SharePoint and how you can use them in your own development efforts. + ## What's new in Excel Services for developers - SharePoint brings new technologies to Excel Services─such as ECMAScript (JavaScript, JScript) UDFs and Excel Interactive View─and new enhancements to existing technologies, such as ODATA for REST, and updates to the ECMAScript (JavaScript, JScript) Object Model (JSOM) API. - - - ### JavaScript UDFs - -Excel Services already lets you create user-defined functions (UDFs) using managed code. Excel Services in SharePoint introduces a new kind of UDF—ECMAScript (JavaScript, JScript) UDFs. JavaScript UDFs run in the context of the browser: either in a Excel workbook that is hosted in an Excel Web Access web part on SharePoint, or in a workbook that is embedded on a host webpage. - - - +Excel Services already lets you create user-defined functions (UDFs) using managed code. Excel Services in SharePoint introduces a new kind of UDF—ECMAScript (JavaScript, JScript) UDFs. JavaScript UDFs run in the context of the browser: either in a Excel workbook that is hosted in an Excel Web Access web part on SharePoint, or in a workbook that is embedded on a host webpage. ### OData in Excel Services - SharePoint Server 2010 introduced the REST API for use in getting and setting information in Excel Workbooks stored in SharePoint document libraries. SharePoint adds a new way to request data from Excel Services that uses the Open Data Protocol (OData) which you can use to get information about Excel Services resources. This new service relies heavily on the existing Excel Services REST API. - - - - -### - > [!NOTE] -> The Excel Interactive View feature has been disabled. For information about removing this feature from your website, see [Removing Excel Interactive View from a webpage](removing-excel-interactive-view-from-a-webpage.md). - - - - +> The Excel Interactive View feature has been disabled. For information about removing this feature from your website, see [Removing Excel Interactive View from a webpage](removing-excel-interactive-view-from-a-webpage.md). ## In this section - - -- [Getting Started with Excel Services](getting-started-with-excel-services.md) - - -- [Excel Web Services](excel-web-services.md) - - -- [Excel Services User-Defined Functions](excel-services-user-defined-functions.md) - - -- [Excel Web Access](excel-web-access.md) - - -- [Excel Services ECMAScript (JavaScript, JScript)](excel-services-ecmascript-javascript-jscript.md) - - -- [Excel Services REST API](excel-services-rest-api.md) - - -- [General Guidelines](general-guidelines.md) - - -- [Removing Excel Interactive View from a webpage](removing-excel-interactive-view-from-a-webpage.md) - - +- [Getting Started with Excel Services](getting-started-with-excel-services.md) +- [Excel Web Services](excel-web-services.md) +- [Excel Services User-Defined Functions](excel-services-user-defined-functions.md) +- [Excel Web Access](excel-web-access.md) +- [Excel Services ECMAScript (JavaScript, JScript)](excel-services-ecmascript-javascript-jscript.md) +- [Excel Services REST API](excel-services-rest-api.md) +- [General Guidelines](general-guidelines.md) +- [Removing Excel Interactive View from a webpage](removing-excel-interactive-view-from-a-webpage.md) ## See also - - - -- [Add SharePoint capabilities](add-sharepoint-capabilities.md) - - -- [Office 2013 and SharePoint application services](office-and-sharepoint-application-services.md) - - - - - - +- [Add SharePoint capabilities](add-sharepoint-capabilities.md) +- [Office 2013 and SharePoint application services](office-and-sharepoint-application-services.md) diff --git a/docs/general-development/excel-services-known-issues-and-tips.md b/docs/general-development/excel-services-known-issues-and-tips.md index 82ec5ef5e..66fa55c00 100644 --- a/docs/general-development/excel-services-known-issues-and-tips.md +++ b/docs/general-development/excel-services-known-issues-and-tips.md @@ -1,328 +1,163 @@ --- title: Excel Services Known Issues and Tips -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes known issues and tips for working with Excel Services and provides links to related documentation. +ms.date: 05/09/2023 ms.assetid: b4a41437-4f00-4f88-8510-627fa0252004 -localization_priority: Normal +ms.localizationpriority: medium --- - # Excel Services Known Issues and Tips The following are a known issues and tips for working with Excel Services. - - - - ## Excel Web Service - ### Viewing the WSDL Location You can view the Excel Web Services Web Services Description Language (WSDL) page by navigating to the following URL on the server: `http:////_vti_bin/excelservice.asmx?WSDL` - - - -If you do not have a custom site, you can view the WSDL by using the following URL: - - - - `http:///_vti_bin/excelservice.asmx?WSDL` - - - -For more information, see [Accessing the SOAP API](accessing-the-soap-api.md). - - - + +If you do not have a custom site, you can view the WSDL by using the following URL: `http:///_vti_bin/excelservice.asmx?WSDL` + +For more information, see [Accessing the SOAP API](accessing-the-soap-api.md). ### Understanding Excel Web Services and Namespaces The following are Excel web services and namespaces: - - - - The single web service object that contains all the API methods: **ExcelService** - - -- The schema namespace: `http://schemas.microsoft.com/office/excel/server/webservices` - - -- The web service page name: ExcelService.asmx - - +- The schema namespace: `http://schemas.microsoft.com/office/excel/server/webservices` +- The web service page name: **ExcelService.asmx** ### Linking Locally or to a Web Service -In certain scenarios, you should link directly to Microsoft.Office.Excel.Server.WebServices.dll and access it as you would any local assembly, instead of calling it as a web service through SOAP over HTTP. - - - +In certain scenarios, you should link directly to Microsoft.Office.Excel.Server.WebServices.dll and access it as you would any local assembly, instead of calling it as a web service through SOAP over HTTP. + For more information and guidelines on when to use direct linking, see [Loop-Back SOAP Calls and Direct Linking](loop-back-soap-calls-and-direct-linking.md). - - - ### Understanding Invalid Characters The calls to the **GetCell** and **GetRange** methods will fail if the workbook cells contain characters that are invalid in an XML response. - - - + For example, if a cell contains characters with hexadecimal values 0x1, 0x2 ... 0x8, the ASP.NET parser will throw an exception that the value of the character being written to the XML response is invalid: - - - - **System.InvalidOperationException: Client found response content type of 'text/html; charset=utf-8', but expected 'text/xml'. The request failed with the error message: -- ' ', hexadecimal value 0x01, is an invalid character.** - - - + +**System.InvalidOperationException: Client found response content type of 'text/html; charset=utf-8', but expected 'text/xml'. The request failed with the error message: -- \ \ \' ', hexadecimal value 0x01, is an invalid character.** + This behavior is expected. The XML specification that defines which characters are allowed in a valid XML response specifies that hexadecimal values 0x1, 0x2 ... 0x8 are invalid XML characters: - - - - **Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */** - - - -For more information, see [W3C Extensible Markup Language (XML) Specification](http://www.w3.org/TR/REC-xml) (http://www.w3.org/TR/REC-xml#NT-Char). - - - + +**Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */** + +For more information, see [W3C Extensible Markup Language (XML) Specification](http://www.w3.org/TR/REC-xml#NT-Char). ### Saving a Workbook When you make changes to a workbook—for example, by setting values to a range using Excel Web Services—the changes to the workbook are preserved only for that particular session. The changes are not saved or persisted back to the original workbook. When the current workbook session ends (for example, when you call the **CloseWorkbook** method, or the session times out), changes you made will be lost. - - - + If you want to save changes to a workbook, you can use the **GetWorkbook** method and then save the workbook using the API of the destination file store. For more information, see [How to: Get an Entire Workbook or a Snapshot](how-to-get-an-entire-workbook-or-a-snapshot.md) and [How to: Save a Workbook](https://msdn.microsoft.com/library/feb74f7a-2d8f-4672-911b-de85f8852aea%28Office.15%29.aspx). - - - ### Understanding the Url Property of an Excel Web Services Proxy Class -Do not use the **Url** property of an Excel Web Services proxy for the location of the workbook you want to open. The **Url** property of a web service proxy class generated by Visual Studio gets or sets the base URL of the XML web service the client is requesting. In the case of Excel Web Services, this is usually: - - - - `http:///_vti_bin/ExcelService.asmx` - - - -To specify the location of a workbook, use the **OpenWorkbook** method instead of the **Url** property as shown in the following code example. - - - - +Do not use the **Url** property of an Excel Web Services proxy for the location of the workbook you want to open. The **Url** property of a web service proxy class generated by Visual Studio gets or sets the base URL of the XML web service the client is requesting. In the case of Excel Web Services, this is usually: `http:///_vti_bin/ExcelService.asmx` +To specify the location of a workbook, use the **OpenWorkbook** method instead of the **Url** property as shown in the following code example. -``` - +```csharp //Instantiate the web service and make a status array object. ExcelService xlservice = new ExcelService(); -string sheetName = "Sheet1"; +string sheetName = "Sheet1"; //Set the path to the workbook to open. //TODO: Change the path to the workbook - //to point to a workbook you have access to. +//to point to a workbook you have access to. //The workbook must be in a trusted location. -string targetWorkbookPath = - "http://myserver02/example/Shared%20Documents/Book1.xlsx"; +string targetWorkbookPath = "http://myserver02/example/Shared%20Documents/Book1.xlsx"; //Set credentials for requests. xlservice.Credentials = System.Net.CredentialCache.DefaultCredentials; -//Call the open workbook, and point to the trusted +//Call the open workbook, and point to the trusted //location of the workbook to open. -string sessionId = xlservice.OpenWorkbook(targetWorkbookPath, "en-US", - "en-US", out outStatus); - +string sessionId = xlservice.OpenWorkbook(targetWorkbookPath, "en-US", "en-US", out outStatus); ``` -For more information, see [WebClientProtocol.Url Property](https://go.microsoft.com/fwlink/?LinkId=64908) (https://msdn.microsoft.com/library/default.asp?url=/library/cpref/html/frlrfSystemWebServicesProtocolsWebClientProtocolClassUrlTopic.asp). - - - +For more information, see [WebClientProtocol.Url Property](https://msdn.microsoft.com/library/default.asp?url=/library/cpref/html/frlrfSystemWebServicesProtocolsWebClientProtocolClassUrlTopic.asp). ## Understanding Security - ### Using Workbook Permissions Beware of the following issues regarding workbook permissions: - - - - Excel Web Services uses the Microsoft SharePoint Foundation authorization scheme to verify that the caller has the right to call APIs (that is, make web service calls) on the SharePoint Foundation site (that is, the website where Excel Web Services is located) remotely. If the caller does not have the "Use Remote API" right, the Excel Web Services returns an "HTTP 401 (Unauthorized)" error, and logs an "API authorization failed" event. Excel Web Services performs these authorization checks only for calls that originate as SOAP calls. Calls from applications that link locally to Microsoft.Office.Excel.Server.WebServices.dll are not considered remote calls. Therefore, they are not subject to authorization checks. However, if the application that links locally to Microsoft.Office.Excel.Server.WebServices.dll is itself a SOAP service, and handles the service's SOAP calls, the call to Excel Web Services will seem like a SOAP call (even though the application links directly to Microsoft.Office.Excel.Server.WebServices.dll). In this scenario, Excel Web Services will perform the authorization checks. - - - To get the entire workbook (for example, by calling the **GetWorkbook** method using the `WorkbookType.FullWorkbook` argument), the caller needs "open" permission for the workbook or "read" permission in a file share. - - - To call the **GetApiVersion** method, no permission is necessary. - - - For the rest of the Excel Web Services methods, besides credentials, the caller needs "view" permission (in SharePoint Foundation) or "read" permission (in a file share) for the workbook. - - ### Trusted Location The workbooks you want to open in Excel Services must be placed in a trusted location. If not, the Excel Web Services calls to open the workbook will fail. - - - + For information about how to trust a location, see [How to: Trust a Location](how-to-trust-a-location.md) and [How to: Trust Workbook Locations Using Script](https://msdn.microsoft.com/library/79ab6ced-7a0c-4275-b852-bb246fc6be57%28Office.15%29.aspx). - - - ## Visual Studio - ### Microsoft Visual Studio Proxy Behavior -When Microsoft Visual Studio creates a proxy class for a client project that calls Excel Web Services, it has the following behavior: - - - +When Microsoft Visual Studio creates a proxy class for a client project that calls Excel Web Services, it has the following behavior: + If a method has no return value, and one or more **out** arguments, the first **out** argument is moved to become the return value. That is, the method in the proxy class will have one less **out** argument in the method signature. But the signature will have a return value with the type and content of what used to be the first **out** argument. - - - + The affected Excel Web Services methods are: - - - - **Calculate** - - - **CalculateA1** - - - **CalculateWorkbook** - - - **CancelRequest** - - - **CloseWorkbook** - - - **GetSessionInformation** - - - **Refresh** - - - **SetCell** - - - **SetCellA1** - - - **SetRange** - - - **SetRangeA1** - - ## Excel Services User-Defined Functions - ### Global Assembly Cache is Checked First, Then the Local Folder By design in the Microsoft .NET Framework, an assembly in a global assembly cache will be loaded instead of the same assembly in a local folder. The common language runtime will look for an assembly in the global assembly cache first before searching in the local folders. - - - + Therefore, if an assembly is installed in the global assembly cache and is in the UDF list but disabled (or removed from the UDF list altogether), and an identical assembly is installed in a local folder and enabled, the assembly in the global assembly cache will still get loaded and used instead of the same assembly in the local folder. - - - + This does not affect upgrade scenarios in which the assembly version has been modified, which means the assembly is not the same anymore. - - - ## General - ### Order of Strings in Sharedstring.xml is Not Maintained -Excel Services does not maintain the original order of strings in a workbook shared-string table (the Sharedstrings.xml part within the Microsoft Office Excel XML Format file). For example, execute the following steps: - - - - -1. Open a file using Excel. - - -2. Save the file in .xlsx file format. - - -3. Upload the file to a document library that is a trusted location. - - -4. Open the file in the document library by using Excel Web Access. - - -5. Click **Open in Excel**. - - -6. Save the file in .xlsx file format. - - -If you compare the Sharedstrings.xml file created in Step 2 with the one created in Step 6, you will find the order of the Sharedstrings.xml parts might be different. - - - +Excel Services does not maintain the original order of strings in a workbook shared-string table (the **Sharedstrings.xml** part within the Microsoft Office Excel XML Format file). For example, execute the following steps: + +1. Open a file using Excel. +1. Save the file in .xlsx file format. +1. Upload the file to a document library that is a trusted location. +1. Open the file in the document library by using Excel Web Access. +1. Click **Open in Excel**. +1. Save the file in .xlsx file format. + +If you compare the **Sharedstrings.xml** file created in Step 2 with the one created in Step 6, you will find the order of the **Sharedstrings.xml** parts might be different. + You should not write an application that assumes the order of strings in the shared-string table is fixed. For example, you cannot replace the shared-string table with an existing localized translation table. You must adjust to the new ordering of strings in the shared-string table. - - - ## See also - #### Tasks +- [How to: Trust a Location](how-to-trust-a-location.md) - - - - [How to: Trust a Location](how-to-trust-a-location.md) #### Concepts - - - - - [Excel Services Best Practices](excel-services-best-practices.md) - - - - [Excel Services Alerts](excel-services-alerts.md) - - - - [Excel Services Architecture](excel-services-architecture.md) - - - - [Supported and Unsupported Features](supported-and-unsupported-features.md) - - - - [Accessing the SOAP API](accessing-the-soap-api.md) - - - - [Excel Services Blogs, Forums, and Resources](excel-services-blogs-forums-and-resources.md) +- [Accessing the SOAP API](accessing-the-soap-api.md) +- [Excel Services Alerts](excel-services-alerts.md) +- [Excel Services Architecture](excel-services-architecture.md) +- [Excel Services Best Practices](excel-services-best-practices.md) +- [Excel Services Blogs, Forums, and Resources](excel-services-blogs-forums-and-resources.md) +- [Supported and Unsupported Features](supported-and-unsupported-features.md) diff --git a/docs/general-development/excel-services-overview.md b/docs/general-development/excel-services-overview.md index 5bc2b52e2..0a6a80f2e 100644 --- a/docs/general-development/excel-services-overview.md +++ b/docs/general-development/excel-services-overview.md @@ -1,9 +1,9 @@ --- title: Excel Services Overview +description: "Excel Services is a service application that enables you to load, calculate, and display Microsoft Excel workbooks on Microsoft SharePoint." ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 5fa22ebb-e507-4ffc-a425-e755502feae2 -localization_priority: Priority +ms.localizationpriority: high --- @@ -283,7 +283,7 @@ From there you can use OData system query options to get specific information ab - [Walkthrough: Developing a Custom Application Using Excel Web Services](walkthrough-developing-a-custom-application-using-excel-web-services.md) -- [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.md) +- [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.yml) - [Unsupported Features in Excel Services](https://msdn.microsoft.com/library/5868e672-4786-4fed-9168-07ff538f6f5c%28Office.15%29.aspx) diff --git a/docs/general-development/excel-services-rest-api-overview.md b/docs/general-development/excel-services-rest-api-overview.md index 3eda94642..7062be383 100644 --- a/docs/general-development/excel-services-rest-api-overview.md +++ b/docs/general-development/excel-services-rest-api-overview.md @@ -1,9 +1,9 @@ --- title: Excel Services REST API Overview -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Provides an overview of the Excel Services REST API and provides a link to an article about the Microsoft Graph REST API endpoint. +ms.date: 06/09/2022 ms.assetid: 5872f311-e180-4578-ac80-2519c1081951 -localization_priority: Priority +ms.localizationpriority: high --- @@ -12,7 +12,7 @@ localization_priority: Priority The REST API in Excel Services is new in Microsoft SharePoint Server 2010. By using the REST API, you can access workbook parts or elements directly through a URL. > [!NOTE] -> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For For Office 365 Education, Business, and Enterprise accounts,, use the Excel REST APIs that are part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel) endpoint. +> The Excel Services REST API for SharePoint Online will no longer be supported for Microsoft 365 accounts from February 28th, 2022 forward. Instead, please use the REST API that’s part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel) endpoint. diff --git a/docs/general-development/excel-services-rest-api.md b/docs/general-development/excel-services-rest-api.md index a2994cd39..29229c636 100644 --- a/docs/general-development/excel-services-rest-api.md +++ b/docs/general-development/excel-services-rest-api.md @@ -1,9 +1,9 @@ --- title: Excel Services REST API -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the Representational State Transfer (REST) API in Excel Services and provides links to articles and tutorials about the REST API. +ms.date: 06/09/2022 ms.assetid: 32033fea-873c-4781-900a-6946906066b0 -localization_priority: Priority +ms.localizationpriority: high --- @@ -12,7 +12,7 @@ localization_priority: Priority This section contains information about the Representational State Transfer (REST) API in Excel Services and explains how to use it. > [!NOTE] -> The Excel Services REST API applies to SharePoint and SharePoint 2016 on-premises. For Office 365 Education, Business, and Enterprise accounts, use the Excel REST APIs that are part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel +> The Excel Services REST API for SharePoint Online will no longer be supported for Microsoft 365 accounts from February 28th, 2022 forward. Instead, please use the REST API that’s part of the [Microsoft Graph](http://graph.microsoft.io/docs/api-reference/v1.0/resources/excel ) endpoint. diff --git a/docs/general-development/excel-services-user-defined-functions.md b/docs/general-development/excel-services-user-defined-functions.md index e35a8b74f..df735d7df 100644 --- a/docs/general-development/excel-services-user-defined-functions.md +++ b/docs/general-development/excel-services-user-defined-functions.md @@ -1,12 +1,12 @@ --- title: Excel Services User-Defined Functions +description: "This section contains information about user-defined functions (UDFs) and how to use UDF attributes in your code." ms.date: 09/25/2017 keywords: functions f1_keywords: - functions -ms.prod: sharepoint ms.assetid: 27dd8024-7e00-40de-a688-afc67c880603 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -35,7 +35,7 @@ This section contains information about user-defined functions (UDFs) and how to > Get step-by-step instructions about developing Excel Services UDFs by using Microsoft Visual C#. - [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.md) + [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.yml) diff --git a/docs/general-development/excel-web-access.md b/docs/general-development/excel-web-access.md index 3d7c15135..104fbd172 100644 --- a/docs/general-development/excel-web-access.md +++ b/docs/general-development/excel-web-access.md @@ -1,9 +1,9 @@ --- title: Excel Web Access -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the Excel Web Access web part and provides its reference and links to tutorials related to Excel Web Access. +ms.date: 06/09/2022 ms.assetid: eef8991d-0844-4b35-a092-33c957102dee -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/excel-web-services.md b/docs/general-development/excel-web-services.md index 6b6f1de2f..843b43fa3 100644 --- a/docs/general-development/excel-web-services.md +++ b/docs/general-development/excel-web-services.md @@ -1,9 +1,9 @@ --- title: Excel Web Services -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes Excel Web Services, explains how to use it to develop custom applications, and provides links to articles and tutorials. +ms.date: 06/09/2022 ms.assetid: e30ef4e3-72ff-43de-beba-b377141d4d19 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/exporting-and-importing-search-configuration-settings-in-sharepoint.md b/docs/general-development/exporting-and-importing-search-configuration-settings-in-sharepoint.md index 27604eae6..e91a6b31a 100644 --- a/docs/general-development/exporting-and-importing-search-configuration-settings-in-sharepoint.md +++ b/docs/general-development/exporting-and-importing-search-configuration-settings-in-sharepoint.md @@ -1,29 +1,29 @@ --- title: Exporting and importing search configuration settings in SharePoint +description: Get code examples that show you how to export and import customized search configuration settings. These settings include all customized query rules, result sources, result types, ranking models, and site search settings. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: d00679a3-ffa2-4281-ad8b-70fc2c4a14e2 -localization_priority: Normal +ms.localizationpriority: medium --- # Exporting and importing search configuration settings in SharePoint -Get code examples that show you how to export and import customized search configuration settings. These settings include all customized query rules, result sources, result types, ranking models, and site search settings. SharePoint exposes this functionality through the [Microsoft.Office.Server.Search.Portability](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Portability.aspx) namespace.You can also export customized search configuration settings from a Search service application (SSA) and import the settings to site collections and sites. +Get code examples that show you how to export and import customized search configuration settings. These settings include all customized query rules, result sources, result types, ranking models, and site search settings. SharePoint exposes this functionality through the [Microsoft.Office.Server.Search.Portability](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Portability.aspx) namespace.You can also export customized search configuration settings from a Search service application (SSA) and import the settings to site collections and sites. > [!NOTE] -> You can't import customized search configuration settings to an SSA, or export the default search configuration settings. - - - +> You can't import customized search configuration settings to an SSA, or export the default search configuration settings. + + + ## Export search configuration settings The following code shows how to use [SearchConfigurationPortability](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Portability.SearchConfigurationPortability.aspx) to export your site's search configuration settings. The code uses an example site `http://yoursite/sites/publishing1`, which you'd replace with your own site. _fileName_ refers to the file where the search configuration settings are stored; _owner_ specifies the [SPWeb](https://msdn.microsoft.com/library/Microsoft.SharePoint.SPWeb.aspx) level at which the search configuration settings are obtained. - - - + + + ``` @@ -43,11 +43,11 @@ private static void Export(string fileName) The following code shows how to import search configuration settings from a file by using [SearchConfigurationPortability](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Portability.SearchConfigurationPortability.aspx) and replace the existing search settings on a specified site, `http://yoursite/sites/publishing1`. _fileName_ refers to the file where the search configuration settings are stored; _owner_ specifies the [SPWeb](https://msdn.microsoft.com/library/Microsoft.SharePoint.SPWeb.aspx) level at which the search configuration settings are obtained. - - - -```cs + + + +```csharp private static void Import(string fileName) { @@ -66,13 +66,13 @@ private static void Import(string fileName) - [Search in SharePoint](search-in-sharepoint.md) - - + + - [Export and import customized search configuration settings in SharePoint](https://technet.microsoft.com/library/jj871675.aspx) - - - - - + + + + + diff --git a/docs/general-development/extend-the-fixed-format-export-feature-in-word-automation-services.md b/docs/general-development/extend-the-fixed-format-export-feature-in-word-automation-services.md index b9ce42d5d..752362eb0 100644 --- a/docs/general-development/extend-the-fixed-format-export-feature-in-word-automation-services.md +++ b/docs/general-development/extend-the-fixed-format-export-feature-in-word-automation-services.md @@ -1,188 +1,121 @@ --- title: Extend the fixed-format export feature in Word Automation Services -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Extend Word Automation Services in Microsoft Office 2013 to replace the library used by the fixed-format export feature. +ms.date: 12/14/2020 ms.assetid: d8375505-432e-438e-971b-221a1d9bb601 -localization_priority: Normal +ms.localizationpriority: medium --- - # Extend the fixed-format export feature in Word Automation Services + Extend Word Automation Services in Microsoft Office 2013 to replace the library used by the fixed-format export feature. + ## Introduction to the Word file conversion service fixed-format export feature -This article describes how to extend the fixed-format export feature of Word Automation Services to use different fixed-format export DLLs, so third-party developers can replace those provided by Microsoft. This mechanism requires and extends the Office client fixed-format extensibility COM interface. For more information, see [Extending the Office 2007 Fixed-Format Export Feature](https://msdn.microsoft.com/library/aa338206.aspx). - - - +This article describes how to extend the fixed-format export feature of Word Automation Services to use different fixed-format export DLLs, so third-party developers can replace those provided by Microsoft. This mechanism requires and extends the Office client fixed-format extensibility COM interface. For more information, see [Extending the Office 2007 Fixed-Format Export Feature](https://msdn.microsoft.com/library/aa338206.aspx). ## Discovery Word Automation Services allows third-party developers to replace either or both of the fixed format outputs supported: - - - - PDF - - - XPS - - -To replace each format, the DLL must be located in the same directory as the core library (Sword.dll) for Word Automation Services (install path: \<\\>\\WebServices\\ConversionService\\Bin\\Converter\\), and must have the specific file name specified in table 1. - - - -**Table 1. File names for fixed-format export DLLs** +To replace each format, the DLL must be located in the same directory as the core library (Sword.dll) for Word Automation Services (install path: **root\WebServices\ConversionService\Bin\Converter**), and must have the specific file name specified in table 1. +### Table 1. File names for fixed-format export DLLs -|**Format**|**File Name**| -|:-----|:-----| -|PDF
|Renderpdf.dll
| -|XPS
|Renderxps.dll
| - +| Format | File Name | +| :----- | :------------ | +| PDF | Renderpdf.dll | +| XPS | Renderxps.dll | ## Initialization The DLL must export a method with the following signature. - - - ``` - HRESULT HrGetDocExporter ( -IMsoDocExporter **ppimde, -IMsoServerFileManagerSite *psfms, -PFNKeepAlive pfnKeepAlive + IMsoDocExporter **ppimde, + IMsoServerFileManagerSite *psfms, + PFNKeepAlive pfnKeepAlive ) ``` The function requires the DLL to supply two interfaces and a method pointer, described in the following section. - - - If the function returns failure the service will not fall back to the Microsoft-provided exporter. Instead, the service will report the conversion as having failed. - - - ## IMsoDocExporter The **IMsoDocExporter** interface is identical to the existing interface documented on MSDN. For more information, see [Extending the Office 2007 Fixed-Format Export Feature](https://msdn.microsoft.com/library/aa338206.aspx). When the previous method returns success, this interface performs the conversion. - - - Beyond the requirements described in the aforementioned article, developers of fixed-format export DLLs must be aware that the service can call the provided **IMsoDocExporter** on a different thread from the one on which the service called **HrGetDocExporter**. The DLL must be able to handle this without marshalling the call back to the thread that called **HrGetDocExporter**, because the service does not run a message pump and the marshaled call will never get through (resulting in a hang and subsequent failure). - - - ## IMsoServerFileManagerSite The IMsoServerFileManagerSite interface is defined as follows. - - - ``` - #undef INTERFACE #define INTERFACE IMsoServerFileManagerSite DECLARE_INTERFACE(IMsoServerFileManagerSite) { -STDMETHOD_(BOOL, FGetHandle) (const WCHAR *pwzFileName, HANDLE *phFile, BOOL fRead, BOOL fWrite) PURE; -STDMETHOD_(BOOL, FCloseHandle) (HANDLE hFile) PURE; + STDMETHOD_(BOOL, FGetHandle) (const WCHAR *pwzFileName, HANDLE *phFile, BOOL fRead, BOOL fWrite) PURE; + STDMETHOD_(BOOL, FCloseHandle) (HANDLE hFile) PURE; }; ``` This interface exposes the following methods. - - - - -**Table 2. Methods exposed by the IMsoServerFileManagerSite interface** - -||| -|:-----|:-----| -|Method
|Description
| -|**FGetHandle**
|Gets a file handle.
| -|**FCloseHandle**
|Releases a file handle.
| - + +### Table 2. Methods exposed by the IMsoServerFileManagerSite interface\*\* + +| Method | Description | +| :--------------- | :---------------------- | +| **FGetHandle** | Gets a file handle. | +| **FCloseHandle** | Releases a file handle. | + This interface does not inherit from **IUnknown**. Accordingly, the fixed-format export DLL is allowed to keep a reference to it for its lifetime. - - - ### FGetHandle The fixed-format export DLL calls this function to get file handles to write to. It must not try to open files through any other mechanism because the service runs in a highly restricted environment without access to most places in the file system. - - - ``` - BOOL FGetHandle ( -const WCHAR *pwzFile, -HANDLE *phFile, -BOOL fRead, -BOOL fWrite + const WCHAR *pwzFile, + HANDLE *phFile, + BOOL fRead, + BOOL fWrite ) ``` +### Table 3. FGetHandle parameters\*\* -**Table 3. FGetHandle parameters** - -||| -|:-----|:-----| -|Parameter
|Description
| -|**pwzFile**
|Specifies the name of the file the fixed-format export DLL wants to open. This must not be a full file path—it must specify only a file name (for example, Output.pdf).
| -|**phFile**
|Specifies the handle to the specified file, if the file is opened successfully. The fixed-format export DLL can then use this HANDLE in normal file operations until it closes it by calling the **FCloseHandle** method.
| -|**fRead**
|Specifies whether the file is to be opened with read access.
| -|**fWrite**
|Specifies whether the file is to be opened with write access. This function returns TRUE to indicate success and FALSE to indicate failure.
| - +| Parameter | Description | +| :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **pwzFile** | Specifies the name of the file the fixed-format export DLL wants to open. This must not be a full file path—it must specify only a file name (for example, Output.pdf). | +| **phFile** | Specifies the handle to the specified file, if the file is opened successfully. The fixed-format export DLL can then use this HANDLE in normal file operations until it closes it by calling the **FCloseHandle** method. | +| **fRead** | Specifies whether the file is to be opened with read access. | +| **fWrite** | Specifies whether the file is to be opened with write access. This function returns TRUE to indicate success and FALSE to indicate failure. | ### FCloseHandle The fixed-format export DLL calls this function to close file handles obtained through calls to the **FGetHandle** method. - - - ``` - BOOL FCloseHandle ( -HANDLE phFile, + HANDLE phFile, ) ``` -The *phFile* parameter specifies the handle to the file to be closed. If the value returned by this method is 0, the operation failed. All other values indicate success. - - - +The _phFile_ parameter specifies the handle to the file to be closed. If the value returned by this method is 0, the operation failed. All other values indicate success. ## PFNKeepAlive When the fixed-format export DLL is active, it must call the **KeepAlive** function at regular intervals (configurable by the administrator) to prevent the service from assuming that the fixed-format export DLL is not responding, and thus terminating the process. - - - - `typedef void (*PFNKeepAlive)(void)` - - - +`typedef void (*PFNKeepAlive)(void)` ## See also - For more information, see the following resources: - - - - -- [Extending the Office 2007 Fixed-Format Export Feature](https://msdn.microsoft.com/library/office/aa338206%28v=office.12%29.aspx) - - +- [Extending the Office 2007 Fixed-Format Export Feature](https://msdn.microsoft.com/library/office/aa338206%28v=office.12%29.aspx) diff --git a/docs/general-development/external-content-types-in-sharepoint.md b/docs/general-development/external-content-types-in-sharepoint.md index a30bd15d9..c7760d0d2 100644 --- a/docs/general-development/external-content-types-in-sharepoint.md +++ b/docs/general-development/external-content-types-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: External content types in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes external content types in SharePoint and provides the prerequisites and steps to create external content types. +ms.date: 06/09/2022 ms.assetid: 11d7adb5-5388-4517-ae03-beb7be1c6981 -localization_priority: Priority +ms.localizationpriority: high --- @@ -129,7 +129,7 @@ Table 1 contains examples of tasks that illustrate working with external content **Table 1. Basic tasks for working with external content types** -|**Task**|**Description**| +|Task|Description| |:-----|:-----| | [How to: Create an external content type from an OData source in SharePoint](how-to-create-an-external-content-type-from-an-odata-source-in-sharepoint.md)
|Learn how to use Visual Studio 2012 to discover a published OData source, and create a reusable external content type for use in SharePoint Business Connectivity Services (BCS).
| | [How to: Create external content types for SQL Server in SharePoint](how-to-create-external-content-types-for-sql-server-in-sharepoint.md)
|Learn how to create an external content type based on a SQL Server database.
| diff --git a/docs/general-development/external-events-and-alerts-in-sharepoint.md b/docs/general-development/external-events-and-alerts-in-sharepoint.md index 235ad0494..056ad3528 100644 --- a/docs/general-development/external-events-and-alerts-in-sharepoint.md +++ b/docs/general-development/external-events-and-alerts-in-sharepoint.md @@ -1,289 +1,167 @@ --- title: External events and alerts in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn the concepts behind creating remote event receivers in SharePoint that can be attached to external lists and execute when the external data that the list represents is updated. +ms.date: 05/18/2023 ms.assetid: e48e4812-a185-43c5-b243-04b1d79b88ee -localization_priority: Normal +ms.localizationpriority: medium --- - - # External events and alerts in SharePoint + Learn the concepts behind creating remote event receivers in SharePoint that can be attached to external lists and execute when the external data that the list represents is updated. -## What are event receivers? - -An event receiver is a piece of managed code that responds to SharePoint triggering events such as adding, moving, deleting, checking in, and checking out. When these events occur, and the event receiver's criteria are met, the code that you write to provide additional functionality is executed. When SharePoint objects, such as lists, workflows and features, are configured to wait on these events to occur, they are called event hosts. - - - -Event receivers let you perform business logic when a specific event occurs. Essentially, these are the hooks where you can create code to handle certain conditions, make notifications, update other systems, and so on. When you create event receivers, a DLL is generated. You can place that DLL into the global assembly cache, so that the event receivers are invoked in response to any changes in an external system. - - - -The following example contains a simple external event receiver in C# that executes when a new item is added to the list. - - - +## What are event receivers? +An event receiver is a piece of managed code that responds to SharePoint triggering events such as adding, moving, deleting, checking in, and checking out. When these events occur, and the event receiver's criteria are met, the code that you write to provide additional functionality is executed. When SharePoint objects, such as lists, workflows and features, are configured to wait on these events to occur, they are called event hosts. +Event receivers let you perform business logic when a specific event occurs. Essentially, these are the hooks where you can create code to handle certain conditions, make notifications, update other systems, and so on. When you create event receivers, a DLL is generated. You can place that DLL into the global assembly cache, so that the event receivers are invoked in response to any changes in an external system. -```cs +The following example contains a simple external event receiver in C# that executes when a new item is added to the list. +```csharp public class EntryContentEventReceiver : SPItemEventReceiver { - public override void ItemAdded(SPItemEventProperties properties) - { - base.ItemAdded(properties); - - // properties.ExternalNotificationMessage holds the message sent by the external - // system. - } + public override void ItemAdded(SPItemEventProperties properties) + { + base.ItemAdded(properties); + // properties.ExternalNotificationMessage holds the message sent by the external system + } +} ``` -External event receivers can also be extended to work against an entity event receiver and as remote event receivers deployed as a service on-premises or in Microsoft Azure. - - - +External event receivers can also be extended to work against an entity event receiver and as remote event receivers deployed as a service on-premises or in Microsoft Azure. ## What are remote event receivers? - Remote event receivers are new for SharePoint. In a traditional SharePoint solution, you use an event receiver to handle events such as users creating or deleting lists or items in lists. In an SharePoint Add-in, you use a remote event receiver to handle similar events. Remote event receivers work similarly to regular event receivers, except that remote event receivers handle events that occur when an SharePoint Add-in is on a different system from its host web application. - - - + Business Connectivity Services (BCS) uses remote event receivers attached to external lists and entities to allow you to write code that can react to changes in data hosted in the external system. - - - + To accommodate this, two stereotypes have been added to the schema of the BDC model: **EventSubscriber** and **EventUnsubscriber**. - -> [!NOTE] -> Event receivers are not supported in sandboxed solutions. - - - +> [!NOTE] +> Event receivers are not supported in sandboxed solutions. ## What features and capabilities does the new external event receiver infrastructure provide? - By using and extending the SharePoint event receiver features, BCS is able to add alerts, external list event receivers, and entity receivers to provide extended functionality. - - - - -- **Alerts:** Alerts have been an integral part of SharePoint for several versions, but until SharePoint, they would not work with external lists. Now a user can create alerts on an external list that have the same behavior as alerts on a standard SharePoint list. - - -- **External list event receivers:** Event receivers can now be attached to external lists just like they can for standard lists. This provides an extensibility mechanism that lets you write code that is executed at specific times. - - + +- **Alerts:** Alerts have been an integral part of SharePoint for several versions, but until arePoint, they would not work with external lists. Now a user can create alerts on an external list that have the same behavior as alerts on a standard SharePoint list. +- **External list event receivers:** Event receivers can now be attached to external lists just like they can for standard lists. This provides an extensibility mechanism that lets you write de that is executed at specific times. - **Entity event receivers:** Entity event receivers provide flexibility by letting you write more robust code that allows other operations like providing user context for filtering data. This can allow better personalization and customized security. - - + Remote eventing in SharePoint makes several interesting scenarios possible. For example, you might have a "Sales Lead Tracking" application that lets a sales team be notified when new sales leads are entered into an external lead application. When a new sales lead is entered, SharePoint is notified through the notification system that is part of the lead application. SharePoint receives the notification and then creates new tasks for the specified salespeople to follow up on each new lead. By configuring the sales lead entry application on the external system to send a notification to SharePoint on the creation of each new lead, SharePoint is kept completely up to date. - - - ## Prerequisites for using event receivers for external lists - To use event receivers for external lists, you need the following: - - - - SharePoint - - - Visual Studio 2012 - - + For more information about setting up a SharePoint development environment, see [Set up a general development environment for SharePoint](set-up-a-general-development-environment-for-sharepoint.md). - - - ## Configure the external system to notify SharePoint of external events - For external events to work, a number of components have to be installed and configured on both the SharePoint host and the external system. - - - + You have to configure the external system so that it can do the following: - - - - **Determine when underlying data changes.** For the external system to know when changes have been made, you have to create a mechanism for polling for specific changes. You can do this by using a timed service that polls the data source at specific intervals. - - -- **Receive and record requests for subscriptions to change notifications.** The external system has to implement a subscription store so that it can store who should receive change notifications. The simplest solution is probably a database table. The table (or whatever mechanism you choose) should record SubscriptionID, Delivery Address, Event Type, and Entity Name. - - -- **Post notifications to Representational State Transfer (REST) endpoints.** To let SharePoint subscribers know that a change has occurred, the external system application needs to send an HTTP WebRequest to the delivery address recorded in the subscription store. This delivery address is a RESTful endpoint generated by SharePoint during the subscription process. - - +- **Receive and record requests for subscriptions to change notifications.** The external system has to implement a subscription store so that it can store who should receive change notifications. The simplest solution is probably a database table. The table (or whatever anism you choose) should record SubscriptionID, Delivery Address, Event Type, and Entity Name. +- **Post notifications to Representational State Transfer (REST) endpoints.** To let SharePoint subscribers know that a change has occurred, the external system application needs to send an HTTPWebRequest to the delivery address recorded in the subscription store. This delivery address is a RESTful endpoint generated by SharePoint during the subscription process ## Configure SharePoint to allow communication with external systems - To allow communication with the external system, SharePoint must be configured with the following: - - - - A BDC model with **EventSubscriber** and **EventUnsubscriber** stereotypes configured - - - Event receivers - - ### How is external eventing enabled? You can enable external eventing in SharePoint through **Site Settings** or by adding the following custom feature id to your project - - - - -```XML +```xml ``` Eventing for an external system is enabled when SharePoint creates the delivery address and sends it to the external system during the Subscribe process. - - - ## Overall flow of external eventing between SharePoint and external systems - In Figure 1, notice that there are three distinct steps involved when using external event receivers: subscribe, notification, and unsubscribe. - - - **Figure 1 Complete data flow for external notifications** - - - - - - - -![Data flow for external event notifications](../images/ExtEvtsAndAlrts_Figure1.jpg) - - - - - - - - - - - +[Data flow for external event notifications](../images/ExtEvtsAndAlrts_Figure1.jpg) ## EventSubscriber: subscribe to notifications - For a user (SharePoint object) to receive notifications when the underlying data has changed, the user must subscribe to the notifications for an entity. To allow this, the BDC Model schema has been extended to include the **Subscribe** stereotype. The **Subscribe** stereotype is used by SharePoint to let the external system know that the sender is requesting to be notified of changes to the underlying data. - - - + Figure 2 demonstrates the flow of information between SharePoint and the external system during the Subscribe process. - - - **Figure 2. Subscribe process flow** - - - - - - - ![External eventing Subscribe method process flow](../images/ExtEvtsAndAlerts_Figure2.jpg) - - - -The following describes the general flow of the subscription process: - - - - - - +The following describes the general flow of the subscription process: 1. **User requests a subscription for notifications.** Using a custom user interface (a button on a page or a ribbon), SharePoint initiates a request to the external system app for notifications. - - -2. **SharePoint generates a delivery address.** As part of the Subscribe process, SharePoint creates a REST endpoint where notifications will be delivered. - - -3. **Subscription request is sent to the external system.** SharePoint then encapsulates the requestor information along with the dynamically generated REST URL, and sends a web request to the external system. - - -4. **External system receives request.** There are different possibilities for implementing a subscription store. In this example, you will use a SQL Server database table. - - -5. **External system generates a subscriptionId.** A new **subscriptionId** is generated using code in the line-of-business (LOB) application. The **subscriptionId** should be a GUID. - - -6. **External system records the subscription.** The external system application records the **subscriptionId**, delivery address, event type, and other information sent from SharePoint into the subscription store. - - -7. **External system sends the subscriptionId back to SharePoint.** For SharePoint to correctly route the updates that are sent by the external system, the **subscriptionId** is sent back to SharePoint and SharePoint records that information in its database. - - The BDC model is working against a **Subscribe** function import. The metadata for function import is shown in this example. - +1. **SharePoint generates a delivery address.** As part of the Subscribe process, SharePoint creates a REST endpoint where notifications will be delivered. +1. **Subscription request is sent to the external system.** SharePoint then encapsulates the requestor information along with the dynamically generated REST URL, and sends a web request to the external system. +1. **External system receives request.** There are different possibilities for implementing a subscription store. In this example, you will use a SQL Server database table. +1. **External system generates a subscriptionId.** A new **subscriptionId** is generated using code in the line-of-business (LOB) application. The **subscriptionId** should be a GUID. +1. **External system records the subscription.** The external system application records the **subscriptionId**, delivery address, event type, and other information sent from SharePoint into the subscription store. +1. **External system sends the subscriptionId back to SharePoint.** For SharePoint to correctly route the updates that are sent by the external system, the **subscriptionId** is sent back to SharePoint and SharePoint records that information in its database. + The BDC model is working against a **Subscribe** function import. The metadata for function import is shown in this example. -```XML - FunctionImport - +```xml - - - + + + - - - + + + - ``` - ### Code example: BDC model with Subscribe The following is an example of a BDC model with the **Subscribe** method added. - - - - -```XML +```xml /EntitySubscribes @@ -318,7 +196,7 @@ The following is an example of a BDC model with the **Subscribe** method added. - Customers @@ -368,148 +246,72 @@ The following is an example of a BDC model with the **Subscribe** method added. ``` Table 1 lists the important attributes of the BDC model that are needed to make the **Subscribe** stereotype work. - - - **Table 1. BDC model attributes** - -|**Attribute**|**Description**| -|:-----|:-----| -|**IsDeliveryAddress**
|A **Boolean** flag used on a **TypeDescriptor** to indicate whether the delivery address provided is to be used to deliver notifications.
| -|**IsEventType**
|A **Boolean** flag used on a **TypeDescriptor** to indicate whether the event type provided is to be used as the event type. Valid event types are **ItemAdded**, **ItemUpdated**, **ItemDeleted**, and so on.
| -|**SubscriptionIdName**
|A string used on a **TypeDescriptor** that represents the name of a **subscriptionId** part.
| - +| **Attribute** | **Description** | +| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **IsDeliveryAddress** | A **Boolean** flag used on a **TypeDescriptor** to indicate whether the delivery address provided is to be used to deliver notifications. | +| **IsEventType** | A **Boolean** flag used on a **TypeDescriptor** to indicate whether the event type provided is to be used as the event type. Valid event types are **ItemAdded**, **ItemUpdated**, **ItemDeleted**, and so on. | +| **SubscriptionIdName** | A string used on a **TypeDescriptor** that represents the name of a **subscriptionId** part. | ## Notifications - In SharePoint, the event-handling infrastructure has been enhanced to allow external data sources to notify SharePoint when information in the external system has been modified. Then, when SharePoint receives a notification, event receivers that are associated with the SharePoint external list or entity can execute code to perform specified actions. - - - + When a subscription is created, the external system needs a way to tell SharePoint about the changes that have occurred on a particular entity. The external system is expected to deliver notifications to the delivery address as provided by SharePoint to the external system during the Subscribe process using an OData Atom-formatted payload. - - - + Figure 3 shows the communication flow between the external system and SharePoint when a new record is added to the data in the external system. - - - **Figure 3 Notification process** - - - - - - - ![External event notification process](../images/ExtEvtsAndAlerts_Figure3.jpg) - - - - - - - 1. **New record is added to external system.** In this example, a new record is added to the external system using the application user interface or directly into the database. - - -2. **External system application is notified of the change.** The external system application has to be made aware of the changes that are happening to the underlying data. There are a number of ways to do this. You can use SQL triggers that fire when data changes on specific tables, or you can create a polling mechanism to query the data store for changes. There are other ways to accomplish this, but each will have to be evaluated with performance in mind. - - -3. **External system sends notification request to SharePoint through delivery address.** To communicate the changes, an Atom-formatted request has to be sent to the delivery address that is stored in the LOB application's subscription store. - - +1. **External system application is notified of the change.** The external system application has to be made aware of the changes that are happening to the underlying data. There are a number of ways to do this. You can use SQL triggers that fire when data changes on specific tables, or you can create a polling mechanism to query the data store for changes. There are other ways to accomplish this, but each will have to be evaluated with performance in mind. +1. **External system sends notification request to SharePoint through delivery address.** To communicate the changes, an Atom-formatted request has to be sent to the delivery address that is stored in the LOB application's subscription store. ### Notification payload In constructing the notification, the LOB system has to create an HTTP payload that includes either the full details of the item that changed, or just the identity of the item that changed. - - - - **Identity:** When the payload is sent as an identity, the payload is expected to have only information about the identity of the changed item. For example, for a customer in a Customers entity, the payload would only contain the ID of the customer that has changed. - - - **Full item:** In this case, the payload is an entire record that has changed in the external system. In the customer example, the entire changed customer record is included. - + > [!NOTE] -> The full item is only supported when you use the OData connector. - - - +> The full item is only supported when you use the OData connector. The type of payload that is being sent by the external system must be indicated during the subscription process. - - - -The following is an example of the BDC model property used for notifications. - - - - +The following is an example of the BDC model property used for notifications. -```XML - +```xml ODataEntryContentNotificationParser - ``` If it is not specified, the default payload is an identity payload. - - - ### Notification delivery address (virtual address) The subscription process initiated from SharePoint results in a virtual address being created by SharePoint, allowing an entry point for the external system to post notifications. The delivery address is used by the external system to post those notifications. The delivery address is also passed to the external system during the subscription request. - - - ## EventUnsubscriber: remove subscription from the notifications list - The **Unsubscribe** operation removes a subscription from the notifications list. - - - - Figure 4 shows that the **UnSubscribe** method is much simpler. Because the subscription ID was sent back to SharePoint, and SharePoint recorded it, all that is needed is to send the UnSubscribe request with the correct subscription ID. - - - -**Figure 4 Code flow for UnSubscribe method** +Figure 4 shows that the **UnSubscribe** method is much simpler. Because the subscription ID was sent back to SharePoint, and SharePoint recorded it, all that is needed is to send the UnSubscribe request with the correct subscription ID. - - - +**Figure 4 Code flow for UnSubscribe method** - - - ![External notifications unsubscribe process](../images/ExternalEventsAndAlerts_UnsubscribeFlow.jpg) - - - ### BDC model for Unsubscribe The following XML example shows how you can create a BDC model that unsubscribes from the external system event notifications. - - - - -```XML +```xml @@ -540,7 +342,7 @@ The following XML example shows how you can create a BDC model that unsubscribes
- @@ -554,8 +356,6 @@ The following XML example shows how you can create a BDC model that unsubscribes
- - @@ -567,12 +367,12 @@ The following XML example shows how you can create a BDC model that unsubscribes - - None @@ -588,77 +388,46 @@ The following XML example shows how you can create a BDC model that unsubscribes - ``` - ## Code example: Attach an event receiver to an external list - The following code provides an example of how to attach an event receiver to an external list. After it is attached, the event receiver listens for notifications from the external system about updates, additions, and deletions that are performed on the native data. - - - - -```XML +```csharp private static void AddEventReceiver(string siteUrl, string listTitle) -{ - string assembly = "SampleEventReceiver, Culture=neutral, Version=1.0.0.0, - PublicKeyToken=1bfafa687d2e46a7"; - string className = "SampleEventReceiver.EntryContentEventReceiver"; - - try - { - using (SPSite site = new SPSite(siteUrl)) - { - using (SPWeb web = site.OpenWeb()) - { - SPList list = web.Lists[listTitle]; - list.EventReceivers.Add(SPEventReceiverType.ItemAdded, - assembly, className); - } +{ + string assembly = "SampleEventReceiver, Culture=neutral, Version=1.0.0.0,PublicKeyToken=1bfafa687d2e46a7"; + string className = "SampleEventReceiver.EntryContentEventReceiver"; + try + { + using (SPSite site = new SPSite(siteUrl)) + { + using (SPWeb web = site.OpenWeb()) + { + SPList list = web.Lists[listTitle]; + list.EventReceivers.Add(SPEventReceiverType.ItemAdded, assembly, className); } - } - catch (Exception e) - { - Console.WriteLine(e); - } + } + } + catch (Exception e) + { + Console.WriteLine(e); + } } - ``` - ## Beyond the basics: Learn more about using external event receivers - For more information about external events and alerts, see the following. - - - **Table 2. Advanced concepts for working with external event receivers** +| **Article** | **Description** | +| :----------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [How to: Create an OData data service for use as a BCS external system](how-to-create-an-odata-data-service-for-use-as-a-bcs-external-system.md) | Learn how to create an Internet-addressable Windows Communication Foundation (WCF) service that uses OData to send notifications to SharePoint when the underlying data changes. These notifications are used to tigger events that are attached to external lists. | -|**Article**|**Description**| -|:-----|:-----| -| [How to: Create an OData data service for use as a BCS external system](how-to-create-an-odata-data-service-for-use-as-a-bcs-external-system.md)
|Learn how to create an Internet-addressable Windows Communication Foundation (WCF) service that uses OData to send notifications to SharePoint when the underlying data changes. These notifications are used to trigger events that are attached to external lists.
| - - -## See also - - - -- [What's new in Business Connectivity Services in SharePoint](what-s-new-in-business-connectivity-services-in-sharepoint.md) - - -- [Business Connectivity Services in SharePoint](business-connectivity-services-in-sharepoint.md) - - -- [Business Connectivity Services programmers reference for SharePoint](business-connectivity-services-programmers-reference-for-sharepoint.md) - - -- [How to: Create external event receivers](how-to-create-external-event-receivers.md) - - +## See Also +- [What's new in Business Connectivity Services in SharePoint](what-s-new-in-business-connectivity-services-in-sharepoint.md) +- [Business Connectivity Services in SharePoint](business-connectivity-services-in-sharepoint.md) diff --git a/docs/general-development/fast-query-language-fql-syntax-reference.md b/docs/general-development/fast-query-language-fql-syntax-reference.md index 633daf16b..3a85d77d4 100644 --- a/docs/general-development/fast-query-language-fql-syntax-reference.md +++ b/docs/general-development/fast-query-language-fql-syntax-reference.md @@ -1,1567 +1,870 @@ --- title: FAST Query Language (FQL) syntax reference -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn about constructing complex search queries for Search in SharePoint using the FAST Query Language (FQL). This reference describes the elements of an FQL query and how to use property specifications, token expressions, and operators in your FQL queries. +ms.date: 06/09/2022 ms.assetid: bd98a41b-623c-41d4-a15d-26c0d4ba4311 -localization_priority: Priority +ms.localizationpriority: high --- - - # FAST Query Language (FQL) syntax reference + Learn about constructing complex search queries for Search in SharePoint using the FAST Query Language (FQL). This reference describes the elements of an FQL query and how to use property specifications, token expressions, and operators in your FQL queries. + ## Introduction to FQL and query language subexpressions and expressions in SharePoint - The FAST Query Language (FQL) is a powerful query language that enables developers to perform exact searches and to narrow the scope of your search to values that belong to a specific managed property or a full-text index. - - - + A query language expression can contain nested subexpressions that include query terms, property specifications, and operators, as described in Table 1. - - - **Table 1. Subexpressions in query language expressions** - -|**Item**|**Description**| -|:-----|:-----| -|Token expressions
|One or more query terms, phrases, or numeric values to search for in a query.
| -|Property specification
|A property or full-text index to match with the affected expression.
| -|Operators
|Keywords that specify Boolean operations (such as **AND**, **OR**) or other constraints to operands (such as **FILTER**.)
| - +| Item | Description | +| :--------------------- | :------------------------------------------------------------------------------------------------------------------------ | +| Token expressions | One or more query terms, phrases, or numeric values to search for in a query. | +| Property specification | A property or full-text index to match with the affected expression. | +| Operators | Keywords that specify Boolean operations (such as **AND**, **OR**) or other constraints to operands (such as **FILTER**.) | ### FQL query example The following FQL query example searches for the terms "hello" and "world" in the **body** managed property of an indexed item: - - - - `body:string("hello world", mode="and")` - - - + +```text +body:string("hello world", mode="and") +``` + In the example: - - - - -- `body:` limits the scope of the query to the body managed property within the item. - - -- `"hello world"` is the operand to the **STRING** operator, which indicates the terms to search for. - - -- `mode="and"` indicates that the logical query operator **AND** will be applied to `"hello world"`. - - + +- `body:` limits the scope of the query to the body managed property within the item. +- `"hello world"` is the operand to the **STRING** operator, which indicates the terms to search for. +- `mode="and"` indicates that the logical query operator **AND** will be applied to `"hello world"`. + The length of FAST Query Language queries is limited to 2,048 characters. - - - ## Property specification in FQL - -A property specification limits the scope of the affected expression to specific regions of the indexed content. Such a region can be identified by a full-text index or a managed property. - - - +A property specification limits the scope of the affected expression to specific regions of the indexed content. Such a region can be identified by a full-text index or a managed property. + Managed properties of type **Text** and **YesNo** are evaluated as text. All other managed property types, including the **Datetime** type, are evaluated as numeric values. - - - + If you don't include a property specification for an expression, the search engine attempts to match the default full-text index defined in the index schema. - - - + The property name must always precede a colon ( **In** operator), and numeric operators must always include a property specification. - - - + A property specification (the **In** Operator) may be applied to the following query entities: - - - - A single term or phrase, as follows: - `author:shakespeare` - - `title:"to be or not to be"` + ```text + author:shakespeare + + title:"to be or not to be" + ``` + - An operator, for example, the **STRING** operator, as follows: -``` + + ```text title:string("to be or not to be") -``` + ``` + In this case the property specification applies to the complete operator expression. ### Examples Each of the following expressions matches items that have both "much" and "nothing" in the **title** managed property. - `title:and(much, nothing)` +```text +title:and(much, nothing) - `and(title:much, title:nothing)` +and(title:much, title:nothing) - `title:string("much nothing", mode="and")` +title:string("much nothing", mode="and") +``` ## Token expressions in FQL - Token expressions are words, phrases, or numeric values that are matched against the index. - - - + A text token expression can be a single word or a phrase enclosed in double quotation marks. - - - + A numeric token expression can be a single value or a value range expression. - - - ### Wildcard expressions A wildcard expression indicates a single term or phrase that includes the Asterisk ("**\***") character; asterisk implies a match of zero or more characters, excluding whitespace. FQL supports prefix search for individual text managed properties and full-text indexes. - - - #### Wildcard expression examples The following is a list of valid uses of wildcard expressions in FQL: - - - -- `text*` - - -- `string("this examp*")` - - +- `text*` +- `string("this examp*")` ### Numeric term expressions - -Each numeric term expression must include a property specification of a compatible index schema data type. Table 2 lists the numeric data types that can be used in FQL. - - - +Each numeric term expression must include a property specification of a compatible index schema data type. Table 2 lists the numeric data types that can be used in FQL. **Table 2. Numeric data types that can be used in FQL** - -|**FQL type**|**Compatible index schema types**|**Description**| -|:-----|:-----|:-----| -|**Int**
|**Integer**
|64 bit integer.
| -|**Float**
|**Double**
|64-bit (double precision) floating point.
| -|**Decimal**
|**Decimal**
|128-bit decimal
| -|**Datetime**
|**Datetime**
|A date and time value.
The date/time support in FQL enables the same numeric operations on date/time values as on other numeric values.
| - +| FQL type | Compatible index schema types | Description | +| :----------- | :---------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- | +| **Int** | **Integer** | 64 bit integer. | +| **Float** | **Double** | 64-bit (double precision) floating point. | +| **Decimal** | **Decimal** | 128-bit decimal | +| **Datetime** | **Datetime** | A date and time value. The date/time support in FQL enables the same numeric operations on date/time values as on other numeric values. | #### Date and time query expressions - FQL provides the **datetime** data type for date and time. - - - + The following ISO 8601-compatible **datetime** formats are supported in queries: - - - - -- YYYY-MM-DD - - -- YYYY-MM-DDThh:mm:ss - - -- YYYY-MM-DDThh:mm:ssZ - - + +- YYYY-MM-DD +- YYYY-MM-DDThh:mm:ss +- YYYY-MM-DDThh:mm:ssZ - YYYY-MM-DDThh:mm:ssfrZ - - + In these **datetime** formats: - - - -- _YYYY_ specifies a four-digit year. - +- _YYYY_ specifies a four-digit year. + > [!NOTE] - > Only four-digit years are supported. - -- _MM_ specifies a two-digit month. For example, 01 = January. - - -- _DD_ specifies a two-digit day of the month (01 through 31). - - -- _T_ specifies the letter "T". - - -- _hh_ specifies a two-digits hour (00 through 23); A.M./P.M. indication is not allowed. - - -- _mm_ specifies a two-digit minute (00 through 59). - - -- _ss_ specifies a two-digit second (00 through 59). - - -- _fr_ specifies an optional fraction of seconds, _ss_; between 1 to 7 digits that follows the **.** after the seconds. For example, 2012-09-27T11:57:34.1234567. - - + > Only four-digit years are supported. + +- _MM_ specifies a two-digit month. For example, 01 = January. +- _DD_ specifies a two-digit day of the month (01 through 31). +- _T_ specifies the letter "T". +- _hh_ specifies a two-digits hour (00 through 23); A.M./P.M. indication is not allowed. +- _mm_ specifies a two-digit minute (00 through 59). +- _ss_ specifies a two-digit second (00 through 59). +- _fr_ specifies an optional fraction of seconds, _ss_; between 1 to 7 digits that follows the **.** after the seconds. For example, 2012-09-27T11:57:34.1234567. + All date/time values must be specified according to the UTC (Coordinated Universal Time), also known as GMT (Greenwich Mean Time) time zone. The UTC time zone identifier (a trailing "Z" character) is optional. - - - ### Reserved words, special characters, and escaping - The following words are reserved within FQL. - - - + `and, or, any, andnot, count, decimal, rank, near, onear, int, in32, int64, float, double, datetime, max, min, range, phrase, scope, filter, not, string, starts-with, ends-with, equals, words, xrank.` - - - -If you want to express any of these words as terms in a query expression, you must enclose them in double quotation marks as shown in the following examples: - - - - -- `or("any", "and", "xrank")` - - -- `string("any and xrank", mode="OR")` - - -- `phrase(this, is, a, "phrase")` - - -> **Tip:** -> Reserved words and characters are not case-sensitive, but using lowercase characters are recommended for future compatibility. - - - - -FQL does not always require a string to be enclosed in double quotation marks. For example, `and(cat, dog)` is valid FQL even though `cat` and `dog` are not in double quotation marks. However, we recommend that you use double quotation marks to avoid conflicts with reserved words. - - - +If you want to express any of these words as terms in a query expression, you must enclose them in double quotation marks as shown in the following examples: + +- `or("any", "and", "xrank")` +- `string("any and xrank", mode="OR")` +- `phrase(this, is, a, "phrase")` + +> [!TIP] +> Reserved words and characters are not case-sensitive, but using lowercase characters are recommended for future compatibility. + +FQL does not always require a string to be enclosed in double quotation marks. For example, `and(cat, dog)` is valid FQL even though `cat` and `dog` are not in double quotation marks. However, we recommend that you use double quotation marks to avoid conflicts with reserved words. + The query terms are tokenized according to your locale setting. The tokenization process removes certain special characters. Because special characters are removed, the following FQL expressions are equivalent. - - - - `and("[king]", "")` - - - - `and("king", "queen")` - - - -When a query includes terms from user input or another application, use the `string("", mode="AND|OR|PHRASE")` operator to avoid conflict with reserved words in the query language. You must also remove possible double quotation marks from the user-provided query. - - - + +`and("[king]", "")` + +`and("king", "queen")` + +When a query includes terms from user input or another application, use the `string("", mode="AND|OR|PHRASE")` operator to avoid conflict with reserved words in the query language. You must also remove possible double quotation marks from the user-provided query. ## FQL Operators - FAST Query Language (FQL) operators are keywords that specify Boolean operations or other constraints to operands. The FQL operator syntax is as follows: - - - - `[property-spec:]operator(operand [,operand]* [, parameter="value"]*)` - - - + +`[property-spec:]operator(operand [,operand]* [, parameter="value"]*)` + In the syntax: - - - - -- _property-spec_ is an optional property specification followed by the "in" operator. - - -- _operator_ is a keyword that specifies an operation to perform. - - -- _operand_ is a term expression or another operator. - - -- _parameter_ is the name of a value that changes the behavior of the operator. - - -- _value_ is the value to use for the parameter name. - - + +- _property-spec_ is an optional property specification followed by the "in" operator. +- _operator_ is a keyword that specifies an operation to perform. +- _operand_ is a term expression or another operator. +- _parameter_ is the name of a value that changes the behavior of the operator. +- _value_ is the value to use for the parameter name. + Operator names, parameter names, and parameter text values are case-insensitive. White space is allowed within the operator body, but is ignored unless it is enclosed in double quotation marks. The length of FAST Query Language queries is limited to 2,048 characters. - - - -Table 3 lists the types of operators supported by FQL. - - - + +Table 3 lists the types of operators supported by FQL. **Table 3. FQL supported operator types** +| Type | Description | Operators | +| :-------- | :------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| String | Enables you to specify query operations on a string of terms. This is the most common operator to use on text terms. | [STRING](#string) | +| Boolean | Enables you to combine terms and sub-expressions in a query. | [AND](#and), [OR](#or), [ANY](#any), [ANDNOT](#andnot), [NOT](#not), [COUNT](#count), [COUNT](#count) | +| Proximity | Enables you to specify the proximity of the query terms in a matching sequence of text. | [NEAR](#near), [ONEAR](#onear), [PHRASE](#phrase), [STARTS-WITH](#starts-with), [ENDS-WITH](#ends-with), [EQUALS](#equals) | +| Numeric | Enables you to specify numeric conditions in the query. | [RANGE](#range) , [INT](#int), [FLOAT](#float), [DATETIME](#datetime), [DECIMAL](#decimal) | +| Relevance | Enables you to impact the relevance evaluation of a query. | [XRANK](#xrank) and [FILTER](#filter) | -|**Type**|**Description**|**Operators**| -|:-----|:-----|:-----| -|String
|Enables you to specify query operations on a string of terms. This is the most common operator to use on text terms.
| [STRING](fast-query-language-fql-syntax-reference.md#fql_string_operator)
| -|Boolean
|Enables you to combine terms and sub-expressions in a query.
| [AND](fast-query-language-fql-syntax-reference.md#fql_and_operator), [OR](fast-query-language-fql-syntax-reference.md#fql_or_operator), [ANY](fast-query-language-fql-syntax-reference.md#fql_any_operator), [ANDNOT](fast-query-language-fql-syntax-reference.md#fql_andnot_operator), [NOT](fast-query-language-fql-syntax-reference.md#fql_not_operator), [COUNT](fast-query-language-fql-syntax-reference.md#fql_count_operator), [COUNT](fast-query-language-fql-syntax-reference.md#fql_count_operator)
| -|Proximity
|Enables you to specify the proximity of the query terms in a matching sequence of text.
| [NEAR](fast-query-language-fql-syntax-reference.md#fql_near_operator), [ONEAR](fast-query-language-fql-syntax-reference.md#fql_onear_operator), [PHRASE](fast-query-language-fql-syntax-reference.md#fql_phrase_operator), [STARTS-WITH](fast-query-language-fql-syntax-reference.md#fql_startswith_operator), [ENDS-WITH](fast-query-language-fql-syntax-reference.md#fql_endswith_operator), [EQUALS](fast-query-language-fql-syntax-reference.md#fql_equals_operator)
| -|Numeric
|Enables you to specify numeric conditions in the query.
| [RANGE](fast-query-language-fql-syntax-reference.md#fql_range_operator) , [INT](fast-query-language-fql-syntax-reference.md#fql_int_operator), [FLOAT](fast-query-language-fql-syntax-reference.md#fql_float_operator), [DATETIME](fast-query-language-fql-syntax-reference.md#fql_datetime_operator), [DECIMAL](#fql_decimal_operator)
| -|Relevance
|Enables you to impact the relevance evaluation of a query.
| [XRANK](fast-query-language-fql-syntax-reference.md#fql_xrank_operator) and [FILTER](fast-query-language-fql-syntax-reference.md#fql_filter_operator)
| - Table 4 provides a list of the supported operators. - - - **Table 4. FQL supported operators** +| **Operator** | **Description** | **Type** | +| :--------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------- | +| [AND](#and) | Returns only items that match all **AND** operands. | Boolean | +| [ANDNOT](#andnot) | Returns only items that match the first operand and that don't match the subsequent operands. | Boolean | +| [ANY](#any) | Similar to the **OR** operator except that the dynamic rank (the relevance score in the result set.md) is affected by neither the number of operands that match nor the distance between the terms in the item. | Boolean | +| [COUNT](#count) | Enables you to specify the number of query term occurrences an item must include to be returned as a result. The operand may be a single query term, a phrase, or wildcard query term. | Boolean | +| [DATETIME](#datetime) | Provides explicit typing of numeric values. The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. | Numeric | +| [DECIMAL](#decimal) | Provides explicit typing of numeric values. The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. | Numeric | +| [ENDS-WITH](#ends-with) | Specifies that a word or phrase must appear in the end of a managed property. | Proximity | +| [EQUALS](#equals) | Specifies that a word or phrase term or phrase must provide an exact token match with the managed property. | Proximity | +| [FILTER](#filter) | Used to query metadata or other structured data. | Relevance | +| [FLOAT](#float) | Provides explicit typing of numeric values. The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. | Numeric | +| [INT](#int) | Provides explicit typing of numeric values. The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. | Numeric | +| [NEAR](#near) | Restricts the result set to items that have `N` terms within a certain distance of one another. | Proximity | +| [NOT](#not) | Returns only items that exclude the operand. | Boolean | +| [ONEAR](#onear) | The ordered variant of **NEAR**, and requires an ordered match of the terms. The **ONEAR** operator can be used to restrict the result set to items that have `N` terms within a certain distance of Returns only items that don't match the operand. The operand may be any valid FQL expression.one another. | Proximity | +| [OR](#or) | Returns only items that match at least one of the **OR** operands. Items that match will get a higher dynamic rank (relevance score in the result set.md) if more of the **OR** operands match. | Boolean | +| [PHRASE](#phrase) | Returns only items that match an exact string of tokens. | Proximity | +| [RANGE](#range) | Enables range matching expressions. The **RANGE** operator is used for numeric and date/time managed properties. | Numeric | +| [STARTS-WITH](#starts-with) | Specifies that a word or phrase must appear in the start of a managed property. | Proximity | +| [STRING](#string) | Define a Boolean matching condition to a text string. | String | +| [XRANK](#xrank) | Enables you to boost the dynamic rank of items based on certain term occurrences without changing which items match the query. A **XRANK** expression contains one component that must be matched, and one or more components that contribute only to dynamic ranking. | Relevance | -|**Operator**|**Description**|**Type**| -|:-----|:-----|:-----| -| [AND](fast-query-language-fql-syntax-reference.md#fql_and_operator)
|Returns only items that match all **AND** operands.
|Boolean
| -| [ANDNOT](fast-query-language-fql-syntax-reference.md#fql_andnot_operator)
|Returns only items that match the first operand and that don't match the subsequent operands.
|Boolean
| -| [ANY](fast-query-language-fql-syntax-reference.md#fql_any_operator)
|Similar to the **OR** operator except that the dynamic rank (the relevance score in the result set.md) is affected by neither the number of operands that match nor the distance between the terms in the item.
|Boolean
| -| [COUNT](fast-query-language-fql-syntax-reference.md#fql_count_operator)
|Enables you to specify the number of query term occurrences an item must include to be returned as a result. The operand may be a single query term, a phrase, or wildcard query term.
|Boolean
| -| [DATETIME](fast-query-language-fql-syntax-reference.md#fql_datetime_operator)
|Provides explicit typing of numeric values.
The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property.
|Numeric
| -| [DECIMAL](fast-query-language-fql-syntax-reference.md#fql_decimal_operator)
|Provides explicit typing of numeric values.
The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property.
|Numeric
| -| [ENDS-WITH](fast-query-language-fql-syntax-reference.md#fql_endswith_operator)
|Specifies that a word or phrase must appear in the end of a managed property.
|Proximity
| -| [EQUALS](fast-query-language-fql-syntax-reference.md#fql_equals_operator)
|Specifies that a word or phrase term or phrase must provide an exact token match with the managed property.
|Proximity
| -| [FILTER](fast-query-language-fql-syntax-reference.md#fql_filter_operator)
|Used to query metadata or other structured data.
|Relevance
| -| [FLOAT](fast-query-language-fql-syntax-reference.md#fql_float_operator)
|Provides explicit typing of numeric values.
The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property.
|Numeric
| -| [INT](fast-query-language-fql-syntax-reference.md#fql_int_operator)
|Provides explicit typing of numeric values.
The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property.
|Numeric
| -| [NEAR](fast-query-language-fql-syntax-reference.md#fql_near_operator)
|Restricts the result set to items that have `N` terms within a certain distance of one another.
|Proximity
| -| [NOT](fast-query-language-fql-syntax-reference.md#fql_not_operator)
|Returns only items that exclude the operand.
|Boolean
| -| [ONEAR](fast-query-language-fql-syntax-reference.md#fql_onear_operator)
|The ordered variant of **NEAR**, and requires an ordered match of the terms. The **ONEAR** operator can be used to restrict the result set to items that have `N` terms within a certain distance of Returns only items that don't match the operand. The operand may be any valid FQL expression.one another.
|Proximity
| -| [OR](fast-query-language-fql-syntax-reference.md#fql_or_operator)
|Returns only items that match at least one of the **OR** operands. Items that match will get a higher dynamic rank (relevance score in the result set.md) if more of the **OR** operands match.
|Boolean
| -| [PHRASE](fast-query-language-fql-syntax-reference.md#fql_phrase_operator)
| Returns only items that match an exact string of tokens.
|Proximity
| -| [RANGE](fast-query-language-fql-syntax-reference.md#fql_range_operator)
| Enables range matching expressions. The **RANGE** operator is used for numeric and date/time managed properties.
|Numeric
| -| [STARTS-WITH](fast-query-language-fql-syntax-reference.md#fql_startswith_operator)
|Specifies that a word or phrase must appear in the start of a managed property.
|Proximity
| -| [STRING](fast-query-language-fql-syntax-reference.md#fql_string_operator)
|Define a Boolean matching condition to a text string.
|String
| -| [XRANK](fast-query-language-fql-syntax-reference.md#fql_xrank_operator)
|Enables you to boost the dynamic rank of items based on certain term occurrences without changing which items match the query. A **XRANK** expression contains one component that must be matched, and one or more components that contribute only to dynamic ranking.
|Relevance
| - > [!NOTE] > In SharePoint, the **RANK** operator is deprecated and will no longer have any effect. Use **XRANK** instead. - - - - ### AND - Returns only items that match all **AND** operands. The operands may be a single term or any valid FQL sub-expression. - - - #### Syntax - `and(operand, operand [, operand]*)` - - - +`and(operand, operand [, operand]*)` #### Parameters Not applicable. - - - #### Examples The following expression matches items for which the default full-text index contains "cat", "dog", and "fox". - - - - `and(cat, dog, fox)` - - - + +`and(cat, dog, fox)` ### ANDNOT - Returns only items that match the first operand and that don't match the subsequent operands. The operands may be a single term or any valid FQL sub-expression. - - - #### Syntax - `andnot(operand, operand [,operand]*)` - - - +`andnot(operand, operand [,operand]*)` #### Parameters Not applicable. - - - #### Examples - **Example 1.** The following expression matches items for which the default full-text index contains "cat" but not "dog". - - - - `andnot(cat, dog)` - - - - **Example 2.** The following expression matches items for which the default full-text index contains "dog" but neither "beagle" nor "chihuahua". - - - - `andnot(dog, beagle, chihuahua)` - - - +**Example 1.** The following expression matches items for which the default full-text index contains "cat" but not "dog". + +`andnot(cat, dog)` + +**Example 2.** The following expression matches items for which the default full-text index contains "dog" but neither "beagle" nor "chihuahua". + +`andnot(dog, beagle, chihuahua)` ### ANY - > [!NOTE] > In SharePoint, the **ANY** operator is deprecated. Use the **OR** operator instead. - - - - -Similar to the [OR](fast-query-language-fql-syntax-reference.md#fql_or_operator) operator except that the dynamic rank (the relevance score in the result set) is affected by neither the number of operands that match nor the distance between the terms in the item. The operands may be a single term or any valid FQL sub-expression. - - - + +Similar to the [OR](#or) operator except that the dynamic rank (the relevance score in the result set) is affected by neither the number of operands that match nor the distance between the terms in the item. The operands may be a single term or any valid FQL sub-expression. + The dynamic ranking component for this part of the query is based on the best matching term within the **ANY** expression. - + > [!NOTE] > he difference from **OR** is related only to the ranking within the result set. The same total set of items will match the query. - - - - #### Syntax - `any(operand, operand [,operand]*)` - - - +`any(operand, operand [,operand]*)` #### Parameters Not applicable. - - - #### Examples - The following expression matches items for which the default full-text index contains "cat" or "dog". - - - +The following expression matches items for which the default full-text index contains "cat" or "dog". + If the index contains both "cat" and "dog", but "cat" is considered a better match, the 'item's dynamic rank will be based on "cat" with no consideration given to "dog". - - - - `any(cat, dog)` - - - + +`any(cat, dog)` ### COUNT - Specifies the of number query term occurrences an item must include for the item to be returned as a result. The operand may be a single query term, a phrase, or a wildcard query term. - - - #### Syntax - `property-spec:count(operand [,from=, to=])` - - - +`property-spec:count(operand [,from=, to=])` #### Parameters +| Parameter | Value | Description | +| :-------- | :------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _From_ | _\_ | The value of the _from_ parameter must be a positive integer that specifies the minimum number of times that the specified operand must be matched. If the _from_ parameter is not specified, no lower limit will exist. | +| _to_ | _\_ | The value of the _to_ parameter must be a positive integer that specifies the non-inclusive maximum number of times that the specified operand must be matched. For example, a _to_ value of **11** specifies 10 times or fewer. If the _to_ parameter is not specified, no upper limit will exist. | +#### Examples -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _From_
| _\_
|The value of the _from_ parameter must be a positive integer that specifies the minimum number of times that the specified operand must be matched.
If the _from_ parameter is not specified, no lower limit will exist.
| -| _to_
| _\_
|The value of the _to_ parameter must be a positive integer that specifies the non-inclusive maximum number of times that the specified operand must be matched. For example, a _to_ value of **11** specifies 10 times or fewer.
If the _to_ parameter is not specified, no upper limit will exist.
| - +**Example 1.** The following expression matches at least 5 occurrences of the word "cat". -#### Examples +`count(cat, from=5)` - **Example 1.** The following expression matches at least 5 occurrences of the word "cat". - - - - `count(cat, from=5)` - - - - **Example 2.** The following expression matches at least 5 but not 10 or more occurrences of the word "cat". - - - - `count(cat, from=5, to=10)` - - - - **Example 3.** Each of the following expressions matches at least 3 occurrences of a certain word, and that word can be either "cat" or "dog". - - - - `count(or(cat, dog), from=3)count(string("cat dog", mode="or"), from=3)` - - - -The following table contains examples of managed property string values and states whether they match the two expressions in Example 3. - - - +**Example 2.** The following expression matches at least 5 but not 10 or more occurrences of the word "cat". +`count(cat, from=5, to=10)` -|**Match?**|**Text**| -|:-----|:-----| -|Yes
|My cat likes my dog, but my dog hates my cat.
| -|No
|My bird likes my newt, but my dog hates my cat.
| - +**Example 3.** Each of the following expressions matches at least 3 occurrences of a certain word, and that word can be either "cat" or "dog". + +`count(or(cat, dog), from=3)count(string("cat dog", mode="or"), from=3)` + +The following table contains examples of managed property string values and states whether they match the two expressions in Example 3. + +| Match? | Text | +| :----- | :---------------------------------------------- | +| Yes | My cat likes my dog, but my dog hates my cat. | +| No | My bird likes my newt, but my dog hates my cat. | ### DATETIME - -Provides explicit typing of date/time numeric values. The operand is a date/time string formatted according to the syntax specified in [Token expressions in FQL](fast-query-language-fql-syntax-reference.md#token_expressions). - - - +Provides explicit typing of date/time numeric values. The operand is a date/time string formatted according to the syntax specified in [Token expressions in FQL](#token-expressions-in-fql). + The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. - - - #### Syntax - `datetime()` - - - +`datetime()` #### Parameters Not applicable. - - - ### DECIMAL - -Provides explicit typing of decimal values. The operand is a decimal value according to the syntax specified in [Token expressions in FQL](fast-query-language-fql-syntax-reference.md#token_expressions). - - - +Provides explicit typing of decimal values. The operand is a decimal value according to the syntax specified in [Token expressions in FQL](#token-expressions-in-fql). + The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. - - - #### Syntax - `decimal()` - - - +`decimal()` #### Parameters Not applicable. - - - ### ENDS-WITH - Specifies that a word or phrase must appear in the end of a managed property (boundary matching). - - - -Boundary matching is not supported on numeric managed properties. Numeric managed properties will always be subject to exact or value range matching. - - - + +Boundary matching is not supported on numeric managed properties. Numeric managed properties will always be subject to exact or value range matching. + Some applications may require that you are able to perform an exact match of a managed property. For example, this may be a **product name** managed property, where the full name of one product is a substring of another product name. - - - #### Syntax - `ends-with()` - - - +`ends-with()` #### Parameters Not applicable. - - - #### Examples The following expression matches items with the values "Mr Adam Jones" and "Adam Jones" in the "author" managed property. It will not match items with the value "Adam Jones sr". - - - - `author:ends-with("adam jones")` - - - + +`author:ends-with("adam jones")` #### Remarks -Boundary matching can be applied to all the text of the managed property, or to individual strings within a managed property that contains a list of string values, for example, a list of names. In this case, you may want to match the exact content of each string, and to avoid query matching across string boundaries. - - - -To apply boundary match queries, you must configure the relevant managed property in the index schema. - - - -By enabling the Boundary Match feature for the managed property, you can do the following: - - - - -- Use explicit boundary match queries. - - +Boundary matching can be applied to all the text of the managed property, or to individual strings within a managed property that contains a list of string values, for example, a list of names. In this case, you may want to match the exact content of each string, and to avoid query matching across string boundaries. + +To apply boundary match queries, you must configure the relevant managed property in the index schema. + +By enabling the Boundary Match feature for the managed property, you can do the following: + +- Use explicit boundary match queries. - Prevent phrases from matching across string boundaries. For managed properties that contain multiple strings, this feature will ensure that a string does not match words before or after a boundary indication. - - ### EQUALS - Specifies that a word or phrase must provide an exact token match with the managed property. - - - #### Syntax - `equals()` - - - +`equals()` #### Parameters Not applicable. - - - #### Examples The following example will match items with the values "Adam Jones" in the "author" managed property. It will not match items with the values "Adam Jones sr" or "Mr Adam Jones". - - - - `author:equals("adam jones")` - - - + +`author:equals("adam jones")` #### Remarks -See also [ENDS-WITH](fast-query-language-fql-syntax-reference.md#fql_endswith_operator). - - - +See also [ENDS-WITH](#ends-with). ### FILTER - -Used to query metadata or other structured data. - - - +Used to query metadata or other structured data. + Using the **FILTER** operator automatically implies the following for the specified query: - - - - Linguistics will be set to linguistics="OFF". - - - Ranking will be disabled. - - + - No query highlighting will be used in the hit highlighted summary for the query result hit. - - > **Tip:** -> If you use the **STRING** operator inside a **FILTER** expression, by default, linguistics is disabled. You can enable linguistics processing within each **STRING** expression inside **FILTER** by using the operand `linguistics="ON"`. - - - - +> If you use the **STRING** operator inside a **FILTER** expression, by default, linguistics is disabled. You can enable linguistics processing within each **STRING** expression inside **FILTER** by using the operand `linguistics="ON"`. #### Syntax - `filter()` - - - +`filter()` #### Parameters Not applicable. - - - #### Examples The following expression matches items that have a **Title** managed property that contains "sonata" and a **Doctype** managed property that contains only the token "audio". No linguistic matching will be performed on "audio". Because the **FILTER** token will be used to match "audio", that text will not be highlighted in the hit highlighted summary. - - - - `and(title:sonata, filter(doctype:equals("audio")))` - - - + +`and(title:sonata, filter(doctype:equals("audio")))` #### Remarks -If you must restrict your query to match at least one of a large set of integer values in a numeric property, you can express this in two functionally equivalent ways: - - - - -- `and(string("hello world"), filter(property-spec:or(1, 20, 453, ... , 3473)))` - - -- `and(string("hello world"), filter(property-spec:int("1 20 453 ... 3473", mode="or")))` - - +If you must restrict your query to match at least one of a large set of integer values in a numeric property, you can express this in two functionally equivalent ways: + +- `and(string("hello world"), filter(property-spec:or(1, 20, 453, ... , 3473)))` +- `and(string("hello world"), filter(property-spec:int("1 20 453 ... 3473", mode="or")))` + The second example uses the **INT** operator by using a string with the set of numeric values in double quotation marks. This provides a significantly better query performance when filtering with a large set of numeric values. - - - + If you must filter a large set of values, you should consider using numeric values instead of string values, and express your queries by using the optimized syntax. - - - ### FLOAT - -Provides explicit typing of floating point numeric values. The operand is a floating point value according to the syntax specified in [Token expressions in FQL](fast-query-language-fql-syntax-reference.md#token_expressions). - - - +Provides explicit typing of floating point numeric values. The operand is a floating point value according to the syntax specified in [Token expressions in FQL](#token-expressions-in-fql). + The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. - - - #### Syntax - `float()` - - - +`float()` #### Parameters Not applicable. - - - ### INT - -Provides explicit typing of integer values. The operand is an integer value according to the syntax specified in [Token expressions in FQL](fast-query-language-fql-syntax-reference.md#token_expressions). - - - +Provides explicit typing of integer values. The operand is an integer value according to the syntax specified in [Token expressions in FQL](#token-expressions-in-fql). + The explicit type conversion is optional and usually is not needed. The type of the query term is detected according to the type of the target numeric managed property. - - - + The **INT** operator can also be used to express a set of integer values as arguments to Boolean FQL operators. This provides a performance efficient way to provide a set of integer values in a query, as the values that are passed by using the **INT** operator are not parsed by the FQL query parser but passed directly to the query matching component. - - - #### Syntax - `int()` - - - - `int("value, value, ??? , value")` - - - +`int()` + +`int("value, value, ??? , value")` + The first syntax specifies a single integer. The second syntax specifies a comma-separated list of integer values enclosed in double quotation marks. - - - #### Parameters Not applicable. - - - #### Examples If you need to restrict your query to match at least one of a large set of integer values in a numeric property, you can express this by using the **INT** operator: - - - - `and(string("hello world"), filter(id:int("1 20 49 124 453 985 3473", mode="or")))` - - - + +`and(string("hello world"), filter(id:int("1 20 49 124 453 985 3473", mode="or")))` ### NEAR - - -Restricts the result set to items that have _N_ terms within a certain distance of one another. - - - -The order of the query terms is not important for the matching, only the distance. - - - + +Restricts the result set to items that have _N_ terms within a certain distance of one another. + +The order of the query terms is not important for the matching, only the distance. + Any number of terms can be combined with the **NEAR** operators. - - - - **NEAR** operands may be single terms, phrases, or Boolean **OR** or **ANY** operator expressions. Wildcards are accepted. - - - + +**NEAR** operands may be single terms, phrases, or Boolean **OR** or **ANY** operator expressions. Wildcards are accepted. + If multiple operands of the **NEAR** operator match the same indexed token, they are considered near one another. - - - #### Syntax - `near(arg, arg [, arg]* [, N=])` - - - +`near(arg, arg [, arg]* [, N=])` #### Parameters +| Parameter | Value | Description | +| :-------- | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _N_ | _\_ | Specifies the maximum number of words that is allowed to appear between the terms (explicit proximity). If **NEAR** includes more than two operands, the maximum number of words allowed between the terms ( _N_) is counted within the whole expression. Default: **4** | +#### Examples -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _N_
| _\_
|Specifies the maximum number of words that is allowed to appear between the terms (explicit proximity).
If **NEAR** includes more than two operands, the maximum number of words allowed between the terms ( _N_) is counted within the whole expression.
Default: **4**
| - +**Example 1.** The following expression matches strings that contain both "cat" and "dog" if no more than four indexed tokens (default) separate them. -#### Examples +`near(cat, dog)` + +**Example 2.** The following expression matches strings that contain "cat", "dog", "fox", and "wolf" if no more than four indexed tokens separate them. + +`near(cat, dog, fox, wolf)` - **Example 1.** The following expression matches strings that contain both "cat" and "dog" if no more than four indexed tokens (default) separate them. - - - - `near(cat, dog)` - - - - **Example 2.** The following expression matches strings that contain "cat", "dog", "fox", and "wolf" if no more than four indexed tokens separate them. - - - - `near(cat, dog, fox, wolf)` - - - The following table contains examples of managed property string values and states whether they match the previous expression in Example 2. - - - +| Match? | Text | +| :------------------ | :--------------------------------------------------------- | +| Yes | The picture shows a cat, a dog, a fox, and a wolf. | +| Yes (with stemming) | Dogs, foxes, and wolves are canines, but cats are felines. | +| No | The picture shows a cat with a dog, a fox, and a wolf. | -|**Match?**|**Text**| -|:-----|:-----| -|Yes
|The picture shows a cat, a dog, a fox, and a wolf.
| -|Yes (with stemming)
|Dogs, foxes, and wolves are canines, but cats are felines.
| -|No
|The picture shows a cat with a dog, a fox, and a wolf.
| - The following expression matches all the strings in the previous table. - - - - `near(cat, dog, fox, wolf, N=5)` - - - + +`near(cat, dog, fox, wolf, N=5)` #### Remarks - **NEAR/ONEAR term distance considerations** - - - - _N_ indicates the maximum number of words that are allowed to appear between the query terms within the matching segment of the item. If **NEAR** or **ONEAR** includes more than two operands, the maximum number of words allowed between the query terms ( _N_) is counted within the segment of the item matching all the **NEAR** or **ONEAR** terms. - - - - **NEAR** or **ONEAR** operates on tokenized text. This means that special characters such as comma (" **,** "), period (" **.** "), colon (" **:** "), or semicolon (" **;** ") will be treated as white space. The term "distance" relates to tokens within the indexed text. - - - +**NEAR/ONEAR term distance considerations** + +_N_ indicates the maximum number of words that are allowed to appear between the query terms within the matching segment of the item. If **NEAR** or **ONEAR** includes more than two operands, the maximum number of words allowed between the query terms ( _N_) is counted within the segment of the item matching all the **NEAR** or **ONEAR** terms. + +**NEAR** or **ONEAR** operates on tokenized text. This means that special characters such as comma (" **,** "), period (" **.** "), colon (" **:** "), or semicolon (" **;** ") will be treated as white space. The term "distance" relates to tokens within the indexed text. + If you use **ONEAR** or **NEAR** with equal operands, the operator will work as follows: - - - - `near(a, a, n=x)` - - - -This query will always return **true** if at least one instance of '' `a`'' appears within the context. This also means that **NEAR** cannot be used as a **COUNT** operator. For more information about counting term occurrences, see the [COUNT](fast-query-language-fql-syntax-reference.md#fql_count_operator) operator. - - - - **NEAR** applied to phrases will also match overlapping phrases in the text. - - - -If a token in the matching segment matches more than one operand to the **NEAR** or **ONEAR** expression, the query may match even if the number of nonmatching tokens within the matching segment exceeds the value of ' _N_' in the **NEAR** or **ONEAR** operator expression. For example, an overlap can be overlapping phrases. If the number of token overlap matches is ' `O`', the query will match if not more than ' `N+O`' non-matching tokens appear within the matching segment of the item. - - - + +`near(a, a, n=x)` + +This query will always return **true** if at least one instance of '' `a`'' appears within the context. This also means that **NEAR** cannot be used as a **COUNT** operator. For more information about counting term occurrences, see the [COUNT](#count) operator. + +**NEAR** applied to phrases will also match overlapping phrases in the text. + +If a token in the matching segment matches more than one operand to the **NEAR** or **ONEAR** expression, the query may match even if the number of nonmatching tokens within the matching segment exceeds the value of ' _N_' in the **NEAR** or **ONEAR** operator expression. For example, an overlap can be overlapping phrases. If the number of token overlap matches is ' `O`', the query will match if not more than ' `N+O`' non-matching tokens appear within the matching segment of the item. + **NEAR or ONEAR with NOT** - - - + The **NOT** operator cannot be used inside the **NEAR** or **ONEAR** operator. The following is incorrect FQL syntax: - - - - `near(audi,not(bmw),n=2)` - - - + +`near(audi,not(bmw),n=2)` ### NOT - Returns only items that don't match the operand. The operand may be any valid FQL expression. - - - #### Syntax - `not(operand)` - - - +`not(operand)` #### Parameters Not applicable. - - - ### ONEAR - The ordered variant of **NEAR**, and requires an ordered match of the terms. The **ONEAR** operator can be used to restrict the result set to items that have _N_ terms within a certain distance of one another. - - - #### Syntax - `onear(arg, arg [, arg]* [, N=])` - - - +`onear(arg, arg [, arg]* [, N=])` #### Parameters +| Parameter | Value | Description | +| :-------- | :------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _N_ | _\_ | Specifies the maximum number of words that are allowed to appear between the terms (explicit proximity). If **ONEAR** includes more than two operands, the maximum number of words allowed between the terms ( _N_) is counted within the whole expression. Default: **4** | +#### Examples -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _N_
| _\_
|Specifies the maximum number of words that are allowed to appear between the terms (explicit proximity).
If **ONEAR** includes more than two operands, the maximum number of words allowed between the terms ( _N_) is counted within the whole expression.
Default: **4**
| - +**Example 1.** The following expression matches all the occurrences of the words "cat", "dog", "fox", and "wolf" that appears in order, if no more than four indexed tokens separate them. -#### Examples +`onear(cat, dog, fox, wolf)` - **Example 1.** The following expression matches all the occurrences of the words "cat", "dog", "fox", and "wolf" that appears in order, if no more than four indexed tokens separate them. - - - - `onear(cat, dog, fox, wolf)` - - - The following table contains examples of managed property string values, and states whether they match the previous expression. - - - - - -|**Match?**|**Text**| -|:-----|:-----| -|Yes
|The picture shows a cat, a dog, a fox, and a wolf.
| -|No
|Dogs, foxes, and wolves are canines, but cats are felines.
| -|No
|The picture shows a cat with a dog, a fox, and a wolf.
| - - **Example 2.** The following expression matches (with stemming) the text in the second row of the previous table. - - - - `onear(dog, fox, wolf, cat, N=5)` - - - - **Example 3.** The following expression matches the text in the first and third rows of the preceding table. - - - - `onear(cat, dog, fox, wolf, N=5)` - - - + +| Match? | Text | +| :----- | :--------------------------------------------------------- | +| Yes | The picture shows a cat, a dog, a fox, and a wolf. | +| No | Dogs, foxes, and wolves are canines, but cats are felines. | +| No | The picture shows a cat with a dog, a fox, and a wolf. | + +**Example 2.** The following expression matches (with stemming) the text in the second row of the previous table. + +`onear(dog, fox, wolf, cat, N=5)` + +**Example 3.** The following expression matches the text in the first and third rows of the preceding table. + +`onear(cat, dog, fox, wolf, N=5)` #### Remarks -See also [NEAR](fast-query-language-fql-syntax-reference.md#fql_near_operator). - - - +See also [NEAR](#near). ### OR - Returns only items that match at least one of the **OR** operands. Items that match will get a higher dynamic rank (relevance score in the result set) if more of the **OR** operands match. The operands may be a single term or any valid FQL sub-expression. - - - #### Syntax - `or(operand, operand [,operand]*)` - - - +`or(operand, operand [,operand]*)` #### Parameters Not applicable. - - - #### Examples The following expression matches all the items for which the default full-text index contains either "cat" or "dog". If an item's default full-text index contains both "cat" and "dog", it will match and have a higher dynamic rank than it would if it contained only one of the tokens. - - - - `or(cat, dog)` - - - + +`or(cat, dog)` ### PHRASE - -Searches for an exact string of tokens. - - - +Searches for an exact string of tokens. + The **PHRASE** operands can be single terms. Wildcards are accepted. - - - #### Syntax - `phrase(term [, term]*)` - - - +`phrase(term [, term]*)` #### Parameters Not applicable. - - - #### Remarks -See also [STRING](fast-query-language-fql-syntax-reference.md#fql_string_operator). - - - +See also [STRING](#string). ### RANGE - Use the **RANGE** operator for numeric and date/time managed properties. The operator enables range matching expressions. - - - #### Syntax - `range(start, stop [,from="GE"|"GT"] [,to="LE"|"LT"])` - - - +`range(start, stop [,from="GE"|"GT"] [,to="LE"|"LT"])` #### Parameters - - -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _start_
| _\\|\_
|Start value for the range.
To specify that the range has no lower bound, use the reserved word **min**.
| -| _stop_
| _\\|\_
|End value for the range.
To specify that the range has no upper bound, use the reserved word **max**.
| -| _from_
|**GE\|GT**
| Optional parameter that indicates the open or close start interval.
Valid values:
  • **GE** Greater than or equal to the start value (>= start of interval).
  • **GT** Greater than the start value (> start of interval).
Default: **GE** | -| _to_
|**LE\|LT**
| Optional parameter that indicates the open or close end interval.
Valid values:
  • **LE** Less than or equal to the end value (<= end of interval).
  • **LT** Less than the end value (< end of interval).
Default: **LT** | - +| Parameter | Value | Value | Description | +| :-------- | :------------------ | :------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _start_ | _\\ | \_ | Start value for the range. To specify that the range has no lower bound, use the reserved word **min**. | +| _stop_ | _\\ | \_ | End value for the range. To specify that the range has no upper bound, use the reserved word **max**. | +| _from_ | **GE\ | GT** | Optional parameter that indicates the open or close start interval. Valid values:
  • **GE** Greater than or equal to the start value (>= start of interval).
  • **GT** Greater than the start value (> start of interval).
Default: **GE** | +| _to_ | **LE\ | LT** | Optional parameter that indicates the open or close end interval. Valid values:
  • **LE** Less than or equal to the end value (<= end of interval).
  • **LT** Less than the end value (< end of interval).
Default: **LT** | #### Examples The following expression matches a description property starting with the phrase "big accomplishments" appearing in items with a size of at least 10 000 bytes. - - - - `and(size:range(10000, max), description:starts-with("big accomplishments"))` - - - + +`and(size:range(10000, max), description:starts-with("big accomplishments"))` ### STARTS-WITH - Specifies a word or phrase that must appear at the start of a managed property. - - - #### Syntax - `starts-with()` - - - +`starts-with()` #### Parameters Not applicable. - - - #### Examples The following expression will match items with the values "Adam Jones sr" and "Adam Jones" in the **author** managed property. It will not match items with the value "Mr Adam Jones". - - - - `author:starts-with("adam jones")` - - - + +`author:starts-with("adam jones")` #### Remarks -For additional remarks on boundary matching, see [ENDS-WITH](fast-query-language-fql-syntax-reference.md#fql_endswith_operator). - - - +For additional remarks on boundary matching, see [ENDS-WITH](#ends-with). ### STRING - Defines a Boolean matching condition to a text string. - - - -The operand is a text string (one or more terms) that is to be matched. The string is followed by zero or more parameters. - - - + +The operand is a text string (one or more terms) that is to be matched. The string is followed by zero or more parameters. + The **STRING** operator can also be used as a type conversion. The query `string("24.5")`, for example, will treat the numeric value "24.5" as a text string. - - - #### Syntax - `string(""` - - - - ` [, mode=]` - - - - ` [, n=]` - - - - ` [, weight=]` - - - - ` [, linguistics=]` - - - - ` [, wildcard=])` - - - +`string(""` -#### Parameters +` [, mode=]` +` [, n=]` +` [, weight=]` -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _mode_
| _\_
| The _mode_ parameter specifies how to evaluate the \ value. The following list shows valid values.
**"PHRASE"** - `phrase(term [,term]*)`
**Mode****Equivalent operator expression**
**"PHRASE"** `phrase(term [,term]*)`
**"AND"** `and(term, term [,term]*)`
**"OR"** `or(term, term [,term]*)`
**"ANY"** `any(term, term [,term]*)`
**"NEAR"** `near(term, term [,term]*, N)`
**"ONEAR"** `onear(term, term [,term]*, N)`

Default: **"PHRASE"** | -| _n_
| _\_
|This parameter indicates the maximum term distance for _mode_= **"NEAR"** or _mode_= **"ONEAR"**.
The following expressions are equivalent:
`string("hello world", mode="NEAR", n=5)`
`near(hello, world, n=5)`
Default: **4**
| -| _weight_
| _\_
|This parameter is a positive numeric value indicating term weight for dynamic ranking.
A lower value indicates that a term should contribute less to the ranking. A higher value indicates that a term should contribute more to the ranking. A value of zero for the weight parameter specifies that a term should not affect dynamic rank.
The _weight_ parameter applies to all the terms in the **STRING** expression.
**TIP:** The weight parameter will affect only full-text index queries. Default: **100**.
| -| _linguistics_
|**on\|off**
|Disables/enables all linguistics features for the string (lemmatization, synonyms, spelling checking) if they are enabled for the query.
You can use this parameter to switch off linguistic processing for a given term or string while you still want the term or string to contribute to ranking.
Default: **"ON"**
| -| _wildcard_
|**on\|off**
| This parameter controls wildcard expansion of terms inside the _\_. This setting overrides any wildcard settings in query parameters, and allows extended wildcard characters to be enabled or disabled on specific parts of the query.
The following are valid values:
  • **"ON"** Specifies that the character "\*" is evaluated as wildcard. A "\*" character matches zero or more characters.
  • **"OFF"** Specifies that the characters "\*" is not evaluated as wildcard.
Default: **"ON"**
| - -> [!NOTE] -> In SharePoint the _minexpansion_, _maxexpansion_ and _annotation_class_ parameters for the **STRING** operator are obsolete. - - - +` [, linguistics=]` +` [, wildcard=])` + +#### Parameters + +| Parameter | Value | Description | +| :------------------ | :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _mode_ | _\_ | The _mode_ parameter specifies how to evaluate the \ value. The following list shows valid values. **"PHRASE"** - `phrase(term [,term]*)`
**Mode****Equivalent operator expression**
**"PHRASE"** `phrase(term [,term]*)`
**"AND"** `and(term, term [,term]*)`
**"OR"** `or(term, term [,term]*)`
**"ANY"** `any(term, term [,term]*)`
**"NEAR"** `near(term, term [,term]*, N)`
**"ONEAR"** `onear(term, term [,term]*, N)`
Default: **"PHRASE"** | +| _n_ | _\_ | This parameter indicates the maximum term distance for _mode_= **"NEAR"** or _mode_= **"ONEAR"**. The following expressions are equivalent: `string("hello world", mode="NEAR", n=5)` `near(hello, world, n=5)` Default: **4** | +| _weight_ | _\_ | This parameter is a positive numeric value indicating term weight for dynamic ranking. A lower value indicates that a term should contribute less to the ranking. A higher value indicates that a term should contribute more to the ranking. A value of zero for the weight parameter specifies that a term should not affect dynamic rank. The _weight_ parameter applies to all the terms in the **STRING** expression. **TIP:** The weight parameter will affect only full-text index queries. Default: **100**. | +| _linguistics_ | **on\|off** | Disables/enables all linguistics features for the string (lemmatization, synonyms, spelling checking) if they are enabled for the query. You can use this parameter to switch off linguistic processing for a given term or string while you still want the term or string to contribute to ranking. Default: **"ON"** | +| _wildcard_ | **on\|off** | This parameter controls wildcard expansion of terms inside the _\_. This setting overrides any wildcard settings in query parameters, and allows extended wildcard characters to be enabled or disabled on specific parts of the query. The following are valid values:
  • **"ON"** Specifies that the character "\*" is evaluated as wildcard. A "\*" character matches zero or more characters.
  • **"OFF"** Specifies that the characters "\*" is not evaluated as wildcard.
Default: **"ON"** | + +> [!NOTE] +> In SharePoint the _minexpansion_, _maxexpansion_ and _annotation_class_ parameters for the **STRING** operator are obsolete. #### Examples - **Example 1.** Because the default string mode is " **PHRASE** ", each of the following expressions returns the same results. - - - - `"what light through yonder window breaks"string("what light through yonder window breaks")string("what light through yonder window breaks", mode="phrase")phrase(what, light, through, yonder, window, breaks)` - - - - **Example 2.** The following string token expression and the **AND** operator expression return the same results. - - - - `string("cat dog fox", mode="and")and(cat, dog, fox)` - - - - **Example 3.** The following string token expression and **OR** operator expression return the same results. - - - - `string("coyote saguaro", mode="or")or(coyote, saguaro)` - - - - **Example 4.** The following string token expression and **ANY** operator expression return the same results. - - - - `string("coyote saguaro", mode="any")any(coyote, saguaro)` - - - - **Example 5.** The following string token expression and **NEAR** operator expression return the same results. - - - - `string("coyote saguaro", mode="near")near(coyote, saguaro)` - - - - **Example 6.** The following string token expression and **NEAR** operator expression return the same results. - - - - `string("cat dog fox wolf", mode="near", N=4)near(cat, dog, fox, wolf, N=4)` - - - - **Example 7.** The following string token expression and **ONEAR** operator expression return the same results. - - - - `string("cat dog fox wolf", mode="onear")onear(cat, dog, fox, wolf)` - - - - **Example 8.** The following string token expression matches the word "nobler" with linguistic features disabled, so other forms of the word (such as "ennobling") are not matched by using stemming. - - - - `string("nobler", linguistics="off")` - - - - **Example 9.** The following expression matches items that contain either "cat" or "dog ", but the expression increases the dynamic rank of items that contain "dog" more than items that contain "cat". - - - - `or(string("cat", weight="200"), string("dog", weight="500"))` - - - +**Example 1.** Because the default string mode is " **PHRASE** ", each of the following expressions returns the same results. + +`"what light through yonder window breaks"string("what light through yonder window breaks")string("what light through yonder window breaks", mode="phrase")phrase(what, light, through, yonder, window, breaks)` + +**Example 2.** The following string token expression and the **AND** operator expression return the same results. + +`string("cat dog fox", mode="and")and(cat, dog, fox)` + +**Example 3.** The following string token expression and **OR** operator expression return the same results. + +`string("coyote saguaro", mode="or")or(coyote, saguaro)` + +**Example 4.** The following string token expression and **ANY** operator expression return the same results. + +`string("coyote saguaro", mode="any")any(coyote, saguaro)` + +**Example 5.** The following string token expression and **NEAR** operator expression return the same results. + +`string("coyote saguaro", mode="near")near(coyote, saguaro)` + +**Example 6.** The following string token expression and **NEAR** operator expression return the same results. + +`string("cat dog fox wolf", mode="near", N=4)near(cat, dog, fox, wolf, N=4)` + +**Example 7.** The following string token expression and **ONEAR** operator expression return the same results. + +`string("cat dog fox wolf", mode="onear")onear(cat, dog, fox, wolf)` + +**Example 8.** The following string token expression matches the word "nobler" with linguistic features disabled, so other forms of the word (such as "ennobling") are not matched by using stemming. + +`string("nobler", linguistics="off")` + +**Example 9.** The following expression matches items that contain either "cat" or "dog ", but the expression increases the dynamic rank of items that contain "dog" more than items that contain "cat". + +`or(string("cat", weight="200"), string("dog", weight="500"))` #### Remarks - **Relevance weight for dynamic ranking** - - - +**Relevance weight for dynamic ranking** + The main effect of the **weight** parameter is for **OR** queries. It can also have some effect on **AND** queries. The dynamic rank algorithm can imply that different terms give different rank contribution depending on where in the item the term match occurs. - - - + The difference in rank contribution can also be based on term frequency and inverse item frequency. The following is an example: - - - -- Query: `and(string("a"), string("b", weight=200))` - - +- Query: `and(string("a"), string("b", weight=200))` - Index schema: The **title** managed property has more weight than the **body** managed property. - - -- Index item 1 includes term 'a' in the title and term 'b' in the body. - - -- Index item 2 includes term 'a' in the body and term 'b' in the title. - - +- Index item 1 includes term 'a' in the title and term 'b' in the body. +- Index item 2 includes term 'a' in the body and term 'b' in the title. + In this example, item 2 will get the highest total rank, as the items with higher dynamic rank contribution will get even more boost. - - - > **Tip:** -> The relative term boost (positive or negative) is applied to the dynamic rank component of the total rank. However, proximity boost (distance between words) rank calculations are not affected by the term weighting. The relative weighting does not always imply that the total rank for the item is modified according to the percentage given. > The following query will search for the terms "peter", "paul", or "mary", where "peter" will have twice as much rank contribution as the two other terms. > `or(peter, string("paul mary", mode="OR", weight=50))` - - - - - **Handling strings with special characters** - - - -Special characters such as comma (","), semicolon (";"), colon (":"), period ("."), minus ("-"), underline ("_"), or forward slash ("/") are treated as white space inside a string expression enclosed in double quotation marks. This is related to the tokenization process. These characters also imply an implicit phrasing of the tokens separated by these characters. - - - +> The relative term boost (positive or negative) is applied to the dynamic rank component of the total rank. However, proximity boost (distance between words) rank calculations are not affected by the term weighting. The relative weighting does not always imply that the total rank for the item is modified according to the percentage given. > The following query will search for the terms "peter", "paul", or "mary", where "peter" will have twice as much rank contribution as the two other terms. > `or(peter, string("paul mary", mode="OR", weight=50))` + +**Handling strings with special characters** + +Special characters such as comma (","), semicolon (";"), colon (":"), period ("."), minus ("-"), underline ("\_"), or forward slash ("/") are treated as white space inside a string expression enclosed in double quotation marks. This is related to the tokenization process. These characters also imply an implicit phrasing of the tokens separated by these characters. + The following query expressions are equivalent. - - - - `title:string("animals birds", mode="phrase")title:"animals/birds"title:string("animals/birds", mode="and")title:string("animals/birds", mode="or")` - - - + +`title:string("animals birds", mode="phrase")title:"animals/birds"title:string("animals/birds", mode="and")title:string("animals/birds", mode="or")` + The following query expressions are equivalent. - - - - `title:or(string("animals birds", mode="phrase"), string("animals insects", mode="phrase"))title:string("animals/birds animals/insects", mode="or")` - - - + +`title:or(string("animals birds", mode="phrase"), string("animals insects", mode="phrase"))title:string("animals/birds animals/insects", mode="or")` + The following query expressions are equivalent. - - - - `body:string("help contoso com", mode="phrase")body:string("help@contoso.com")` - - - - **Tokenized phrase matching** - - - + +`body:string("help contoso com", mode="phrase")body:string("help@contoso.com")` + +**Tokenized phrase matching** + You can search for an exact string of tokens by using the **STRING** operator with _mode_="phrase" or the **PHRASE** operator. - - - + All such phrase operations imply a tokenized phrase match. This means that special characters such as comma (" **,** "), semicolon (" **;** "), colon (" **:** "), underscore (" \_ "), minus (" **-** "), or forward slash (" **/** ") are treated as white space. This is related to the tokenization process. - - - ### XRANK - - -Boosts the dynamic rank of items based on certain term occurrences within the _match expression_, without changing which items match the query. An **XRANK** expression consists of one component that must be matched, the _match expression_, and one or more components that contribute only to dynamic ranking, the _rank expression_. At least **one** of the parameters, excluding _n_, must be specified for an XRANK expression to be valid. - - - - _Match expressions_ may be any valid FQL expression, including nested **XRANK** expressions. _Rank expressions_ may be any valid FQL expression without **XRANK** expressions. If your FQL queries have multiple **XRANK** operators, the final dynamic rank value is calculated as a sum of boosts across all **XRANK** operators. - -> [!NOTE] -> In SharePoint Server 2010, the **XRANK** operator had two parameters: _boost_ and _boostall_, as well as the following syntax: `xrank(operand, rank-operand [, rank-operand]* [,boost=n] [,boostall=yes])`. This syntax along with its parameters is deprecated in SharePoint. We recommend the use of the new syntax and parameters instead. - - - +Boosts the dynamic rank of items based on certain term occurrences within the _match expression_, without changing which items match the query. An **XRANK** expression consists of one component that must be matched, the _match expression_, and one or more components that contribute only to dynamic ranking, the _rank expression_. At least **one** of the parameters, excluding _n_, must be specified for an XRANK expression to be valid. + +_Match expressions_ may be any valid FQL expression, including nested **XRANK** expressions. _Rank expressions_ may be any valid FQL expression without **XRANK** expressions. If your FQL queries have multiple **XRANK** operators, the final dynamic rank value is calculated as a sum of boosts across all **XRANK** operators. + +> [!NOTE] +> In SharePoint Server 2010, the **XRANK** operator had two parameters: _boost_ and _boostall_, as well as the following syntax: `xrank(operand, rank-operand [, rank-operand]* [,boost=n] [,boostall=yes])`. This syntax along with its parameters is deprecated in SharePoint. We recommend the use of the new syntax and parameters instead. #### Syntax - `xrank( [, ]*, rank-parameter[, rank-parameter]*)` - - - +`xrank( [, ]*, rank-parameter[, rank-parameter]*)` #### Formula - - - - ![Formula for XRANK operator](../images/XRANKFormula.gif) - - - - - - - - - - - #### Parameters +| Parameter | Value | Description | +| :------------ | :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| _N_ | _\_ | Specifies the number of results to compute statistics from. This parameter does not affect the number of results that the dynamic rank contributes to; it is just a means to exclude irrelevant items from the statistics calculations. Default: **0**. A zero value carries the sematic of _all documents_ . | +| _Nb_ | _\_ | The _nb_ parameter refers to normalized boost. This parameter specifies the factor that is multiplied with the product of the variance and average score of the rank values of the results set. _f_ in the XRANK formula. | - -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _N_
| _\_
|Specifies the number of results to compute statistics from.
This parameter does not affect the number of results that the dynamic rank contributes to; it is just a means to exclude irrelevant items from the statistics calculations.
Default: **0**. A zero value carries the sematic of *all documents* .
| -| _Nb_
| _\_
|The _nb_ parameter refers to normalized boost. This parameter specifies the factor that is multiplied with the product of the variance and average score of the rank values of the results set.
_f_ in the XRANK formula.
| - -Typically normalized boost, _nb_, is the only parameter that is modified. This parameter provides the necessary control to promote or demote a particular item, without taking standard deviation into account. - - - +Typically normalized boost, _nb_, is the only parameter that is modified. This parameter provides the necessary control to promote or demote a particular item, without taking standard deviation into account. #### Advanced parameters The following advanced parameters are also available. However, typically they aren't used. - - - - -|**Parameter**|**Value**|**Description**| -|:-----|:-----|:-----| -| _cb_
| _\_
|The _cb_ parameter refers to constant boost.
Default: **0**.
_a_ in the XRANK formula.
| -| _stdb_
| _\_
|The _stdb_ parameter refers to standard deviation boost.
Default: **0**.
_e_ in the XRANK formula.
| -| _avgb_
| _\_
|The _avgb_ parameter refers to average boost. This factor is multiplied with the average rank value of the results set.
Default: **0**.
_d_ in the XRANK formula.
| -| _rb_
| _\_
|The _rb_ parameter refers to range boost. This factor is multiplied with the range of rank values in the results set.
Default: **0**.
_b_ in the XRANK formula.
| -| _pb_
| _\_
|The _pb_ parameter refers to percentage boost. This factor is multiplied with the item's own rank compared to the minimum value in the corpus.
Default: **0**.
_c_ in the XRANK formula.
| - +| Parameter | Value | Description | +| :------------ | :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _cb_ | _\_ | The _cb_ parameter refers to constant boost. Default: **0**. _a_ in the XRANK formula. | +| _stdb_ | _\_ | The _stdb_ parameter refers to standard deviation boost. Default: **0**. _e_ in the XRANK formula. | +| _avgb_ | _\_ | The _avgb_ parameter refers to average boost. This factor is multiplied with the average rank value of the results set. Default: **0**. _d_ in the XRANK formula. | +| _rb_ | _\_ | The _rb_ parameter refers to range boost. This factor is multiplied with the range of rank values in the results set. Default: **0**. _b_ in the XRANK formula. | +| _pb_ | _\_ | The _pb_ parameter refers to percentage boost. This factor is multiplied with the item's own rank compared to the minimum value in the corpus. Default: **0**. _c_ in the XRANK formula. | #### Examples - **Example 1.** The following expression matches items for which the default full-text index contains either "cat" or "dog". The expression increases dynamic rank of those items with a constant boost of 100 for items that also contain "thoroughbred". - - - - `xrank(or(cat, dog), thoroughbred, cb=100)` - - - - **Example 2.** The following expression matches items for which the default full-text index contains either "cat" or "dog". The expression increases dynamic rank of those items with a normalized boost of 1.5 for items that also contain "thoroughbred". - - - - `xrank(or(cat, dog), thoroughbred, nb=1.5)` - - - - **Example 3.** The following expression matches items for which the default full-text index contains either "cat" or "dog". The expression increases dynamic rank of those items with a constant boost of 100 and a normalized boost of 1.5, for items that also contain "thoroughbred". - - - - `xrank(or(cat, dog), thoroughbred, cb=100, nb=1.5)` - - - - **Example 4.** The following expression matches all items containing the term "animals", and boosts dynamic rank as follows: - - - +**Example 1.** The following expression matches items for which the default full-text index contains either "cat" or "dog". The expression increases dynamic rank of those items with a constant boost of 100 for items that also contain "thoroughbred". + +`xrank(or(cat, dog), thoroughbred, cb=100)` + +**Example 2.** The following expression matches items for which the default full-text index contains either "cat" or "dog". The expression increases dynamic rank of those items with a normalized boost of 1.5 for items that also contain "thoroughbred". + +`xrank(or(cat, dog), thoroughbred, nb=1.5)` + +**Example 3.** The following expression matches items for which the default full-text index contains either "cat" or "dog". The expression increases dynamic rank of those items with a constant boost of 100 and a normalized boost of 1.5, for items that also contain "thoroughbred". + +`xrank(or(cat, dog), thoroughbred, cb=100, nb=1.5)` + +**Example 4.** The following expression matches all items containing the term "animals", and boosts dynamic rank as follows: - Dynamic rank of items that contain the term "dogs" is boosted by 100 points. - - + - Dynamic rank of items that contain the term "cats" is boosted by 200 points. - - + - Dynamic rank of items that contain both the terms "dogs" and "cats" is boosted by 300 points. - - - `xrank(xrank(animals, dogs, cb=100), cats, cb=200)` - - - -## See also - +`xrank(xrank(animals, dogs, cb=100), cats, cb=200)` +## See also -- [Building search queries in SharePoint](building-search-queries-in-sharepoint.md) - - +- [Building search queries in SharePoint](building-search-queries-in-sharepoint.md) diff --git a/docs/general-development/follow-content-in-sharepoint.md b/docs/general-development/follow-content-in-sharepoint.md index 5abf78f05..13944f2dd 100644 --- a/docs/general-development/follow-content-in-sharepoint.md +++ b/docs/general-development/follow-content-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Follow content in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the APIs for programmatically following content in SharePoint and provides lists of SharePoint APIs. +ms.date: 06/09/2022 ms.assetid: 30e68cd6-6e55-4cf9-afd6-7139b0a97288 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -65,7 +65,7 @@ Table 1 shows the manager and other key objects (or REST resources) in the APIs **Table 1. SharePoint APIs used for following content programmatically** -|**API**|**Key objects**| +|API|Key objects| |:-----|:-----| |.NET client object model
See: [How to: Follow documents and sites by using the .NET client object model in SharePoint](how-to-follow-documents-and-sites-by-using-the-net-client-object-model-in-sharep.md)|Manager object: [SocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFollowingManager.aspx)
Primary namespace: [Microsoft.SharePoint.Client.Social](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.aspx)
Other key objects: [SocialActor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActor.aspx) , [SocialActorInfo](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActorInfo.aspx) , [SocialActorType](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActorType.aspx) , [SocialActorTypes](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActorTypes.aspx)
Class library: Microsoft.SharePoint.Client.UserProfiles.dll | |JavaScript object model|Manager object: [SocialFollowingManager](https://msdn.microsoft.com/library/9ee1c0c0-b864-f0c3-f0cb-4dd4f1870dfa%28Office.15%29.aspx)
Primary namespace: [SP.Social](https://msdn.microsoft.com/library/43d47f01-c085-0e77-bd01-48bcb7d5bb35%28Office.15%29.aspx)
Other key objects: [SocialActor](https://msdn.microsoft.com/library/4e369fd5-b9b0-9804-957e-b3e39c559cd4%28Office.15%29.aspx), [SocialActorInfo](https://msdn.microsoft.com/library/d940db32-1561-c868-bb66-0612e2031f17%28Office.15%29.aspx), [SocialActorType](https://msdn.microsoft.com/library/fbde74da-f292-dc87-0b7e-81bc5b7a880c%28Office.15%29.aspx), [SocialActorTypes](https://msdn.microsoft.com/library/a460c3e6-ed88-117d-6755-4c5803a154a0%28Office.15%29.aspx)
Class library: SP.UserProfiles.js | @@ -88,7 +88,7 @@ Table 2 shows common programming tasks for following content and the members tha **Table 2. API for common tasks for following content in SharePoint** -|**Task**|**Members**| +|Task|Members| |:-----|:-----| |Create an instance of a manager object in the context of the current user|CSOM: [SocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFollowingManager.aspx)
JSOM: [SocialFollowingManager](https://msdn.microsoft.com/library/9ee1c0c0-b864-f0c3-f0cb-4dd4f1870dfa%28Office.15%29.aspx)
REST: `/_api/social.following`
SSOM: [SPSocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.Office.Server.Social.SPSocialFollowingManager.aspx)| |Create an instance of a manager object in the context of a specified user|CSOM: not implemented
JSOM: not implemented
REST: not implemented
SSOM: [SPSocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.Office.Server.Social.SPSocialFollowingManager.aspx) (overloaded)| diff --git a/docs/general-development/follow-people-in-sharepoint.md b/docs/general-development/follow-people-in-sharepoint.md index 878920949..fb74dd3c7 100644 --- a/docs/general-development/follow-people-in-sharepoint.md +++ b/docs/general-development/follow-people-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Follow people in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the common programming tasks for following people in SharePoint and provides a list of APIs for programmatically following people. +ms.date: 06/09/2022 ms.assetid: 0fa2e235-63d0-41b1-9eed-4aeb2f59a14d -localization_priority: Normal +ms.localizationpriority: medium --- @@ -65,7 +65,7 @@ Table 1 shows the manager and other key objects (or REST resources) in the APIs **Table 1. SharePoint APIs used for following people programmatically** -|**API**|**Key objects**| +|API|Key objects| |:-----|:-----| |.NET client object model
See: [How to: Follow people by using the .NET client object model in SharePoint](how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md)|Manager object: [SocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFollowingManager.aspx)
Primary namespace: [Microsoft.SharePoint.Client.Social](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.aspx)
Other key objects: [SocialActor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActor.aspx) , [SocialActorInfo](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActorInfo.aspx) , [SocialActorType](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActorType.aspx) , [SocialActorTypes](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialActorTypes.aspx)
Class library: Microsoft.SharePoint.Client.UserProfiles.dll | |JavaScript object model
See: [How to: Follow people by using the JavaScript object model in SharePoint](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md)|Manager object: [SocialFollowingManager](https://msdn.microsoft.com/library/9ee1c0c0-b864-f0c3-f0cb-4dd4f1870dfa%28Office.15%29.aspx)
Primary namespace: **SP.Social**
Other key objects: [SocialActor](https://msdn.microsoft.com/library/4e369fd5-b9b0-9804-957e-b3e39c559cd4%28Office.15%29.aspx), [SocialActorInfo](https://msdn.microsoft.com/library/d940db32-1561-c868-bb66-0612e2031f17%28Office.15%29.aspx), [SocialActorType](https://msdn.microsoft.com/library/fbde74da-f292-dc87-0b7e-81bc5b7a880c%28Office.15%29.aspx), [SocialActorTypes](https://msdn.microsoft.com/library/a460c3e6-ed88-117d-6755-4c5803a154a0%28Office.15%29.aspx)
Class library: SP.UserProfiles.js | @@ -92,7 +92,7 @@ The **SocialFollowingManager** object consolidates the core Following People and **Table 2. API for common tasks for following people by using the SocialFollowingManager object** -|**Task**|**Members**| +|Task|Members| |:-----|:-----| |Create an instance of a manager object in the context of the current user |CSOM: [SocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFollowingManager.aspx)
JSOM: **SocialFollowingManager**
REST: `/_api/social.following`
SSOM: [SPSocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.Office.Server.Social.SPSocialFollowingManager.aspx)| |Create an instance of a manager object in the context of a particular user |CSOM: not implemented
JSOM: not implemented
REST: not implemented
SSOM: [SPSocialFollowingManager](https://msdn.microsoft.com/library/Microsoft.Office.Server.Social.SPSocialFollowingManager.aspx) (overloaded)| @@ -111,7 +111,7 @@ Table 3 shows the **PeopleManager** members that you can use for additional Foll **Table 3. API for common tasks for following people by using the PeopleManager object** -|**Task**|**Members**| +|Task|Members| |:-----|:-----| |Find out whether the **People I'm Following** list for the current user is public|CSOM: [IsMyPeopleListPublic](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PeopleManager.IsMyPeopleListPublic.aspx)
JSOM: [isMyPeopleListPublic](https://msdn.microsoft.com/library/2ffc73a5-24ce-1ed4-d850-a6fea4c773bb%28Office.15%29.aspx)
REST: [IsMyPeopleListPublic](https://msdn.microsoft.com/library/10757ed1-6e86-474f-89e0-6dec6aa66a2b%28Office.15%29.aspx#bk_PeopleManagerProperties)
Example: **GET** `/_api/SP.UserProfiles.PeopleManager/IsMyPeopleListPublic`
SSOM: [IsMyPeopleListPublic](https://msdn.microsoft.com/library/Microsoft.Office.Server.UserProfiles.PeopleManager.IsMyPeopleListPublic.aspx)| |Find out whether someone is following the current user |CSOM: [AmIFollowedBy](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PeopleManager.AmIFollowedBy.aspx)
JSOM: [amIFollowedBy](https://msdn.microsoft.com/library/3641c469-0063-054d-355d-e56697cb08ae%28Office.15%29.aspx)
REST: [AmIFollowedBy](https://msdn.microsoft.com/library/10757ed1-6e86-474f-89e0-6dec6aa66a2b%28Office.15%29.aspx#bk_PeopleManagerAmIFollowedBy)
Example: **GET** `/_api/SP.UserProfiles.PeopleManager/AmIFollowedBy(accountName=@v)?@v='domain\\user'`
SSOM: [AmIFollowedBy](https://msdn.microsoft.com/library/Microsoft.Office.Server.UserProfiles.PeopleManager.AmIFollowedBy.aspx)| diff --git a/docs/general-development/following-people-and-content-rest-api-reference-for-sharepoint.md b/docs/general-development/following-people-and-content-rest-api-reference-for-sharepoint.md index 9a3cf0d0f..e917934f3 100644 --- a/docs/general-development/following-people-and-content-rest-api-reference-for-sharepoint.md +++ b/docs/general-development/following-people-and-content-rest-api-reference-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: Following people and content REST API reference for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes finding SharePoint REST endpoints for following people and content by using the SocialRestFollowingManager and the PeopleManager resources. +ms.date: 06/09/2022 ms.assetid: c05755df-846d-4a39-941d-950d066cc6d4 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/frequently-asked-questions-about-excel-services-udfs.md b/docs/general-development/frequently-asked-questions-about-excel-services-udfs.md deleted file mode 100644 index 3f534adef..000000000 --- a/docs/general-development/frequently-asked-questions-about-excel-services-udfs.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -title: Frequently Asked Questions About Excel Services UDFs -ms.date: 09/25/2017 -keywords: faqs -f1_keywords: -- faqs -ms.prod: sharepoint -ms.assetid: 3d94d040-eecf-4f8e-a316-6d1cca95e7eb -localization_priority: Normal ---- - - -# Frequently Asked Questions About Excel Services UDFs - -Here are some frequently asked questions about Excel Services user-defined functions (UDFs). - - - - - -## Creating Managed-Code UDFs - - -### What is a supported UDF class? - -The UDF class in a UDF assembly must be public. It can be sealed. It cannot be abstract, internal, or private. It must have a parameterless, public constructor. For languages that automatically generate a parameterless, public constructor (for example, C#), you can have no constructor at all. - - - - -### What is a supported UDF method? - -The UDF method in a UDF assembly must be public. The UDF method must be thread-safe. - - - -A UDF method cannot have: - - - - -- **ref** or **out** parameters - - -- **retval** attributes - - -- **Optional** arguments - - -- unsupported data types - - -The UDF method must also have a supported return type. For a list of supported data types, see the "Data Types" section of this topic. - - - - -### Can I call a Web service from a UDF assembly? - -Yes. For an example, see the following UDF sample code. Also see [How to: Create a UDF That Calls a Web Service](how-to-create-a-udf-that-calls-a-web-service.md). - - - - -```cs - -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Office.Excel.Server.Udf; -using UdfWS.dk.iter.webservices; - -namespace UdfWS -{ - [UdfClass] - public class MyUdfClass - { - // Instantiate the Web service. The Web service used is at - // http://webservices.iter.dk/calculator.asmx - Calculator calc = new Calculator(); - - [UdfMethod] - public int MyFunction() - { - int i; - i = (i + 88) * 2; - return i; - } - - [UdfMethod(IsVolatile = true)] - public double MyDouble(double d) - { - return d * 9; - } - - [UdfMethod] - public int AddMe(int a, int b) - { - int c; - // Call the Web service Add method - c = calc.Add(a, b); - return c; - } - } -} -``` - - -```VB.net - -Imports System -Imports System.Collections.Generic -Imports System.Text -Imports Microsoft.Office.Excel.Server.Udf -Imports UdfWS.dk.iter.webservices - -Namespace UdfWS - _ - Public Class MyUdfClass - ' Instantiate the Web service. The Web service used is at - ' http://webservices.iter.dk/calculator.asmx - Private calc As New Calculator() - - _ - Public Function MyFunction() As Integer - Dim i As Integer - i = (i + 88) * 2 - Return i - End Function - - _ - Public Function MyDouble(ByVal d As Double) As Double - Return d * 9 - End Function - - _ - Public Function AddMe(ByVal a As Integer, ByVal b As Integer) As Integer - Dim c As Integer - ' Call the Web service Add method - c = calc.Add(a, b) - Return c - End Function - End Class -End Namespace -``` - - -## Data Types - - -### What are the data types that can be used as UDF parameters? - -The supported data types are as follows: - - - - -- Numeric types: Double, Single, Int32, UInt32, Int16, UInt16, Byte, Sbyte - - -- String - - -- Boolean - - -- Object arrays: one- or two- dimensional arrays, that is, object [] and object [,] - - -- DateTime - - - -### What are the supported return value types? - -The supported return value types are as follows: - - - - -- Numeric types: Double, Single, Int32, UInt32, Int16, UInt16, Byte, Sbyte - - -- String - - -- Boolean - - -- Object arrays: one- or two-dimensional arrays, that is, object [], object [,], int[] and int[,]) - - -- DateTime - - -- Object - - - -## XLLs - - -### Are XLLs supported? - -Not directly. Excel Services will load and call only managed-code UDFs. However, you can write a managed-code wrapper to call the XLLs and deploy the XLLs to the server, together with the managed-code wrapper assembly. - - - - -## See also - - -#### Tasks - - - - - - [How to: Create a UDF That Calls a Web Service](how-to-create-a-udf-that-calls-a-web-service.md) - - - - [How to: Trust a Location](how-to-trust-a-location.md) - - - - [How to: Catch Exceptions](how-to-catch-exceptions.md) -#### Concepts - - - - - - [Understanding Excel Services UDFs](understanding-excel-services-udfs.md) - - - - [Walkthrough: Developing a Managed-Code UDF](walkthrough-developing-a-managed-code-udf.md) - - - - [Excel Services Architecture](excel-services-architecture.md) - - - - [Excel Services Alerts](excel-services-alerts.md) - - - - [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) - - - - [Excel Services Best Practices](excel-services-best-practices.md) diff --git a/docs/general-development/frequently-asked-questions-about-excel-services-udfs.yml b/docs/general-development/frequently-asked-questions-about-excel-services-udfs.yml new file mode 100644 index 000000000..761eaac4a --- /dev/null +++ b/docs/general-development/frequently-asked-questions-about-excel-services-udfs.yml @@ -0,0 +1,200 @@ +### YamlMime:FAQ +metadata: + title: Frequently Asked Questions About Excel Services UDFs + description: Here are some frequently asked questions about Excel Services user-defined functions (UDFs). + ms.date: 09/25/2017 + keywords: faqs + f1_keywords: + - faqs + ms.assetid: 3d94d040-eecf-4f8e-a316-6d1cca95e7eb + ms.localizationpriority: medium + +title: Frequently Asked Questions About Excel Services UDFs +summary: | + Here are some frequently asked questions about Excel Services user-defined functions (UDFs). + +sections: + - name: Creating Managed-Code UDFs + questions: + - question: | + What is a supported UDF class? + answer: | + The UDF class in a UDF assembly must be public. It can be sealed. It cannot be abstract, internal, or private. It must have a parameterless, public constructor. For languages that automatically generate a parameterless, public constructor (for example, C#), you can have no constructor at all. + + - question: | + What is a supported UDF method? + answer: | + The UDF method in a UDF assembly must be public. The UDF method must be thread-safe. + + A UDF method cannot have: + + - **ref** or **out** parameters + + - **retval** attributes + + - **Optional** arguments + + - unsupported data types + + The UDF method must also have a supported return type. For a list of supported data types, see the "Data Types" section of this topic. + + - question: | + Can I call a Web service from a UDF assembly? + answer: | + Yes. For an example, see the following UDF sample code. Also see [How to: Create a UDF That Calls a Web Service](how-to-create-a-udf-that-calls-a-web-service.md). + + ```csharp + using System; + using System.Collections.Generic; + using System.Text; + using Microsoft.Office.Excel.Server.Udf; + using UdfWS.dk.iter.webservices; + + namespace UdfWS + { + [UdfClass] + public class MyUdfClass + { + // Instantiate the Web service. The Web service used is at + // http://webservices.iter.dk/calculator.asmx + Calculator calc = new Calculator(); + + [UdfMethod] + public int MyFunction() + { + int i; + i = (i + 88) * 2; + return i; + } + + [UdfMethod(IsVolatile = true)] + public double MyDouble(double d) + { + return d * 9; + } + + [UdfMethod] + public int AddMe(int a, int b) + { + int c; + // Call the Web service Add method + c = calc.Add(a, b); + return c; + } + } + } + ``` + + + ```VB.net + + Imports System + Imports System.Collections.Generic + Imports System.Text + Imports Microsoft.Office.Excel.Server.Udf + Imports UdfWS.dk.iter.webservices + + Namespace UdfWS + _ + Public Class MyUdfClass + ' Instantiate the Web service. The Web service used is at + ' http://webservices.iter.dk/calculator.asmx + Private calc As New Calculator() + + _ + Public Function MyFunction() As Integer + Dim i As Integer + i = (i + 88) * 2 + Return i + End Function + + _ + Public Function MyDouble(ByVal d As Double) As Double + Return d * 9 + End Function + + _ + Public Function AddMe(ByVal a As Integer, ByVal b As Integer) As Integer + Dim c As Integer + ' Call the Web service Add method + c = calc.Add(a, b) + Return c + End Function + End Class + End Namespace + ``` + + - name: Data Types + questions: + - question: | + What are the data types that can be used as UDF parameters? + answer: | + The supported data types are as follows: + + - Numeric types: Double, Single, Int32, UInt32, Int16, UInt16, Byte, Sbyte + + + - String + + + - Boolean + + + - Object arrays: one- or two- dimensional arrays, that is, object [] and object [,] + + + - DateTime + + - question: | + What are the supported return value types? + answer: | + The supported return value types are as follows: + + - Numeric types: Double, Single, Int32, UInt32, Int16, UInt16, Byte, Sbyte + + - String + + - Boolean + + - Object arrays: one- or two-dimensional arrays, that is, object [], object [,], int[] and int[,]) + + - DateTime + + - Object + + + + - name: XLLs + questions: + - question: | + Are XLLs supported? + answer: | + Not directly. Excel Services will load and call only managed-code UDFs. However, you can write a managed-code wrapper to call the XLLs and deploy the XLLs to the server, together with the managed-code wrapper assembly. + + +additionalContent: | + + ## See also + + #### Tasks + + [How to: Create a UDF That Calls a Web Service](how-to-create-a-udf-that-calls-a-web-service.md) + + [How to: Trust a Location](how-to-trust-a-location.md) + + [How to: Catch Exceptions](how-to-catch-exceptions.md) + + #### Concepts + + + [Understanding Excel Services UDFs](understanding-excel-services-udfs.md) + + [Walkthrough: Developing a Managed-Code UDF](walkthrough-developing-a-managed-code-udf.md) + + [Excel Services Architecture](excel-services-architecture.md) + + [Excel Services Alerts](excel-services-alerts.md) + + [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) + + [Excel Services Best Practices](excel-services-best-practices.md) \ No newline at end of file diff --git a/docs/general-development/general-guidelines.md b/docs/general-development/general-guidelines.md index a96824143..c08754b48 100644 --- a/docs/general-development/general-guidelines.md +++ b/docs/general-development/general-guidelines.md @@ -1,9 +1,9 @@ --- title: General Guidelines -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Provides general information related to Excel Services and provides links to articles and tutorials about Excel Services. +ms.date: 06/09/2022 ms.assetid: 437541f8-5cd9-46f4-92b6-3bf9d7e62f69 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/get-started-developing-with-social-features-in-sharepoint.md b/docs/general-development/get-started-developing-with-social-features-in-sharepoint.md index c590fcd2b..9431f614a 100644 --- a/docs/general-development/get-started-developing-with-social-features-in-sharepoint.md +++ b/docs/general-development/get-started-developing-with-social-features-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Get started developing with social features in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to get started with developing SharePoint social features and provides links to articles and tutorials. +ms.date: 06/09/2022 ms.assetid: 8852ce36-8309-45a7-a141-2e10ac17a123 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -113,7 +113,7 @@ After you set up your development environment and choose your scenario, you can **Table 1. How-to articles for developing with social features** -|**Feature area**|**Description**| +|Feature area|Description| |:-----|:-----| | [How to: Learn to read and write to the social feed by using the .NET client object model in SharePoint](how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-net-client-object.md)|Walk through detailed steps for creating an application that reads and writes to the social feed by using the .NET client object model.| | [How to: Learn to read and write to the social feed by using the REST service in SharePoint](how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-rest-service-in-s.md)|Walk through detailed steps for creating an application that reads and writes to the social feed by using the REST service.| @@ -141,7 +141,7 @@ Although apps and solutions access SharePoint differently, after you do access S **Table 2. APIs for programming with social features** -|**API name**|**Source and path**| +|API name|Source and path| |:-----|:-----| | [.NET client object model](https://msdn.microsoft.com/library/9cc3f70c-78ac-4d2d-b46e-77522ee5d937%28Office.15%29.aspx)|Microsoft.SharePoint.Client.UserProfiles.dll
in %ProgramFiles%\\Common Files\\Microsoft Shared\\web server extensions\\15\\ISAPI| |Silverlight client object model|Microsoft.SharePoint.Client.UserProfiles.Silverlight.dll
in %ProgramFiles%\\Common Files\\Microsoft Shared\\web server extensions\\15\\TEMPLATE\\LAYOUTS\\ClientBin| @@ -172,7 +172,7 @@ App permission requests are scoped to the SharePoint deployment landscape. Table **Table 3. App permission scopes and available rights for social features in SharePoint** -|**Scope name**|**Description**|**Available rights**| +|Scope name|Description|Available rights| |:-----|:-----|:-----| |User Profiles
`http://sharepoint/social/tenant`|The permission request scope used to access all user profiles. Only the profile picture can be changed; all other user profile properties are read-only for SharePoint Add-ins. Must be installed by a tenant administrator.|Read, Write, Manage, FullControl| |Core
`http://sharepoint/social/core`|The permission request scope used to access the user's followed content and shared metadata that is used by microblogging features. This scope applies only to personal sites that support following content. If the app installs on any other type of site, use the Tenant scope.|Read, Write, Manage, FullControl| diff --git a/docs/general-development/get-started-using-the-client-object-model-with-external-data-in-sharepoint.md b/docs/general-development/get-started-using-the-client-object-model-with-external-data-in-sharepoint.md index e337c9d51..b6fe3360a 100644 --- a/docs/general-development/get-started-using-the-client-object-model-with-external-data-in-sharepoint.md +++ b/docs/general-development/get-started-using-the-client-object-model-with-external-data-in-sharepoint.md @@ -1,15 +1,14 @@ --- title: Get started using the client object model with external data in SharePoint +description: Learn how to use the SharePoint client object model to work with Business Connectivity Services (BCS) in SharePoint. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 8ed91929-fdb6-4fde-ba2a-7942870575f3 -localization_priority: Normal +ms.localizationpriority: medium --- - - - # Get started using the client object model with external data in SharePoint + Learn how to use the SharePoint client object model to work with Business Connectivity Services (BCS) in SharePoint. + ## What is the SharePoint client object model? The client object model for SharePoint is a set of client-based libraries that represent the server object model. They are packaged in three different DLLs to accommodate a variety of development types. The client object model includes most of the major functions of the server API. This allows access to the same types of functionality from browser scripting and also .NET web applications and Silverlight applications.
To enhance and expand the capabilities for working with external data, Business Connectivity Services (BCS) has expanded the client object model to include additional functionality.
@@ -100,7 +99,7 @@ This example shows how to get context from SharePoint, and then retrieve a speci -```cs +```csharp ClientContext ctx = new ClientContext("http://sharepointservername"); Web web = ctx.Web; @@ -108,7 +107,6 @@ ctx.Load(web); Entity entity = ctx.Web.GetEntity("http://sharepointservername", "EntityName"); ctx.Load(entity); ctx.ExecuteQuery(); - ``` @@ -119,12 +117,29 @@ This example shows how to write a generic invoker so that you can create an enti -```cs +```csharp +LobSystem lobSystem = entity.GetLobSystem(); +ctx.Load(lobSystem); -ObjectCollection myObj; -entity.Execute("MethodInstanceName", lsi, myObj); -ctx.Load(myObj); -ctx.ExecuteQuery(); +LobSystemInstanceCollection lobInstances = lobSystem.GetLobSystemInstances(); +ctx.Load(lobInstances); +ctx.ExecuteQuery(); + +LobSystemInstance lsi; +foreach(LobSystemInstance lobInstance in lobInstances) +{ + if (lobInstance.Name.CompareTo("MyLOBSystemInstance") == 0) + { + lsi = lobInstance; + } +} + +if (null != lsi) +{ + entity.Execute("MethodInstanceName", lsi, Array.Empty()); + ctx.Load(myObj); + ctx.ExecuteQuery(); +} ``` @@ -136,27 +151,18 @@ The following example shows how to retrieve a filtered, paged dataset. In this c -```cs +```csharp // Find filters for given Method Name. FilterCollection fCollection = entity.GetFilters("methodName"); ctx.Load(fCollection); ctx.ExecuteQuery(); -FilterCollection modifiedFCollection = new FilterCollection(); -foreach( Filter filter in fCollection) -{ - if( filter.FilterField.equals("X.Y.Z.Country")) - { - filter.FilterValue = "India"; - modifiedFCollection.Add(Filter); - } - if(filter.FilterType == FilterType.Limit) - { - filter.FilterValue = 50; - modifiedFCollection.Add(Filter); - } -} -EntityInstanceCollection eCollection = entity.FindFiltered(modifiedFCollection, + +fCollection.SetFilterValue("X.Y.Z.Country", 0, "India") +// Assuming that the "RowLimit" filter has the Limit filter type +fCollection.SetFilterValue("RowLimit", 0, 50) + +EntityInstanceCollection eCollection = entity.FindFiltered(fCollection, "nameOfFinder", lsi); ctx.ExecuteQuery(); @@ -170,22 +176,16 @@ The following example demonstrates how to return a filtered result set. In this -```cs +```csharp // Find filters for given Method Name. FilterCollection fCollection = entity.GetFilters("methodName"); ctx.Load(fCollection); ctx.ExecuteQuery(); -FilterCollection modifiedFCollection = new FilterCollection(); -foreach( Filter filter in fCollection) -{ - if( filter.FilterField.equals("X.Y.Z.Country")) - { - filter.FilterValue = "India"; - modifiedFCollection.Add(Filter); - } -} -EntityInstanceCollection eCollection = entity.FindFiltered(modifiedFCollection, + +fCollection.SetFilterValue("X.Y.Z.Country", 0, "India") + +EntityInstanceCollection eCollection = entity.FindFiltered(fCollection, "nameOfFinder", lsi); ctx.ExecuteQuery(); diff --git a/docs/general-development/get-started-with-business-connectivity-services-in-sharepoint.md b/docs/general-development/get-started-with-business-connectivity-services-in-sharepoint.md index e1c4247ac..724782b63 100644 --- a/docs/general-development/get-started-with-business-connectivity-services-in-sharepoint.md +++ b/docs/general-development/get-started-with-business-connectivity-services-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Get started with Business Connectivity Services in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to get started with Business Connectivity Services in SharePoint and provides lists of core concepts and basic tasks. +ms.date: 06/09/2022 ms.assetid: c6bf3db0-db79-4b13-9834-891d24b2c9e5 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/get-started-with-workflows-in-sharepoint.md b/docs/general-development/get-started-with-workflows-in-sharepoint.md index 5a2accb3b..9a55786ce 100644 --- a/docs/general-development/get-started-with-workflows-in-sharepoint.md +++ b/docs/general-development/get-started-with-workflows-in-sharepoint.md @@ -1,12 +1,12 @@ --- title: Get started with workflows in SharePoint -ms.date: 09/25/2017 +description: Describes how to get started with workflows in SharePoint and provides steps for creating a workflow using Visual Studio. +ms.date: 06/09/2022 keywords: vs.sharepointtools.workflow4.workflowlist,VS.SharePointTools.Workflow4.WorkflowName f1_keywords: - vs.sharepointtools.workflow4.workflowlist,VS.SharePointTools.Workflow4.WorkflowName -ms.prod: sharepoint ms.assetid: a2643cd7-474d-4e4c-85bb-00f0b6685a1d -localization_priority: Priority +ms.localizationpriority: high --- @@ -15,9 +15,10 @@ Learn about the newly engineered Workflow Manager Client 1.0, which provides the > **Important:** > For instructions on setting up and configuring SharePoint and Microsoft Azure, see [Set up and configure SharePoint Workflow Manager](set-up-and-configure-sharepoint-workflow-manager.md). +> [!NOTE] +> SharePoint 2013 workflow has been deprecated since April 2023 and will be turned off for new tenants as of April 2, 2024. It will be removed from existing tenants and will be fully retired as of April 2, 2026. If you’re using SharePoint 2013 workflow, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2013 workflow retirement in Microsoft 365](https://support.microsoft.com/office/4613d9cf-69aa-40f7-b6bf-6e7831c9691e). +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). - - ## Overview of workflows in SharePoint @@ -101,7 +102,7 @@ There are two primary authoring environments for Workflow Manager Client 1.0: Sh -However, the primary authoring environments are Visual Studio 2012 and SharePoint Designer 2013. To help you decide which of these best suits your needs, see the decision matrix in [Comparing SharePoint Designer with Visual Studio](develop-sharepoint-workflows-using-visual-studio.md#bkm_Comparing). +However, the primary authoring environments are Visual Studio 2012 and SharePoint Designer 2013. To help you decide which of these best suits your needs, see the decision matrix in [Comparing SharePoint Designer with Visual Studio](develop-sharepoint-workflows-using-visual-studio.md#comparing-sharepoint-designer-with-visual-studio). diff --git a/docs/general-development/getting-familiar-with-visual-designer-for-workflow-in-sharepoint-designer.md b/docs/general-development/getting-familiar-with-visual-designer-for-workflow-in-sharepoint-designer.md index a118df638..eb5bd2f49 100644 --- a/docs/general-development/getting-familiar-with-visual-designer-for-workflow-in-sharepoint-designer.md +++ b/docs/general-development/getting-familiar-with-visual-designer-for-workflow-in-sharepoint-designer.md @@ -1,14 +1,18 @@ --- title: Getting familiar with Visual Designer for workflow in SharePoint Designer 2013 -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the basic features of the Visual Designer in SharePoint Designer 2013 and provides guidance for using the Visual Designer in SharePoint. +ms.date: 06/09/2022 ms.assetid: ff9b0314-eea1-47e4-87c7-53ed4de98c30 -localization_priority: Normal +ms.localizationpriority: medium --- # Getting familiar with Visual Designer for workflow in SharePoint Designer 2013 Learn the basic features of the Visual Designer in SharePoint Designer 2013. + +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). + ## Overview of the Visual Designer in SharePoint Designer 2013 diff --git a/docs/general-development/getting-ranges-using-atom-feed-and-html-fragment.md b/docs/general-development/getting-ranges-using-atom-feed-and-html-fragment.md index e1e168419..138b17b3f 100644 --- a/docs/general-development/getting-ranges-using-atom-feed-and-html-fragment.md +++ b/docs/general-development/getting-ranges-using-atom-feed-and-html-fragment.md @@ -1,9 +1,9 @@ --- title: Getting Ranges Using Atom Feed and HTML Fragment -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the Atom feed method and the HTML fragment method to access ranges by using the REST API in Excel Services. +ms.date: 06/09/2022 ms.assetid: 45d4ef08-02d6-48dd-b0ef-a748db1a0c6a -localization_priority: Normal +ms.localizationpriority: medium --- @@ -48,7 +48,7 @@ Therefore, for a workbook with the file name **sampleWorkbook.xlsx** that is sav http:///_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model ``` -Using the discovery mechanism described in [Discovery in Excel Services REST API](discovery-in-excel-services-rest-api.md), if you click on the **Ranges** Atom feed on the model page on the server, ( `http://` __ `/_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model`), it displays a page that shows all the named ranges in the workbook. The sampleWorkbook.xlsx contains one named range, **SampleNamedRange**, as shown in the following screen shot: +Using the discovery mechanism described in [Discovery in Excel Services REST API](discovery-in-excel-services-rest-api.md), if you click on the **Ranges** Atom feed on the model page on the server, ( `http://` _\_ `/_vti_bin/ExcelRest.aspx/Docs/Documents/sampleWorkbook.xlsx/model`), it displays a page that shows all the named ranges in the workbook. The sampleWorkbook.xlsx contains one named range, **SampleNamedRange**, as shown in the following screen shot: @@ -184,19 +184,19 @@ The feed item contains XML that represents the data inside the range. Following -- **** The range element. Represents the container of the returned range. +- **\** The range element. Represents the container of the returned range. -- **** The row element. Represents each row in the range. +- **\** The row element. Represents each row in the range. -- **** The cell element. Represents each cell in a row. +- **\** The cell element. Represents each cell in a row. -- **** The formatted value element. Represents the value as it is formatted by Excel. If the value is of type string in the workbook, the formatted value element is the only element under ****. +- **\** The formatted value element. Represents the value as it is formatted by Excel. If the value is of type string in the workbook, the formatted value element is the only element under **\**. -- **** The value element. Represents a number value. If the value in the cell is a number instead of a string, the value element contains that information. +- **\** The value element. Represents a number value. If the value in the cell is a number instead of a string, the value element contains that information. Using XML gives you an easier way to get data out of an Excel range so that you can use it in your application. diff --git a/docs/general-development/getting-started-with-excel-services.md b/docs/general-development/getting-started-with-excel-services.md index 6ae8ae47a..cc622475f 100644 --- a/docs/general-development/getting-started-with-excel-services.md +++ b/docs/general-development/getting-started-with-excel-services.md @@ -1,9 +1,9 @@ --- title: Getting Started with Excel Services -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Provides an overview of Excel Services and its architecture, and provides links to Excel Service articles and reference topics. +ms.date: 06/09/2022 ms.assetid: 392e4734-5ca0-4647-8f6d-e671daa45a4d -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/how-to-access-an-external-data-source-from-a-udf.md b/docs/general-development/how-to-access-an-external-data-source-from-a-udf.md index a6d3067b0..93dfbf263 100644 --- a/docs/general-development/how-to-access-an-external-data-source-from-a-udf.md +++ b/docs/general-development/how-to-access-an-external-data-source-from-a-udf.md @@ -1,12 +1,12 @@ --- title: Access an external data source from a UDF +description: This example shows how to access an external database from a user-defined function (UDF). ms.date: 09/25/2017 keywords: how to,howdoi,howto,UDF f1_keywords: - how to,howdoi,howto,UDF -ms.prod: sharepoint ms.assetid: 7a1876da-aeb5-4017-8eb6-3fed47912f70 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -21,7 +21,7 @@ This example shows how to access an external database from a user-defined functi ## Example -```cs +```csharp using System; using System.Collections.Generic; @@ -185,7 +185,7 @@ End Namespace - [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.md) + [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.yml) diff --git a/docs/general-development/how-to-access-external-data-with-rest-in-sharepoint.md b/docs/general-development/how-to-access-external-data-with-rest-in-sharepoint.md index dda4d9fbd..5d9087c9d 100644 --- a/docs/general-development/how-to-access-external-data-with-rest-in-sharepoint.md +++ b/docs/general-development/how-to-access-external-data-with-rest-in-sharepoint.md @@ -1,193 +1,130 @@ --- title: Access external data by using REST in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to access external data from SharePoint by using REST URLs for BCS and provides an example that sets up an external list. +ms.date: 05/18/2023 ms.assetid: 0663cc8c-a736-434d-9858-6ce12ce7f748 -localization_priority: Priority +ms.localizationpriority: high --- - - # Access external data by using REST in SharePoint Learn how to access external data from SharePoint by using Representational State Transfer (REST) URLs for Business Connectivity Services (BCS). This article shows how to set up an external list that retrieves data from an Open Data protocol (OData) source. - - - - ## Prerequisites for accessing external data using REST - To access external data from SharePoint by using REST, you need the following: - - - - SharePoint - - - Visual Studio 2012 - - - Office Developer Tools for Visual Studio 2012 - - - A functioning SharePoint Add-ins development environment: Follow the instructions in [Set up a general development environment for SharePoint](set-up-a-general-development-environment-for-sharepoint.md). - - - Access to the public OData.org producers - - ### Core concepts to know when accessing external data with REST The SharePoint REST service provides a way to access external data using a specially constructed URL. To understand how it works and how to use it, see the following articles. - - - **Table 1. Core concepts for REST in SharePoint** - -|**Article title**|**Description**| -|:-----|:-----| -| [Use OData query operations in SharePoint REST requests](https://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72%28Office.15%29.aspx)
|Learn how to use the SharePoint REST service, which provides a REST programming interface comparable to the existing client object model.
| -| [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx)
|Get the basics of using the SharePoint REST service to access and update SharePoint data, using the REST and OData web protocol standards.
| -| [Complete basic operations using SharePoint REST endpoints](https://docs.microsoft.com/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints)
|Learn how to navigate the SharePoint data structure as it is represented in the REST service, perform common CRUD (create, read, update, and delete) operations on SharePoint items via the REST service, synchronize SharePoint items across applications, and control item concurrency.
| - +| **Article title** | **Description** | +| :---------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Use OData query operations in SharePoint REST requests](https://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72%28Office.15%29.aspx) | Learn how to use the SharePoint REST service, which provides a REST programming interface comparable to the existing client object model. | +| [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx) | Get the basics of using the SharePoint REST service to access and update SharePoint data, using the REST and OData web protocol standards. | +| [Complete basic operations using SharePoint REST endpoints](/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints) | Learn how to navigate the SharePoint data structure as it is represented in the REST service, perform common CRUD (create, read, update, and delete) operations on SharePoint items via the REST service, synchronize SharePoint items across applications, and control item concurrency. | ## Create an SharePoint Add-in to access external data using REST - The following procedures guide you through setting up an SharePoint Add-in and configuring a webpage to make requests using REST functions to retrieve data from an external data source. - - - ### To create an SharePoint Add-in - 1. Open Visual Studio 2012 or later. - - -2. Create an **App for SharePoint** project. - - -3. Specify the app settings, including app name, the site URL for debugging the app, and how you want to host the app (Autohosted, Provider-hosted, SharePoint-hosted). For more information about hosting options, see [Choose patterns for developing and hosting your SharePoint Add-in](https://msdn.microsoft.com/library/05ce5435-0a03-4ddc-976b-c33b08d03457%28Office.15%29.aspx). - - -4. Choose **Finish** to create the app. - - +1. Create an **App for SharePoint** project. +1. Specify the app settings, including app name, the site URL for debugging the app, and how you want to host the app (Autohosted, Provider-hosted, SharePoint-hosted). For more information about hosting options, see [Choose patterns for developing and hosting your SharePoint Add-in](https://msdn.microsoft.com/library/05ce5435-0a03-4ddc-976b-c33b08d03457%28Office.15%29.aspx). +1. Choose **Finish** to create the app. ### To generate the external content type - 1. In **Solution Explorer**, open the shortcut menu for the project, and choose **Add**, **Content Types for External Data Source**. - - -2. In the **Specify OData Source** page, enter the URL of the OData service you want to connect to. In this case, use the Northwind OData source published at [http://www.odata.org/ecosystem](http://www.odata.org/ecosystem). Set the URL for the OData service to `http://services.odata.org/Northwind/Northwind.svc/`, and provide a name for the data source. - +1. In the **Specify OData Source** page, enter the URL of the OData service you want to connect to. In this case, use the Northwind OData source published at [https://www.odata.org/ecosystem](https://www.odata.org/ecosystem). Set the URL for the OData service to `http://services.odata.org/Northwind/Northwind.svc/`, and provide a name for the data source. + Choose **Next**. - - -3. This displays a list of data entities that are being exposed by the OData Service. Select the **Customers** entity. Ensure that the **Create list instances for the selected data entities (except Service Operations)** check box is selected. - - -4. Choose **Finish**. - - + +1. This displays a list of data entities that are being exposed by the OData Service. Select the **Customers** entity. Ensure that the **Create list instances for the selected data entities (except Service Operations)** check box is selected. +1. Choose **Finish**. ## Code example: Add scripts and HTML to the Home.aspx page - -At this point, you have an external content type and an external list that will display the data from the Northwind OData source. - - - +At this point, you have an external content type and an external list that will display the data from the Northwind OData source. + The next objective is to modify the default.aspx page that was created when you created your app. You will add a container to hold the results of the query that is executed with the page loads. By executing the scripts on the page load event, you ensure that the script is executed every time the page is browsed, and the resulting REST calls are made to the Northwind OData source to add records to the page. - - - ### To add the container to the Default.aspx page - 1. In **Solution Explorer**, open the Default.aspx page in the **Pages** module. - - -2. Add the following **div** element to the page. - -```HTML - -
-``` +1. Add the following **div** element to the page. + + ```html +
+ ``` + +1. Save the page. -3. Save the page. - - Finally, you add code to the App.js file that executes when the page loads. - - - ### To modify the App.js file to make REST calls +1. Open the **App.js** file in the Scripts module of your SharePoint project. +1. Paste the following code at the end of the file. -1. Open the App.js file in the Scripts module of your SharePoint project. - - -2. Paste the following code at the end of the file. - -``` - $(document).ready(function () { +```javascript +$(document).ready(function () { - // Namespace - window.AppLevelECT = window.AppLevelECT || {}; + // Namespace + window.AppLevelECT = window.AppLevelECT || {}; - // Constructor - AppLevelECT.Grid = function (hostElement, surlWeb) { - this.hostElement = hostElement; - if (surlWeb.length > 0 && surlWeb.substring(surlWeb.length - 1, surlWeb.length) != "/") - surlWeb += "/"; - this.surlWeb = surlWeb; - } + // Constructor + AppLevelECT.Grid = function (hostElement, surlWeb) { + this.hostElement = hostElement; + if (surlWeb.length > 0 && surlWeb.substring(surlWeb.length - 1, surlWeb.length) != "/") + surlWeb += "/"; + this.surlWeb = surlWeb; + } - // Prototype - AppLevelECT.Grid.prototype = { + // Prototype + AppLevelECT.Grid.prototype = { - init: function () { + init: function () { - $.ajax({ - url: this.surlWeb + "_api/lists/getbytitle('Customer')/items?$select=BdcIdentity,CustomerID,ContactName", - headers: { - "accept": "application/json", - "X-RequestDigest": $("#__REQUESTDIGEST").val() - }, - success: this.showItems - }); - }, + $.ajax({ + url: this.surlWeb + "_api/lists/getbytitle('Customer')/items?$select=BdcIdentity,CustomerID,ContactName", + headers: { + "accept": "application/json", + "X-RequestDigest": $("#__REQUESTDIGEST").val() + }, + success: this.showItems + }); + }, - showItems: function (data) { - var items = []; + showItems: function (data) { + var items = []; - items.push(""); - items.push(''); + items.push("
Customer IDCustomer Name
"); + items.push(''); - $.each(data.d.results, function (key, val) { - items.push(''); - }); + $.each(data.d.results, function (key, val) { + items.push(''); + }); - items.push("
Customer IDCustomer Name
' + - val.CustomerID + '' + - val.ContactName + '
' + + val.CustomerID + '' + + val.ContactName + '
"); + items.push(""); - $("#displayDiv").html(items.join('')); - } - } + $("#displayDiv").html(items.join('')); + } + } - ExecuteOrDelayUntilScriptLoaded(getCustomers, "sp.js"); + ExecuteOrDelayUntilScriptLoaded(getCustomers, "sp.js"); }); function getCustomers() { @@ -197,28 +134,11 @@ function getCustomers() { ``` Press F5 to deploy the app to SharePoint. Browse to the Default.aspx page in the app, and a list of customers appears on the page. - - - ## See also - - - -- [Business Connectivity Services in SharePoint](business-connectivity-services-in-sharepoint.md) - - -- [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx) - - -- [Complete basic operations using SharePoint REST endpoints](https://docs.microsoft.com/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints) - - -- [Add-in-scoped external content types in SharePoint](add-in-scoped-external-content-types-in-sharepoint.md) - - -- [What's new in Business Connectivity Services in SharePoint](what-s-new-in-business-connectivity-services-in-sharepoint.md) - - - +- [Business Connectivity Services in SharePoint](business-connectivity-services-in-sharepoint.md) +- [Get to know the SharePoint REST service](https://msdn.microsoft.com/library/2de035a0-ac75-43bd-9665-5c5a59c4c590%28Office.15%29.aspx) +- [Complete basic operations using SharePoint REST endpoints](/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints) +- [Add-in-scoped external content types in SharePoint](add-in-scoped-external-content-types-in-sharepoint.md) +- [What's new in Business Connectivity Services in SharePoint](what-s-new-in-business-connectivity-services-in-sharepoint.md) diff --git a/docs/general-development/how-to-add-a-device-channel-panel-snippet-in-sharepoint.md b/docs/general-development/how-to-add-a-device-channel-panel-snippet-in-sharepoint.md index 164b254e0..6d119f6d0 100644 --- a/docs/general-development/how-to-add-a-device-channel-panel-snippet-in-sharepoint.md +++ b/docs/general-development/how-to-add-a-device-channel-panel-snippet-in-sharepoint.md @@ -1,156 +1,92 @@ --- title: Add a Device Channel Panel snippet in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to add a Device Channel Panel that can be added to a master page or page layout to control how content is rendered in created channels. +ms.date: 05/18/2023 ms.assetid: 612780a8-6267-49f6-a32d-33600bb5f6b4 -localization_priority: Normal +ms.localizationpriority: medium --- - # Add a Device Channel Panel snippet in SharePoint A Device Channel Panel is a snippet that you can add to a master page or page layout to control what content is rendered for each channel that you create. The primary purpose of a Device Channel Panel is to selectively display different page fields on different channels from a single page layout. ## Introduction to the Device Channel Panel snippet - A Device Channel Panel is a control that you can add to a master page or page layout to control what content is rendered in each channel that you create. A Device Channel Panel is a container that specifies one or more channels; if one or more of those channels are active when the page is rendered, all of the contents of the Device Channel Panel are also rendered. A Device Channel Panel can include almost any type of content, including a link to a CSS file or a .js file. It is an easy way to include specific content for specific channels. - - - + Perhaps the most common scenario for using Device Channel Panels is to selectively include parts of a page layout for specific channels. For example, you may have a page layout with separate text fields for a long greeting and a short greeting. By placing the page fields inside Device Channel Panels, you can display the short greeting only to phones and the long greeting only to the desktop. The content of a Device Channel Panel is not displayed on non-included channels—in fact, the content is not rendered at all, which prevents bytes from going across the wire. For this reason, using Device Channel Panels is a better way to display content on specific channels than using a CSS class with `Display:None` because Device Channel Panels help to reduce the page weight for a specific channel. - - - + You can also use Device Channel Panels on master pages. For example, if you have a master page that can accommodate two different devices (or two different browsers) with only minimal changes, you can use Device Channel Panels to hold the content on the master page that is specific to either of those devices. - - - + There are two limitations to using a Device Channel Panel: - - - - **Display templates** Because display templates are rendered on the client side and Device Channel Panels run on the server side, you cannot use a Device Channel Panel within a display template. Instead, you should use two different Content Search web parts within Device Channel Panels on your page layout, or use the JavaScript variable to trigger the behavior you want within the display template itself. - - - **Web part zones** You cannot insert a web part zone inside a Device Channel Panel. If you want to allow authors to add web parts to a page, and if you are not concerned about the page weight for mobile devices, you can add a Rich Text Editor page field to a Device Channel Panel, and then instruct authors to add web parts there. You can add web parts directly to a Device Channel Panel (without a web part zone). - - ## Inserting a Device Channel Panel snippet - Like all snippets, you add a Device Channel Panel snippet from the Snippet Gallery. To navigate to the Snippet Gallery, you must first select a master page or page layout to edit. - - - - ### To insert a Device Channel Panel snippet - 1. Browse to your publishing site. - - -2. In the upper-right corner of the page, choose the Settings gear, and then choose **Design Manager**. - - -3. In Design Manager, in the left navigation pane, choose **Edit Master Pages** or **Edit Page Layouts**, depending on what type of file you're editing. - - -4. Select the name of the master page or page layout that you want to add the snippet to. - - -5. To open the Snippet Gallery, choose **Snippets** in the upper-right corner of the server-side preview. - - -6. On the ribbon, on the **Design** tab, choose **Device Channel Panel**. - - -7. On the right side of the Snippet Gallery, under **About this Component**, click or select section headers to expand or collapse groups of properties, and then configure any custom settings that you want. - +1. In the upper-right corner of the page, choose the Settings gear, and then choose **Design Manager**. +1. In Design Manager, in the left navigation pane, choose **Edit Master Pages** or **Edit Page Layouts**, depending on what type of file you're editing. +1. Select the name of the master page or page layout that you want to add the snippet to. +1. To open the Snippet Gallery, choose **Snippets** in the upper-right corner of the server-side preview. +1. On the ribbon, on the **Design** tab, choose **Device Channel Panel**. +1. On the right side of the Snippet Gallery, under **About this Component**, click or select section headers to expand or collapse groups of properties, and then configure any custom settings that you want. + The section named **Important** contains the properties that are key to how this particular snippet works. For a Device Channel Panel, the **IncludedChannels** property is the most important. For this property, enter the alias of each Device Channel that you want to display the content contained in this Device Channel Panel. If you enter more than one alias, separate each with a comma. - + > [!NOTE] > If you edit the alias of a channel in the Device Channels list, you must manually find and update that alias wherever it appears in your design files, including updating the **IncludedChannels** property for every Device Channel Panel that uses that alias. -8. After you configure any other properties, choose **Update**. This updates the HTML snippet on the left side of the page, so that the markup reflects your custom settings. You can always choose **Reset** to return all properties to their default settings. - - -9. On the left side of the Snippet Gallery, under **HTML Snippet**, choose **Copy to Clipboard**. - - -10. In your HTML editor, open the mapped network drive on your computer, and then open the HTML file for the master page or page layout that you're adding the snippet to. - +1. After you configure any other properties, choose **Update**. This updates the HTML snippet on the left side of the page, so that the markup reflects your custom settings. You can always choose **Reset** to return all properties to their default settings. +1. On the left side of the Snippet Gallery, under **HTML Snippet**, choose **Copy to Clipboard**. +1. In your HTML editor, open the mapped network drive on your computer, and then open the HTML file for the master page or page layout that you're adding the snippet to. + For more information, see [How to: Map a network drive to the SharePoint Master Page Gallery](how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md). - - -11. In the HTML file, paste the snippet where you want the markup to appear. - + +1. In the HTML file, paste the snippet where you want the markup to appear. + If you are adding the snippet to a page layout, make sure to paste the snippet inside **PlaceHolderMain**. - - -12. Replace the **
** where `class="DefaultContentBlock"` with your own specific content. - - Typically, if you're adding a Device Channel Panel to a page layout, you replace the **
** by copying page fields inside the panel. - - -13. Save the page, and then refresh the server-side preview in Design Manager to make sure the Device Channel Panel appears as expected. - + +1. Replace the `
` where `class="DefaultContentBlock"` with your own specific content. + + Typically, if you're adding a Device Channel Panel to a page layout, you replace the `
` by copying page fields inside the panel. + +1. Save the page, and then refresh the server-side preview in Design Manager to make sure the Device Channel Panel appears as expected. + To preview the panel on different channels, you can add query string parameters to the URL. For example, you can append the query string variable `"DeviceChannel=YourChannelAlias"` to the URL of any page in the server-side preview. - - ## Understanding the snippet markup - -The two most important parts of a Device Channel Panel snippet are the **IncludedChannels** property and the **
** where `class="DefaultContentBlock"`. By default, the **IncludedChannels** property is empty. In the **Important** section of the property grid, you should enter the aliases, separated by commas, of the device channels that you want to display the content in this panel. - +The two most important parts of a Device Channel Panel snippet are the **IncludedChannels** property and the `
` where `class="DefaultContentBlock"`. By default, the **IncludedChannels** property is empty. In the **Important** section of the property grid, you should enter the aliases, separated by commas, of the device channels that you want to display the content in this panel. + > [!NOTE] > If you change an alias in the Device Channels list, you must also change that alias wherever it appears in your markup, including in the **IncludedChannels** property for every Device Channel Panel that uses that alias. - - - - -The **
** where `class="DefaultContentBlock"` should be replaced with whatever specific content you want to display for the included channels. A Device Channel Panel can include almost any type of content, including a link to a CSS file or a .js file. The most common scenario for using Device Channel Panels is to include specific page fields from a page layout for specific channels. In this case, you copy the page field markup where the **
** is positioned inside the Device Channel Panel. - - - +The `
` where `class="DefaultContentBlock"` should be replaced with whatever specific content you want to display for the included channels. A Device Channel Panel can include almost any type of content, including a link to a CSS file or a .js file. The most common scenario for using Device Channel Panels is to include specific page fields from a page layout for specific channels. In this case, you copy the page field markup where the `
` is positioned inside the Device Channel Panel. ```HTML -
- You should replace this div with content that renders based on your Device Channel Panel Properties. + You should replace this div with content that renders based on your Device Channel Panel Properties.
- ``` - ## See also - - - -- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) - - -- [SharePoint Design Manager device channels](sharepoint-design-manager-device-channels.md) - - -- [Build sites for SharePoint](build-sites-for-sharepoint.md) - - -- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) - - +- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) +- [SharePoint Design Manager device channels](sharepoint-design-manager-device-channels.md) +- [Build sites for SharePoint](build-sites-for-sharepoint.md) +- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) diff --git a/docs/general-development/how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md b/docs/general-development/how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md index 051ff94b7..29d293584 100644 --- a/docs/general-development/how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md +++ b/docs/general-development/how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md @@ -1,216 +1,160 @@ --- title: Add a Geolocation column to a list programmatically in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to programmatically add a Geolocation column to a list in SharePoint. Integrate location information and maps in SharePoint lists and location-based websites by using the new Geolocation field creating your own Geolocation-based field type. +ms.date: 01/06/2023 ms.assetid: f31a3594-c328-4731-b8eb-5da6b85103ad -localization_priority: Priority +ms.localizationpriority: high --- - - # Add a Geolocation column to a list programmatically in SharePoint + Learn how to programmatically add a Geolocation column to a list in SharePoint. Integrate location information and maps in SharePoint lists and location-based websites by using the new Geolocation field creating your own Geolocation-based field type. -SharePoint introduces a new field type named Geolocation that enables you to annotate SharePoint lists with location information. In columns of type Geolocation, you can enter location information as a pair of latitude and longitude coordinates in decimal degrees or retrieve the coordinates of the user's current location from the browser if it implements the W3C Geolocation API. For more information about the Geolocation column, see [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md). The Geolocation column is not available by default in SharePoint lists. To add the column to a SharePoint list, you have to write code. In this article, learn how to add the Geolocation field to a list programmatically by using the SharePoint client object model. - - - -An MSI package named SQLSysClrTypes.msi must be installed on every SharePoint front-end web server to view the geolocation field value or data in a list. This package installs components that implement the new geometry, geography, and hierarchy ID types in SQL Server 2008. By default, this file is installed for SharePoint Online. However, it is not for an on-premises deployment of SharePoint. You must be a member of the Farm Administrators group to perform this operation. To download SQLSysClrTypes.msi, see [Microsoft SQL Server 2008 R2 SP1 Feature Pack](https://www.microsoft.com/download/details.aspx?id=26728) for SQL Server 2008, or [Microsoft SQL Server 2012 Feature Pack](https://www.microsoft.com/download/details.aspx?id=29065)for SQL Server 2012 in the Microsoft Download Center. -## Prerequisites for adding a Geolocation column - +SharePoint introduces a new field type named Geolocation that enables you to annotate SharePoint lists with location information. In columns of type Geolocation, you can enter location information as a pair of latitude and longitude coordinates in decimal degrees or retrieve the coordinates of the user's current location from the browser if it implements the W3C Geolocation API. For more information about the Geolocation column, see [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md). The Geolocation column isn't available by default in SharePoint lists. To add the column to a SharePoint list, you have to write code. In this article, learn how to add the Geolocation field to a list programmatically by using the SharePoint client object model. +An MSI package named SQLSysClrTypes.msi must be installed on every SharePoint front-end web server to view the geolocation field value or data in a list. This package installs components that implement the new geometry, geography, and hierarchy ID types in SQL Server 2008. By default, this file is installed for SharePoint Online. However, it isn't for an on-premises deployment of SharePoint. You must be a member of the Farm Administrators group to perform this operation. To download SQLSysClrTypes.msi, see [Microsoft SQL Server 2008 R2 SP1 Feature Pack](https://www.microsoft.com/download/details.aspx?id=30437) for SQL Server 2008, or [Microsoft SQL Server 2012 Feature Pack](https://www.microsoft.com/download/details.aspx?id=29065)for SQL Server 2012 in the Microsoft Download Center. - - - +## Prerequisites for adding a Geolocation column - Access to a SharePoint list, with sufficient privileges to add a column. - - -- A valid Bing Maps key set at the farm or web level, which can be obtained from the [Bing Maps Account Center](https://www.bingmapsportal.com/). - - > **Important:** - > Please note that you are responsible for compliance with terms and conditions applicable to your use of the Bing Maps key, and any necessary disclosures to users of your application regarding data passed to the Bing Maps service. -- Visual Studio 2010. -- SharePoint Online Management Shell - https://www.microsoft.com/download/details.aspx?id=35588 -- SharePoint PnP PowerShell - https://github.com/SharePoint/PnP-PowerShell/ - - +- A valid Bing Maps key set at the farm or web level, which can be obtained from the [Bing Maps Account Center](https://www.bingmapsportal.com/). + + > [!IMPORTANT] + > Please note that you are responsible for compliance with terms and conditions applicable to your use of the Bing Maps key, and any necessary disclosures to users of your application regarding data passed to the Bing Maps service. + +- Visual Studio 2010 +- SharePoint Online Management Shell: https://www.microsoft.com/download/details.aspx?id=35588 +- SharePoint PnP-PowerShell (legacy): https://github.com/SharePoint/PnP-PowerShell/ +- SharePoint PnP.PowerShell (latest): https://github.com/pnp/powershell + +[!INCLUDE [pnp-powershell](../../includes/snippets/open-source/pnp-powershell.md)] ## Code example: Add a Geolocation column to an existing list programmatically - Follow these steps to add the Geolocation column to a list. This must be done programmatically with CSOM or PowerShell - + ### To add the Geolocation column to a list using PnP PowerShell -1. Open the SharePoint Online Management Shell -2. Connect to the site you wish to add the column to -```cs -Connect-PnPOnline -url "https://TENANT.sharepoint.com/sites/SITEURL" -``` -3. Open the list you wish to add the column to -```cs -$list = Get-PnPList -Identity "LISTNAME" -``` -4. #Add the Geolocation field - Change parameters as necessary -```cs -Add-PnPField -List $list -Type GeoLocation -DisplayName "GeoLocationField" -InternalName "GeoLocationField" -AddToDefaultView -Required -``` - - - -### To add the Geolocation column to a list using the client object model in Visual Studio +1. Open PowerShell +1. Connect to the site you wish to add the column to + + ```powershell + Connect-PnPOnline -url "https://TENANT.sharepoint.com/sites/SITEURL" + ``` + +1. Open the list you wish to add the column to + ```powershell + $list = Get-PnPList -Identity "LISTNAME" + ``` + +1. #Add the Geolocation field - Change parameters as necessary + + ```powershell + Add-PnPField -List $list -Type GeoLocation -DisplayName "GeoLocationField" -InternalName "GeoLocationField" -AddToDefaultView -Required + ``` + +### To add the Geolocation column to a list using the client object model in Visual Studio 1. Start Visual Studio. - - -2. On the menu bar, choose **File, New Project**. The **New Project** dialog box opens. - - -3. In the **New Project** dialog box, choose **C#** in the **Installed Templates** box, and then choose the **Console Application** template. - - -4. Give the project a name, and then choose the **OK** button. - - -5. Visual Studio creates the project. Add a reference to the following assemblies, and choose **OK**. - - Microsoft.SharePoint.Client.dll - - Microsoft.SharePoint.Client.Runtime.dll - - -6. In the default .cs file, add a **using** directive as follows. - - `using Microsoft.SharePoint.Client;` - - -7. Add the following code to the **Main** method in the .cs file. - -```cs - -class Program +1. On the menu bar, choose **File, New Project**. The **New Project** dialog box opens. +1. In the **New Project** dialog box, choose **C#** in the **Installed Templates** box, and then choose the **Console Application** template. +1. Give the project a name, and then choose the **OK** button. +1. Visual Studio creates the project. Add a reference to the following assemblies, and choose **OK**. + + - Microsoft.SharePoint.Client.dll + - Microsoft.SharePoint.Client.Runtime.dll + +1. In the default .cs file, add a **using** directive as follows. + + ```csharp + using Microsoft.SharePoint.Client; + ``` + +1. Add the following code to the **Main** method in the .cs file. + + ```csharp + class Program { - static void Main(string[] args) - { - AddGeolocationField(); - Console.WriteLine("Location field added successfully"); - } - private static void AddGeolocationField() - { - // Replace site URL and List Title with Valid values. - ClientContext context = new ClientContext(""); - List oList = context.Web.Lists.GetByTitle(""); - oList.Fields.AddFieldAsXml("",true, AddFieldOptions.AddToAllContentTypes); - oList.Update(); - context.ExecuteQuery(); - } + static void Main(string[] args) + { + AddGeolocationField(); + Console.WriteLine("Location field added successfully"); + } + private static void AddGeolocationField() + { + // Replace site URL and List Title with Valid values. + ClientContext context = new ClientContext(""); + List oList = context.Web.Lists.GetByTitle(""); + oList.Fields.AddFieldAsXml("",true, AddFieldOptions.AddToAllContentTypes); + oList.Update(); + context.ExecuteQuery(); + } } -``` - -8. Replace \ and \ with valid values. - - -9. Set the target framework in Project Properties as .NET Framework 4.0 or 3.5, and run the example. - - -10. Navigate to the list. You should be able to see a column named **Location** of type Geolocation in the list. You can now enter some values and see it in action. Figure 1 shows the default location and map features that you can expect to see in your list. - - **Figure 1. Summarized view of the default location and map features** + ``` - +1. Replace `` and `` with valid values. +1. Set the target framework in Project Properties as .NET Framework 4.0 or 3.5, and run the example. +1. Navigate to the list. You should be able to see a column named **Location** of type Geolocation in the list. You can now enter some values and see it in action. Figure 1 shows the default location and map features that you can expect to see in your list. + **Figure 1. Summarized view of the default location and map features** ![Default Geolocation and Map feature](../images/SP15Con_HowToAddGeolocationColumnUpdated_Fig1.png) - - - - - ## Add a list item with the Geolocation field value to a SharePoint list programmatically - After the Geolocation field is added to a SharePoint list, the developer can add the list item to the list programmatically. There are two ways to add the list item programmatically: by passing the **FieldGeolocationValue** object to the Geolocation field, and by passing **Raw Value** to the Geolocation field. - - - ### Method A: Pass the FieldGeolocationValue object to the Geolocation field - - The following method adds a list item by passing the Geolocation value as an object. - -```cs - -private void AddListItem() - { // Replace site URL and List Title with Valid values. - ClientContext context = new ClientContext(""); - List oList = context.Web.Lists.GetByTitle(""); - ListItemCreationInformation itemCreationInfo = new ListItemCreationInformation(); - ListItem oListItem = oList.AddItem(itemCreationInfo); + ```csharp + private void AddListItem() { + // Replace site URL and List Title with Valid values. + ClientContext context = new ClientContext(""); + List oList = context.Web.Lists.GetByTitle(""); - oListItem["Title"] = "New Title"; + ListItemCreationInformation itemCreationInfo = new ListItemCreationInformation(); + ListItem oListItem = oList.AddItem(itemCreationInfo); - FieldGeolocationValue oGeolocationValue = new FieldGeolocationValue(); - oGeolocationValue.Latitude = (double)17.4; - oGeolocationValue.Longitude = (double)78.4; - oListItem["location"] = oGeolocationValue; + oListItem["Title"] = "New Title"; - oListItem.Update(); - context.ExecuteQuery(); - } - -``` + FieldGeolocationValue oGeolocationValue = new FieldGeolocationValue(); + oGeolocationValue.Latitude = (double)17.4; + oGeolocationValue.Longitude = (double)78.4; + oListItem["location"] = oGeolocationValue; + oListItem.Update(); + context.ExecuteQuery(); + } + ``` ### Method B: Pass a raw value to the Geolocation field - - The following method adds a list item to the SharePoint list by passing raw values to the Geolocation field. - -```cs - -private void AddListItem() - { // Replace site URL and List Title with Valid values. - ClientContext context = new ClientContext(""); - List oList = context.Web.Lists.GetByTitle(""); - - ListItemCreationInformation itemCreationInfo = new ListItemCreationInformation(); - ListItem oListItem = oList.AddItem(itemCreationInfo); - oListItem["Title"] = "New Title"; - // Data in WKT (World Known Text) format. - oListItem["location"] = "POINT (78.4 17.4)" ; + ```csharp + private void AddListItem() { + // Replace site URL and List Title with Valid values. + ClientContext context = new ClientContext(""); + List oList = context.Web.Lists.GetByTitle(""); - oListItem.Update(); - context.ExecuteQuery(); - } + ListItemCreationInformation itemCreationInfo = new ListItemCreationInformation(); + ListItem oListItem = oList.AddItem(itemCreationInfo); -``` + oListItem["Title"] = "New Title"; + // Data in WKT (World Known Text) format. + oListItem["location"] = "POINT (78.4 17.4)" ; + oListItem.Update(); + context.ExecuteQuery(); + } + ``` ## See also - - - -- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) - - -- [How to: Set the Bing Maps key at the web and farm level in SharePoint](how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md) - - -- [How to: Extend the Geolocation field type using client-side rendering](how-to-extend-the-geolocation-field-type-using-client-side-rendering.md) - - -- [Create a map view for the Geolocation field in SharePoint](create-a-map-view-for-the-geolocation-field-in-sharepoint.md) - - -- [How to: Integrate maps with Windows Phone apps and SharePoint lists](how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md) - - -- [Use the SharePoint location field type in mobile applications](https://technet.microsoft.com/library/fp161355%28v=office.15%29.aspx) - - +- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) +- [How to: Set the Bing Maps key at the web and farm level in SharePoint](how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md) +- [How to: Extend the Geolocation field type using client-side rendering](how-to-extend-the-geolocation-field-type-using-client-side-rendering.md) +- [Create a map view for the Geolocation field in SharePoint](create-a-map-view-for-the-geolocation-field-in-sharepoint.md) +- [How to: Integrate maps with Windows Phone apps and SharePoint lists](how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md) +- [Use the SharePoint location field type in mobile applications](https://technet.microsoft.com/library/fp161355%28v=office.15%29.aspx) diff --git a/docs/general-development/how-to-add-a-security-trim-snippet-in-sharepoint.md b/docs/general-development/how-to-add-a-security-trim-snippet-in-sharepoint.md index 175bc66fe..6fde84dc3 100644 --- a/docs/general-development/how-to-add-a-security-trim-snippet-in-sharepoint.md +++ b/docs/general-development/how-to-add-a-security-trim-snippet-in-sharepoint.md @@ -1,152 +1,87 @@ --- title: Add a Security Trim snippet in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to add a Security Trim snippet in SharePoint to display content only to specific and authenticated users. +ms.date: 05/18/2023 ms.assetid: 4beaab08-760b-408a-b768-906312779379 -localization_priority: Priority +ms.localizationpriority: high --- - # Add a Security Trim snippet in SharePoint You can use a Security Trim snippet to display content only to specific users, based on a specific permission that those users must have and whether the users are authenticated or anonymous. ## Introduction to the Security Trim snippet - You can use a Security Trim snippet to display content only to specific users, based on a specific permission that those users must have, and whether those users are authenticated or anonymous. You can add a Security Trim panel to a master page or page layout. A Security Trim panel is a container that can include other components or snippets, such as web parts, in addition to static content. - - - + For example, you can use a Security Trim panel to display the following content to specific users: - - - - A Content by Search web part that displays which documents an authenticated user is currently working on. - - - A list view of recently modified documents so that authenticated users can see what's new on the site. - - - A Content by Search web part that displays to non-authenticated visitors a list of recommended links based on the current article. Such a list of recommendations might be noise to authenticated content authors working in the site, but it's important for non-authenticated visitors. - - - A sign-in link separate from the ribbon, for non-authenticated users or users who have yet to be authenticated. - + > [!NOTE] - > This sign-in link is inserted automatically into a master page that is created by using Design Manager, but you can delete it if it's not needed. + > This sign-in link is inserted automatically into a master page that is created by using Design Manager, but you can delete it if it's not needed. A Security Trim panel has two important property settings, one for authentication and one for permissions (or authorization). For example, you can use a Security Trim panel to display the following content to specific users: - - - - **AuthenticationRestrictions** With this property, you can restrict the panel to either authenticated or anonymous users, or choose all users (all users is the default setting). - - - **Permissions** With this property, you can select a specific permission that users must have to view the content in the panel. - + > [!NOTE] - > You are selecting an individual permission, not a permission level. (A permission level is a set of granted permissions.) + > You are selecting an individual permission, not a permission level. (A permission level is a set of granted permissions.) + Of course, if you restrict the authentication to only anonymous users, it's typically not necessary to specify a specific permission because anonymous users have usually not been given any SharePoint permissions. It makes sense to use permissions only with all users or with all authenticated users. - - - -The Security Trim panel has three options on the ribbon, listed in the left column of Table 1. Table 1 shows how these settings determine the specific permission that users are required to have, the lowest default permission level that includes that specific permission, and the group that is linked to that permission level by default.) - + +The Security Trim panel has three options on the ribbon, listed in the left column of Table 1. Table 1 shows how these settings determine the specific permission that users are required to have, the lowest default permission level that includes that specific permission, and the group that is linked to that permission level by default. + > [!NOTE] -> These are the default settings, which can be changed for any given scope, such as a site collection, site, list, or item. - - - +> These are the default settings, which can be changed for any given scope, such as a site collection, site, list, or item. For example, if you set a Security Trim panel to **Show to authors**, by default content inside that panel is visible to users in the Members group and the Owners group. - - - **Table 1. Mapping of panel options to default permission levels and groups** - |**Security Trim panel option**|**Permissions property**|**Permission**|**Permission level**|**Group**| |:-----|:-----|:-----|:-----|:-----| -|Show to authors
|**AddAndCustomizePages**
|Add and Customize Pages
|Contribute (or higher)
|Members
| -|Show to Authenticated Users
|**ViewPages**
|View Pages
|Read (or higher)
|Visitors
| -|Show to Administrators
|**FullMask**
|Select All
|Full Control
|Owners
| - +|Show to authors |**AddAndCustomizePages** |Add and Customize Pages |Contribute (or higher) |Members | +|Show to Authenticated Users |**ViewPages** |View Pages |Read (or higher) |Visitors | +|Show to Administrators |**FullMask** |Select All |Full Control |Owners | ### Inserting a Security Trim panel - Like all snippets, you add the Security Trim snippet from the Snippet Gallery. To navigate to the Snippet Gallery, you must first select a master page or page layout to edit. - - - ### To insert a Security Trim panel - 1. Browse to your publishing site. - - -2. In the upper-right corner of the page, choose the Settings gear, and then choose **Design Manager**. - - -3. In Design Manager, in the left navigation pane, choose **Edit Master Pages** or **Edit Page Layouts**, depending on what type of file you're editing. - - -4. Select the name of the master page or page layout that you want to add the snippet to. - - -5. To open the Snippet Gallery, choose **Snippets** in the upper-right corner of the server-side preview. - - -6. On the ribbon, on the **Design** tab, choose **Security Trim**. - +1. In the upper-right corner of the page, choose the Settings gear, and then choose **Design Manager**. +1. In Design Manager, in the left navigation pane, choose **Edit Master Pages** or **Edit Page Layouts**, depending on what type of file you're editing. +1. Select the name of the master page or page layout that you want to add the snippet to. +1. To open the Snippet Gallery, choose **Snippets** in the upper-right corner of the server-side preview. +1. On the ribbon, on the **Design** tab, choose **Security Trim**. + Optionally, in the drop-down list on the **Security Trim** button, you can select the users to whom the panel content will be visible, or you can see more options by configuring the important property values for the panel. - - -7. On the right side of the Snippet Gallery, under **About this Component**, click or select section headers to expand or collapse groups of properties, and then configure any custom settings that you want. - - -8. After you configure any properties, choose **Update**. This updates the HTML snippet on the left side of the page, so that the markup reflects your custom settings. You can always choose **Reset** to return all properties to their default settings. - - -9. On the left side of the Snippet Gallery, under **HTML Snippet**, choose **Copy to Clipboard**. - - -10. In your HTML editor, open the mapped network drive on your computer, and then open the HTML file for the master page or page layout that you're adding the snippet to. - - -11. In the HTML file, paste the snippet where you want the markup to appear. - + +1. On the right side of the Snippet Gallery, under **About this Component**, click or select section headers to expand or collapse groups of properties, and then configure any custom settings that you want. +1. After you configure any properties, choose **Update**. This updates the HTML snippet on the left side of the page, so that the markup reflects your custom settings. You can always choose **Reset** to return all properties to their default settings. +1. On the left side of the Snippet Gallery, under **HTML Snippet**, choose **Copy to Clipboard**. +1. In your HTML editor, open the mapped network drive on your computer, and then open the HTML file for the master page or page layout that you're adding the snippet to. +1. In the HTML file, paste the snippet where you want the markup to appear. + If you are adding the snippet to a page layout, make sure to paste the snippet inside **PlaceHolderMain**. - - -12. Replace the **
** where `class="DefaultContentBlock"` with your own specific content. - - -13. Save the page, and then refresh the server-side preview in Design Manager to make sure the Security Trim panel appears as expected. - - -## Understanding the snippet markup - +1. Replace the `
` where `class="DefaultContentBlock"` with your own specific content. +1. Save the page, and then refresh the server-side preview in Design Manager to make sure the Security Trim panel appears as expected. -The most important parts of a Security Trim snippet are the **AuthenticationRestrictions** property and the **Permissions** property, and the **
** in bold below. **AuthenticationRestrictions** appears in the markup only when changed from **AllUsers**, which is the default. If you choose **Reset** for the snippet in the Snippet Gallery, **AuthenticationRestrictions** is removed from the markup, which means the snippet uses the default value, **AllUsers**. - - - -The **
** where `class="DefaultContentBlock"` is what you replace with your own content, which can include other snippets and controls. - - - +## Understanding the snippet markup +The most important parts of a Security Trim snippet are the **AuthenticationRestrictions** property and the **Permissions** property, and the `
` in bold below. **AuthenticationRestrictions** appears in the markup only when changed from **AllUsers**, which is the default. If you choose **Reset** for the snippet in the Snippet Gallery, **AuthenticationRestrictions** is removed from the markup, which means the snippet uses the default value, **AllUsers**. +The `
` where `class="DefaultContentBlock"` is what you replace with your own content, which can include other snippets and controls. ```HTML -
@@ -161,21 +96,9 @@ The **
** where `class="DefaultContentBlock"` is what you replace with your
``` - ## See also - - - -- [Understanding permission levels](https://support.office.com/article/understanding-permission-levels-in-sharepoint-87ecbb0e-6550-491a-8826-c075e4859848) - - -- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) - - -- [Build sites for SharePoint](build-sites-for-sharepoint.md) - - -- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) - - +- [Understanding permission levels](https://support.office.com/article/understanding-permission-levels-in-sharepoint-87ecbb0e-6550-491a-8826-c075e4859848) +- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) +- [Build sites for SharePoint](build-sites-for-sharepoint.md) +- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) diff --git a/docs/general-development/how-to-add-a-web-part-zone-snippet-in-sharepoint.md b/docs/general-development/how-to-add-a-web-part-zone-snippet-in-sharepoint.md index 76f02dcf2..5390f1ed0 100644 --- a/docs/general-development/how-to-add-a-web-part-zone-snippet-in-sharepoint.md +++ b/docs/general-development/how-to-add-a-web-part-zone-snippet-in-sharepoint.md @@ -1,206 +1,116 @@ --- title: Add a web part zone snippet in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to add a web part zone snippet in SharePoint and provides a list of Web part zone properties used to restrict content authors. +ms.date: 05/18/2023 ms.assetid: 7583b217-200c-4569-8f88-fe975c8ebd72 -localization_priority: Priority +ms.localizationpriority: high --- - # Add a web part zone snippet in SharePoint +> [!IMPORTANT] +> This extensibility option is **only** available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. We do not recommend using classic experience or these branding techniques anymore. + A web part zone is a snippet that you can add to a page layout so that content authors can add, edit, or delete web parts in that zone. ## Introduction to the web part zone snippet - A web part is a server control that provides a specific piece of SharePoint functionality, and a web part zone is a container that determines the layout, behavior, and other properties of the web parts contained in that zone. For example, a web part zone can specify whether the web parts in the zone: - - - -- Are arranged in a horizontal or vertical layout. - - +- Are arranged in a horizontal or vertical layout. - Display common user interface (UI) elements such as a title bar or border. - - - Can be customized by content authors when they edit a page in the browser. - - - Can be personalized by site visitors who create a personal view of a web part when they view a page in the browser. - - + In a publishing site, content authors with the necessary permissions can create or edit pages that reside in the Pages library. As a designer, you can add a web part zone to a page layout. When a content author creates or edits a page based on that page layout, the author can add, edit, or delete web parts in that zone. For example, you may want to add a web part zone to a page layout so that content authors can: - - - - Display the results of a search query by using a Content Search web part. Authors can update or modify the search query when a search-driven web part resides inside a web part zone. - - - Embed video or audio clips in a webpage by using a Media web part. - - - Create lists of hyperlinks that are easily edited, grouped, or reordered by using a Summary Link web part. - - - Create a site map that lists all pages in a site and that is automatically updated whenever a page is added, deleted, renamed, or moved by using a Table of Contents web part. - - ### When to use web part zones When a page layout includes one or more web part zones, the web part zones are available on all pages that use that layout, which enables authors to insert web parts onto those pages. If you enable authors to insert web parts on pages, you reduce your control over the users' experience of the site. For example, an author could insert a Table of Contents web part onto a page that exposes parts of your site that you don't want visitors to navigate to from the current page. - - - + If you want complete control over how a web part appears on your site, and if you want that web part to appear on all pages of a certain type, add the web part directly to a page layout. If you want a web part to appear on all pages in a site, you can also add a web part directly to a master page. - + > [!NOTE] -> Web part zones are available on page layouts but not on master pages—the purpose of zones is to allow authors to modify web parts, and authors typically don't edit a master page. - - - +> Web part zones are available on page layouts but not on master pages—the purpose of zones is to allow authors to modify web parts, and authors typically don't edit a master page. You can also add web part zones to a page layout but restrict their use. For example, you can add web parts to a zone, and then set a property of that zone so that content authors can edit the properties of existing web parts but not add or remove web parts from the zone. web part zones have a set of properties that serve a dual purpose. You can use one subset of properties to organize the layout and format of web parts on the page. You can use another subset of properties to provide an additional level of protection from modification (or "lock down") of the web parts within the zone. - - - + For varying levels of control over how web parts are presented on your site, you can: - - - - Add web parts directly to a master page or page layout. This means content authors cannot modify the web parts. - - - Add web parts to zones on page layouts, but restrict those zones to only the default web parts that you add. - - - Add web part zones to page layouts, and give content authors complete control over what web parts appear in those zones and how they are configured. - - + The properties of a web part zone can specify whether content authors are allowed to change: - - - - The layout of web parts in the zone by adding, deleting, resizing, or moving the web parts. - - - The web part settings for all users (the shared view of a web part). - - - Their personal web part settings (the personal view of a web part). - - + Table 1 shows important properties to consider when you want to restrict a web part zone. - - - **Table 1. Web part zone properties used to restrict content authors** - |**Property Name**|**Description**| |:-----|:-----| -|**AllowLayoutChange**
|Specifies whether web parts within the zone can be closed, minimized, deleted, or restored.
If set to **False**, users cannot close, minimize, delete, or restore web parts in the zone, drag web parts to a different zone, or rearrange or move web parts within the zone. Users also cannot add web parts from the web part catalog, and several properties that affect the UI of web parts in the zone are disabled. This property does not affect the ability to change the layout programmatically.
If set to **True**, users with appropriate permissions can perform these actions.
| -|**LockLayout**
|Specifies whether web parts within the zone can be added, deleted, resized, or moved. This property works the same whether the web part page is in personal view or shared view.
If set to **True**, the specific web part properties for each web part in the zone that are affected are: **Zone (ZoneID)**, **Part Order (PartOrder)**, **Visible on Page (IsVisible)**, **Height (Height)**, **Width (Width)**, **Allow Close (AllowRemove)**, and **IsIncluded** (the **Close** command on the **web part** menu). Other web part properties are not affected.
If set to **False**, the web part properties determine whether modifications can be made (together with the appropriate site permissions).
| -|**AllowCustomization**
|Specifies whether shared property values of web parts within the zone can be modified.
If set to **True**, users with appropriate permissions can make changes to the web parts in the zone for all users.
If set to **False**, users cannot make changes to the web parts in the zone in the UI in shared view. But, changes can still be made programmatically and by using the web part Maintenance page.
| -|**AllowPersonalization**
|Specifies whether personal property values of web parts within the zone can be modified.
If set to **True**, users with appropriate permissions can make personal changes to the web parts in the zone.
If set to **False**, users cannot make personal changes to the web parts through the UI, unless the web part is a private web part and they have appropriate permissions.
| - -> [!NOTE] -> You cannot insert a web part zone inside a Device Channel Panel. If you want to allow authors to add web parts to a page, and if you are not concerned about the page weight for mobile devices, you can add a Rich Text Editor page field to a Device Channel Panel, and then instruct authors to add web parts there. You can add web parts directly to a Device Channel Panel (without a web part zone). For more information, see [How to: Add a Device Channel Panel snippet in SharePoint](how-to-add-a-device-channel-panel-snippet-in-sharepoint.md). - - - +|**AllowLayoutChange** |Specifies whether web parts within the zone can be closed, minimized, deleted, or restored. If set to **False**, users cannot close, minimize, delete, or restore web parts in the zone, drag web parts to a different zone, or rearrange or move web parts within the zone. Users also cannot add web parts from the web part catalog, and several properties that affect the UI of web parts in the zone are disabled. This property does not affect the ability to change the layout programmatically. If set to **True**, users with appropriate permissions can perform these actions. | +|**LockLayout** |Specifies whether web parts within the zone can be added, deleted, resized, or moved. This property works the same whether the web part page is in personal view or shared view. If set to **True**, the specific web part properties for each web part in the zone that are affected are: **Zone (ZoneID)**, **Part Order (PartOrder)**, **Visible on Page (IsVisible)**, **Height (Height)**, **Width (Width)**, **Allow Close (AllowRemove)**, and **IsIncluded** (the **Close** command on the **web part** menu). Other web part properties are not affected. If set to **False**, the web part properties determine whether modifications can be made (together with the appropriate site permissions). | +|**AllowCustomization** |Specifies whether shared property values of web parts within the zone can be modified. If set to **True**, users with appropriate permissions can make changes to the web parts in the zone for all users. If set to **False**, users cannot make changes to the web parts in the zone in the UI in shared view. But, changes can still be made programmatically and by using the web part Maintenance page. | +|**AllowPersonalization** |Specifies whether personal property values of web parts within the zone can be modified. If set to **True**, users with appropriate permissions can make personal changes to the web parts in the zone. If set to **False**, users cannot make personal changes to the web parts through the UI, unless the web part is a private web part and they have appropriate permissions. | +> [!NOTE] +> You cannot insert a web part zone inside a Device Channel Panel. If you want to allow authors to add web parts to a page, and if you are not concerned about the page weight for mobile devices, you can add a Rich Text Editor page field to a Device Channel Panel, and then instruct authors to add web parts there. You can add web parts directly to a Device Channel Panel (without a web part zone). For more information, see [How to: Add a Device Channel Panel snippet in SharePoint](how-to-add-a-device-channel-panel-snippet-in-sharepoint.md). ## Inserting a web part zone snippet - Like all snippets, you add this snippet from the Snippet Gallery. To navigate to the Snippet Gallery, you must first select a page layout to edit. Web part zones can be added to page layouts but cannot be added to master pages. - - - ### To insert a web part zone snippet - 1. Browse to your publishing site. - - -2. In the upper-right corner of the page, choose the Settings gear, and then choose **Design Manager**. - - -3. In Design Manager, in the left navigation pane, choose **Edit Page Layouts**. - - -4. Select the name of the page layout that you want to add the snippet to. - - -5. To open the Snippet Gallery, choose **Snippets** in the upper-right corner of the server-side preview. - - -6. On the ribbon, on the **Design** tab, choose **web part zone**. - - -7. On the right side of the Snippet Gallery, under **About this Component**, click or select section headers to expand or collapse groups of properties, and then configure any custom settings that you want. - +1. In the upper-right corner of the page, choose the Settings gear, and then choose **Design Manager**. +1. In Design Manager, in the left navigation pane, choose **Edit Page Layouts**. +1. Select the name of the page layout that you want to add the snippet to. +1. To open the Snippet Gallery, choose **Snippets** in the upper-right corner of the server-side preview. +1. On the ribbon, on the **Design** tab, choose **web part zone**. +1. On the right side of the Snippet Gallery, under **About this Component**, click or select section headers to expand or collapse groups of properties, and then configure any custom settings that you want. + The section named **Important** contains the properties that are key to how this particular snippet works. For a web part zone, the snippet has a unique ID. After you copy the snippet into your page layout, you should not reuse this ID. If you want to add another web part zone snippet, choose **Refresh** to generate a new ID for the next snippet. - + For descriptions of properties that are necessary for restricting a web part zone ( **LockLayout**, **AllowCustomization**, and **AllowPersonalization**), see Table 1. - + > [!NOTE] - > You may notice that some property names are bold in the property grid of the Snippet Gallery. These properties have values that have been changed from the default setting for this component, but these properties are not necessarily relevant to a designer scenario. In other words, a property may be bold but not necessarily important for your scenario. - -8. After you configure any properties, choose **Update**. This updates the HTML snippet on the left side of the page, so that the markup reflects your custom settings. You can always choose **Reset** to return all properties to their default settings. - - -9. On the left side of the Snippet Gallery, under **HTML Snippet**, choose **Copy to Clipboard**. - - -10. In your HTML editor, open the mapped network drive on your computer, and then open the HTML file for the master page or page layout that you're adding the snippet to. - + > You may notice that some property names are bold in the property grid of the Snippet Gallery. These properties have values that have been changed from the default setting for this component, but these properties are not necessarily relevant to a designer scenario. In other words, a property may be bold but not necessarily important for your scenario. + +1. After you configure any properties, choose **Update**. This updates the HTML snippet on the left side of the page, so that the markup reflects your custom settings. You can always choose **Reset** to return all properties to their default settings. +1. On the left side of the Snippet Gallery, under **HTML Snippet**, choose **Copy to Clipboard**. +1. In your HTML editor, open the mapped network drive on your computer, and then open the HTML file for the master page or page layout that you're adding the snippet to. + For more information, see [How to: Map a network drive to the SharePoint Master Page Gallery](how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md). - - -11. In the HTML file, paste the snippet where you want the markup to appear. - + +1. In the HTML file, paste the snippet where you want the markup to appear. + When you are adding the snippet to a page layout, make sure to paste the snippet inside **PlaceHolderMain**. - - -12. Replace the **
** where `class="DefaultContentBlock"` with your own specific content. - - -13. If you want to prepopulate the zone with web parts—for example, if the zone will restrict content authors to modifying only existing web parts and not adding new ones—insert web part snippets where the **** tag appears. - - -14. Save the page, and then refresh the server-side preview in Design Manager to make sure the page appears as expected. - - + +1. Replace the `
` where `class="DefaultContentBlock"` with your own specific content. +1. If you want to prepopulate the zone with web parts—for example, if the zone will restrict content authors to modifying only existing web parts and not adding new ones—insert web part snippets where the **** tag appears. +1. Save the page, and then refresh the server-side preview in Design Manager to make sure the page appears as expected. ## Understanding the snippet markup - The two most important parts of a web part zone snippet are the **ID** property and the **** comment. Each zone should have a unique ID. If you want to add more than one web part zone to your page layout, make sure to choose **Refresh** in the Snippet Gallery before copying each snippet so that a new ID is generated. The **** comment should be replaced with any web parts that you want to appear in the zone by default. - - - + Additional properties that can be used to restrict how content authors can use zones ( **AllowCustomization**, **AllowPersonalization**, and **LockLayout**) are shown in the following code. - + > [!NOTE] > The **AllowCustomization**, **AllowPersonalization**, and **LockLayout** properties appear in the markup only if you change their default values in the property grid. - - - - - - - -```HTML +```html
@@ -216,24 +126,10 @@ Additional properties that can be used to restrict how content authors can use z ``` - ## See also - - - -- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) - - -- [WebPartZone class](https://msdn.microsoft.com/library/system.web.ui.webcontrols.webparts.webpartzone.aspx) - - -- [WebPartZoneBase properties](https://msdn.microsoft.com/library/335sw9k3.aspx) - - -- [Build sites for SharePoint](build-sites-for-sharepoint.md) - - -- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) - - +- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) +- [WebPartZone class](https://msdn.microsoft.com/library/system.web.ui.webcontrols.webparts.webpartzone.aspx) +- [WebPartZoneBase properties](https://msdn.microsoft.com/library/335sw9k3.aspx) +- [Build sites for SharePoint](build-sites-for-sharepoint.md) +- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) diff --git a/docs/general-development/how-to-add-an-edit-mode-panel-snippet-in-sharepoint.md b/docs/general-development/how-to-add-an-edit-mode-panel-snippet-in-sharepoint.md index 0644cca70..c5ebadd63 100644 --- a/docs/general-development/how-to-add-an-edit-mode-panel-snippet-in-sharepoint.md +++ b/docs/general-development/how-to-add-an-edit-mode-panel-snippet-in-sharepoint.md @@ -1,14 +1,17 @@ --- title: Add an Edit Mode Panel snippet in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to add an Edit Mode Panel snippet in SharePoint to display instructions or other content to content authors. +ms.date: 06/09/2022 ms.assetid: 39fa1e32-9129-407d-914f-96f4c6e66dc8 -localization_priority: Normal +ms.localizationpriority: medium --- # Add an Edit Mode Panel snippet in SharePoint +> [!IMPORTANT] +> This extensibility option is **only** available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. We do not recommend using classic experience or these branding techniques anymore. + An Edit Mode Panel is a snippet that you can use to display instructions or other content to content authors, who see the contents of that panel only when they edit a page. Conversely, this snippet can also be configured to display its contents only in regular (view) mode instead of in edit mode. ## Introduction to the Edit Mode Panel diff --git a/docs/general-development/how-to-apply-a-master-page-to-a-site-in-sharepoint.md b/docs/general-development/how-to-apply-a-master-page-to-a-site-in-sharepoint.md index 80b96e64d..ca1720117 100644 --- a/docs/general-development/how-to-apply-a-master-page-to-a-site-in-sharepoint.md +++ b/docs/general-development/how-to-apply-a-master-page-to-a-site-in-sharepoint.md @@ -1,13 +1,17 @@ --- title: Apply a master page to a site in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to apply a master page to a site in SharePoint and how to map a master page to a SharePoint site. +ms.date: 06/09/2022 ms.assetid: 04861390-84d5-40ea-b0db-6c0748eff196 -localization_priority: Priority +ms.localizationpriority: high --- # Apply a master page to a site in SharePoint + +> [!IMPORTANT] +> This extensibility option is **only** available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. We do not recommend using classic experience or these branding techniques anymore. + Learn how to map a master page to a SharePoint site. ## Mapping a master page to a site diff --git a/docs/general-development/how-to-apply-styles-to-page-fields-in-sharepoint.md b/docs/general-development/how-to-apply-styles-to-page-fields-in-sharepoint.md index e4be8dc84..084691223 100644 --- a/docs/general-development/how-to-apply-styles-to-page-fields-in-sharepoint.md +++ b/docs/general-development/how-to-apply-styles-to-page-fields-in-sharepoint.md @@ -1,58 +1,34 @@ --- title: Apply styles to page fields in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: In a page layout, you can apply styles to a page field, and those styles are applied to any content added by content authors when they create a page from that page layout. Also, you have further options to control how content in a RichHtmlField page field is styled. +ms.date: 12/22/2020 ms.assetid: e227613d-0e4d-4312-924d-bb55e1fe4293 -localization_priority: Priority +ms.localizationpriority: high --- - - # Apply styles to page fields in SharePoint + In a page layout, you can apply styles to a page field, and those styles are applied to any content added by content authors when they create a page from that page layout. Also, you have further options to control how content in a RichHtmlField page field is styled. + ## Introduction to applying styles to page fields - As a designer, you have ultimate control over the positioning and styling of page fields on a page layout and on any pages created from that page layout. When content authors create pages from a browser, they can't move page fields on the page or override the styles that you specify. This helps to ensure that your branding remains consistent through all pages in the site. - - - + When you apply styles to page fields, there are two basic categories of field types to consider: - - - - **Field types other than RichHtmlField** The page fields that make up a page layout conform to the content type for that page layout. A page field can be of many types, such as a Single Line of Text (TextField) or Multiple Lines of Text (NoteField). As a designer, you can apply styles to all of these page fields in the same way, by applying styles to the page field directly on the page layout. - - - **RichHtmlField** The rich HTML field control (also known as a Publishing HTML field) is one of the most powerful and frequently used controls in page layouts. By default, in a rich HTML field, content authors use the ribbon to format and apply styles to content, and to insert tables, media such as images and video, and web parts. This field type is useful when you want to give content authors the freedom to add and style content within parameters that you can control. You can control a RichHtmlField in two ways: - - **Create a custom style sheet** By default, the styles available on the ribbon of a RichHtmlField come from a style sheet named HtmlEditorStyles.css. You can configure the **PrefixStyleSheet** property for this snippet so that your own custom styles appear on the ribbon for content authors to use. - - - **Configure the Allow properties** A snippet for a RichHtmlField has 28 available properties that start with **Allow**, and you can use these properties to make specific commands or groups of commands on the ribbon unavailable to content authors. For example, if you set the **AllowFontsMenu** property to **False**, authors cannot use the Font menu on the ribbon to change what font is applied to text; instead, they can use only the CSS styles that you specify. - - + For all types of page fields, including the RichHtmlField, the designer determines how the content is styled. You can use the RichHtmlField to give content authors the freedom to insert rich content and apply styles; you still have ultimate control over what content can be added and what styles can be applied. - - - ## Applying styles to page fields other than RichHtmlField - With a page field control, you can define the styles used by the content. Authors can add content to a page, but the designer controls how that content is rendered through CSS applied to those controls. - - - -In the HTML page layout, each page field is wrapped in a **\** tag. To apply a style to a page field, you can simply add a style to the **\**—for example, `
** for each page field in the page layout, and then use the **id** as a selector for styles that reside in an external style sheet. This way, if you have multiple device channels, and each channel has its own style sheet, you can apply different styles to each page field for each channel. For example, the following page field of the type TextField (also called Multiple Lines of Text) might have only an **id** attribute on the **\** tag. - - - - +In the HTML page layout, each page field is wrapped in a `` tag. To apply a style to a page field, you can simply add a style to the ``. For example, `
` for each page field in the page layout, and then use the `ID` as a selector for styles that reside in an external style sheet. This way, if you have multiple device channels, and each channel has its own style sheet, you can apply different styles to each page field for each channel. For example, the following page field of the type TextField (also called Multiple Lines of Text) might have only an `ID` attribute on the `` tag. ```HTML -
@@ -64,30 +40,16 @@ In the HTML page layout, each page field is wrapped in a **\** tag. To app ``` For more information about where styles and style references for a page layout should go, see [How to: Create a page layout in SharePoint](how-to-create-a-page-layout-in-sharepoint.md). - - - ## Disabling options on the ribbon of a RichHtmlField - -When content authors create or edit a page and then add content to a RichHtmlField using a browser, they can use commands on the ribbon for that field to format, style, or insert rich content and media. - - - -In the Snippet Gallery, you can configure the properties of a page field of the type RichHtmlField, so that specific commands or groups of commands on the ribbon are made unavailable to authors. For example, by setting the **AllowFontSizesMenu** property to **False**, you can disable the **Font Size** menu on the ribbon. By setting the **AllowFonts** property to **False**, you can disable the entire **Font** group on the ribbon. - - - -After you configure these properties in the Snippet Gallery and then update the snippet, the properties appear in the snippet markup inside the ` @@ -100,182 +62,104 @@ After you configure these properties in the Snippet Gallery and then update the ``` > [!NOTE] -> If you set **AllowFonts** to **False**, content authors can still use keyboard shortcuts such as CTRL+B (strong) to format text. To prevent authors from adding any styles to text, you can set **AllowTextMarkup** to **False**. With this setting, when content authors attempt to save content that contains styles applied to text, the HTML editor in the browser returns an error and prompts the author to remove the markup that is not valid. - - - +> If you set **AllowFonts** to **False**, content authors can still use keyboard shortcuts such as CTRL+B (strong) to format text. To prevent authors from adding any styles to text, you can set **AllowTextMarkup** to **False**. With this setting, when content authors attempt to save content that contains styles applied to text, the HTML editor in the browser returns an error and prompts the author to remove the markup that is not valid. A RichHtmlField page field contains 28 different **Allow** properties. For more information about what specific properties control, see [RichHtmlField properties](https://msdn.microsoft.com/library/microsoft.sharepoint.publishing.webcontrols.richhtmlfield_properties) For more information about adding and configuring snippets, see [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md). - - - ## Controlling the styles available in a RichHtmlField - In a RichHtmlField, content authors can use options on the ribbon to format content. These formatting options are implemented by using CSS, and these styles are defined in a SharePoint style sheet named HtmlEditorStyles.css that resides on the server at one of the following locations: - - - - -- C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\15\\TEMPLATE\\LAYOUTS\\1033\\STYLES - - -- C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\15\\TEMPLATE\\FEATURES\\PublishingLayouts\\en-us - - -Because the RichHtmlField in the browser uses CSS to implement its styles, you can create your own styles that are consistent with the branding of your site, and then you can make those styles available on the ribbon for content authors to use. To make minor changes to the default styles, you can copy an existing style from HtmlEditorStyles.css to your style sheet that is referenced by the page layout, and then modify that style by changing the CSS properties and values (but not the selector). You can also hide default styles from the ribbon by copying them to your style sheet and then setting `display:none`. - - - -To implement custom styles, you can also build a style sheet from scratch by changing the **PrefixStyleSheet** property for the RichHtmlField snippet. By default, this property is set to **ms-rte**, and the styles in the default style sheet HtmlEditorStyles.css each begin with this prefix—for example: - - - +- **C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\LAYOUTS\1033\STYLES** +- **C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\FEATURES\PublishingLayouts\en-us** +Because the RichHtmlField in the browser uses CSS to implement its styles, you can create your own styles that are consistent with the branding of your site, and then you can make those styles available on the ribbon for content authors to use. To make minor changes to the default styles, you can copy an existing style from HtmlEditorStyles.css to your style sheet that is referenced by the page layout, and then modify that style by changing the CSS properties and values (but not the selector). You can also hide default styles from the ribbon by copying them to your style sheet and then setting `display:none`. -```HTML +To implement custom styles, you can also build a style sheet from scratch by changing the **PrefixStyleSheet** property for the RichHtmlField snippet. By default, this property is set to **ms-rte**, and the styles in the default style sheet HtmlEditorStyles.css each begin with this prefix—for example: +```HTML H1. ms-rteElement-H1 { --ms-name:"Heading 1"; --ms-element:"true"; + -ms-name:"Heading 1"; + -ms-element:"true"; } ``` When you change the value of the **PrefixStyleSheet** property, none of the existing **ms-rte** styles are available in the rich HTML editor, and only styles that you create that use the new prefix are available to content authors. This means if you want to use some of the default styles, they must be copied to your style sheet and modified so that they use the new prefix. - + > [!NOTE] > The **PrefixStyleSheet** property is defined per each RichHtmlField page field, but multiple page fields can use the same value for this property. So, if multiple page layouts reference the same style sheet, it's possible for multiple RichHtmlFields on those page layouts to have the same style prefix and reference the same styles. - - - - ### To define a new list of styles for a RichHtmlField - 1. Browse to your publishing site. - - -2. In the upper-right corner of the page, choose **Settings**, and then choose **Design Manager**. - - -3. In Design Manager, in the left navigation pane, choose **Edit Page Layouts**. - - -4. Choose the page layout on which the RichHtmlField page field will reside. - - -5. In the upper-right corner of the server-side preview, choose **Snippet Gallery**. - - -6. On the ribbon, choose **Page Fields**, and then choose a page field of the type **RichHtmlField**. - - -7. In the property grid, expand the **Misc** section, and then change the **PrefixStyleSheet** property to a value other than **ms-rte**—for example, change the value to be **customstyle**. - - > **Important:** - > This property value must be all lowercase. -8. Choose **Update**. - - -9. On the left side of the Snippet Gallery, choose **Copy to Clipboard**. - - -10. In the mapped network drive on your computer, open the HTML page layout in your HTML editor. - +1. In the upper-right corner of the page, choose **Settings**, and then choose **Design Manager**. +1. In Design Manager, in the left navigation pane, choose **Edit Page Layouts**. +1. Choose the page layout on which the RichHtmlField page field will reside. +1. In the upper-right corner of the server-side preview, choose **Snippet Gallery**. +1. On the ribbon, choose **Page Fields**, and then choose a page field of the type **RichHtmlField**. +1. In the property grid, expand the **Misc** section, and then change the **PrefixStyleSheet** property to a value other than **ms-rte**—for example, change the value to be **customstyle**. + + > [!IMPORTANT] + > This property value must be all lowercase. + +1. Choose **Update**. +1. On the left side of the Snippet Gallery, choose **Copy to Clipboard**. +1. In the mapped network drive on your computer, open the HTML page layout in your HTML editor. + > [!NOTE] - > For more information, see [How to: Map a network drive to the SharePoint Master Page Gallery](how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md). + > For more information, see [How to: Map a network drive to the SharePoint Master Page Gallery](how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md). + +1. In the HTML page layout, paste the HTML snippet inside **PlaceHolderMain**. +1. Save the HTML page layout. The changes to the HTML file are synced to the associated .aspx page layout. -11. In the HTML page layout, paste the HTML snippet inside **PlaceHolderMain**. - - -12. Save the HTML page layout. The changes to the HTML file are synced to the associated .aspx page layout. - At this point, if a content author creates or edits a page based on this page layout, no styles are available on the ribbon of the HTML editor because this specific page field uses only styles that begin with the new prefix **customstyle**, but those styles have not yet been defined. - - -13. On the server, browse to the following location and open HtmlEditorStyles.css: - - C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\15\\TEMPLATE\\LAYOUTS\\1033\\STYLES - - It's useful to view the default styles, understand how they're written, and possibly reuse some of them by copying them to your style sheet and then modifying them. If you do this, replace the default **ms-rte** prefix with your own prefix. - - > [!IMPORTANT] - > Do not modify the default style sheet, HtmlEditorStyles.css. This style sheet provides styles for every RichHtmlField in the farm. Also, service updates or an upgrade may overwrite this file, causing you to lose any changes. -14. In your style sheet, create a list of new styles that start with the new prefix. - - For example, if **customstyle** is the new prefix, your style sheet might contain the following style. - +1. On the server, browse to the following location and open HtmlEditorStyles.css: + **C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\LAYOUTS\1033\STYLES** -```HTML - -H2.customstyleElement-H2 -{ --ms-name:"Heading 2"; --ms-element:"true"; -} -customstyleElement-H2 -{ -font-weight: bold; -font-family: Cambria; -font-size: 16pt; -} + It's useful to view the default styles, understand how they're written, and possibly reuse some of them by copying them to your style sheet and then modifying them. If you do this, replace the default **ms-rte** prefix with your own prefix. -``` + > [!IMPORTANT] + > Do not modify the default style sheet, HtmlEditorStyles.css. This style sheet provides styles for every RichHtmlField in the farm. Also, service updates or an upgrade may overwrite this file, causing you to lose any changes. + +1. In your style sheet, create a list of new styles that start with the new prefix. + + For example, if **customstyle** is the new prefix, your style sheet might contain the following style. + ```HTML + H2.customstyleElement-H2 + { + -ms-name:"Heading 2"; + -ms-element:"true"; + } + customstyleElement-H2 + { + font-weight: bold; + font-family: Cambria; + font-size: 16pt; + } + ``` For clarity, the class name and the name of the style as it appears on the ribbon are defined separately from the style properties. In this example, **H2** is the element selector for the style, and **customstyleElement-H2** is the class name of the style. The class name has two parts: **customstyle** is the prefix that you specified for this page field, and **Element** specifies that this style will appear in the **Page Elements** section of the **Styles** gallery on the ribbon of the HTML editor. The **-ms-name** property sets the display name that appears to content authors in the Styles gallery. - + SharePoint maps a style to a menu or command on the ribbon by parsing the class name immediately after the prefix and looking for one of these strings: - - - **Element**: The Page Elements section of the Styles gallery - - - - **Style**: The Text Styles section of the Styles gallery - - - - **FontSize**: The Font Size menu - - - - **ThemeFontFace**: The Font menu - - - - **ForeColor**: The Font Color menu - - - - **BackColor**: The Highlight Color menu - - - - **Image**: The Image menu - - - - **Table**: The Table menu - - - - **Position**: The Align buttons in the Paragraph group - - + + - **Element**: The Page Elements section of the Styles gallery + - **Style**: The Text Styles section of the Styles gallery + - **FontSize**: The Font Size menu + - **ThemeFontFace**: The Font menu + - **ForeColor**: The Font Color menu + - **BackColor**: The Highlight Color menu + - **Image**: The Image menu + - **Table**: The Table menu + - **Position**: The Align buttons in the Paragraph group For more information about where styles for a page layout should reside, see [How to: Create a page layout in SharePoint](how-to-create-a-page-layout-in-sharepoint.md). - - ## See also - - - -- [Overview of Design Manager in SharePoint](overview-of-design-manager-in-sharepoint.md) - - -- [How to: Create a page layout in SharePoint](how-to-create-a-page-layout-in-sharepoint.md) - - -- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) - - +- [Overview of Design Manager in SharePoint](overview-of-design-manager-in-sharepoint.md) +- [How to: Create a page layout in SharePoint](how-to-create-a-page-layout-in-sharepoint.md) +- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) diff --git a/docs/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md b/docs/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md index f1a08eb6b..f239f0fb8 100644 --- a/docs/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md +++ b/docs/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md @@ -1,282 +1,325 @@ --- title: Avoid getting throttled or blocked in SharePoint Online -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn about throttling in SharePoint Online and learn how to avoid being throttled or blocked. +ms.date: 06/12/2025 ms.assetid: 33ed8106-d850-42b1-8d7f-5ba83901149c -localization_priority: Priority +ms.localizationpriority: high --- - # Avoid getting throttled or blocked in SharePoint Online -Find out about throttling in SharePoint Online, and learn how to avoid being throttled or blocked. Includes sample CSOM and REST code you can use to make your task easier. +Find out about throttling in SharePoint Online and learn how to avoid being throttled or blocked. -- [What is throttling?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_Whatisthrottling) +- [What is throttling?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#what-is-throttling) +- [How to handle throttling?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#how-to-handle-throttling) +- [Common throttling scenarios in SharePoint Online](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#common-throttling-scenarios-in-sharepoint-online) +- [Scenario specific limits](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#scenario-specific-limits) +- [What should you do if you get blocked in SharePoint Online?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#what-should-you-do-if-you-get-blocked-in-sharepoint-online) +- [Additional resources](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#see-also) -- [Common throttling scenarios in SharePoint Online](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_Commonthrottlingscenarios) +Does this sound familiar? You're running an application - for example, to scan files in SharePoint Online - but you get throttled. Or even worse, you get blocked. What's going on and what can you do to make it stop? -- [Why can't you just tell me the exact throttling limits?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_Whycantyoujusttellmetheexactthrottlinglimits) +## What is throttling? -- [Best practices to handle throttling](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_Bestpracticestohandlethrottling) - -- [How to decorate your traffic to avoid getting throttled?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_DecorateSharePointOnlineThrottling) - -- [GitHub CSOM code samples: SharePoint Online Throttling](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md) - - -- [What should you do if you get blocked in SharePoint Online?](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_Whatshouldyoudoifyougetblocked) - - -- [Additional resources](how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online.md#BKMK_Additionalresources) +SharePoint Online uses throttling to maintain the optimal performance and reliability of the SharePoint Online service. Throttling limits the number of API calls or operations within a time window to prevent the overuse of resources. + +> [!NOTE] +> Recent updates to this article enhance transparency to already existing throttling rules in the system -Does this sound familiar? You're running a CSOM process - for example, to migrate files in SharePoint Online - but you keep getting throttled. Or even worse, you get completely blocked. What's going on and what can you do to make it stop? - -## What is throttling? - - -SharePoint Online uses throttling to maintain optimal performance and reliability of the SharePoint Online service. Throttling limits the number of user actions or concurrent calls (by script or code) to prevent overuse of resources. - -That said, it is extremely rare for a user to get throttled in SharePoint Online. The service is robust, and it is designed to handle very high volume. If you do get throttled, 99% of the time it is because of custom code. That doesn't mean that there aren't other ways to get throttled, just that they are less common. For example you spin up 10 machines and have a sync client going on all 10. On each sync 1TB of content. This would likely get you throttled. - -![How throttling happens](../images/3b9184db-99a4-416e-ba1e-7f8653484cee.png) - ### What happens when you get throttled in SharePoint Online? -When a user exceeds usage limits, SharePoint Online throttles any further requests from that user account for a short period. All user actions are throttled while the throttle is in effect. - -- For requests that a user performs directly in the browser, SharePoint Online redirects you to the throttling information page, and the requests fail. - -- For all other requests, including CSOM or REST calls, SharePoint Online returns HTTP status code 429 ("Too many requests") or 503 ("Server Too Busy") and the requests will fail. - -If the offending process continues to exceed usage limits, SharePoint Online might completely block the process; in this case, you will not see any successful requests and we will notify you of the block in the Office 365 Message Center. +When usage limits are exceeded, SharePoint Online throttles any further requests from that client for a short period. + +For requests that a user performs directly in the browser, SharePoint Online redirects you to the throttling information page, and the requests fail. + +For requests that an application makes, including [Microsoft Graph](/graph), CSOM, or REST calls, SharePoint Online returns HTTP status code 429 ("Too many requests") or 503 ("Server Too Busy"), and the requests will fail. + +- HTTP 429 indicates the calling application sent too many requests in a time window and exceeded a predetermined limit. +- HTTP 503 indicates the service isn't ready to handle the request. The common cause is that the service is experiencing more temporary load spikes. + +In both cases, a `Retry-After` header is included in the response, indicating how long the calling application should wait before retrying or making a new request. Throttled requests count towards usage limits, so failure to honor `Retry-After` may result in more throttling. + +If the offending application continues to exceed usage limits, SharePoint Online may completely block the application or specific request patterns from the application; in this case, the application will keep getting HTTP status code 503, and Microsoft will notify the tenant of the block in the Office 365 Message Center. + +### Resource units + +Some limits are measured in terms of API costs. [Microsoft Graph APIs](/graph) have a predetermined resource unit cost per request: + +| Resource units per request | Operations | +| -------------------------- | -------------------------------------------------------------------------------------------------------------- | +| 1 |
  • Single item query, such as get item
  • Delta with a token
  • Download file from drive item | +| 2 |
  • Multi item query, such as list children, except delta with a token
  • Create, update, delete, and upload | +| 5 |
  • All permission resource operations, including `$expand=permissions` | + +> [!NOTE] +> We reserve the right to change the API resource unit cost. + +### User Throttling + +Throttling limits the number of calls and operations collectively made by applications on behalf of a user to prevent the overuse of resources. + +That said, it's rare for a user to get throttled in SharePoint Online. The service is robust, and it's designed to handle high volume. If you do get throttled, 99% of the time it is because of custom code, such as custom web parts, complex list views and queries, or custom apps users run. That doesn’t mean that there aren’t other ways to get throttled, just that they’re less common. For example, one user syncing a large amount of data across 10 machines at the same time could trigger throttling. + +| Category | Type of throttling | Time interval | Limit | +|--------------|------------------------------|-------------------|-----------| +| User | Requests | 5 min | 3,000 | +| User | Ingress | 1 H | 50 GB | +| User | Egress | 1 H | 100 GB | +| User | Delegation Token Request | 5 min | 50 | +| User | External sharing emails | 1 H | 200 | + +> [!NOTE] +> Displayed limits are default values. Microsoft may change these limits at any time. Your experience may vary + +### Tenant Throttling + +Some throttling limits are applied at the Tenant level to ensure the operations collectively made do not overuse resources. + +When a customer enables Multi-Geo, each geo gets its own limits (usage measurement not shared across geos). For the limits that are dependent on license count, the total tenant user license count is used (total users across all geos). + +| Category | Type of throttling | Time interval | Tenant license count | Limit | +|--------------|--------------------------------------|-------------------|--------------------------|-----------| +| Tenant | [Resource Units](#resource-units) | 5 min | 0 - 1,000 | 18,750 | +| Tenant | [Resource Units](#resource-units) | 5 min | 1,001 - 5,000 | 37,500 | +| Tenant | [Resource Units](#resource-units) | 5 min | 5,001 - 15,000 | 56,250 | +| Tenant | [Resource Units](#resource-units) | 5 min | 15,001 - 50,000 | 75,000 | +| Tenant | [Resource Units](#resource-units) | 5 min | 50,000+ | 93,750 | +| Tenant | Assign Sensitivity Label | 5 min | no license bound | 100 | +| Tenant | PeopleManagerAPIs | 5 min | 0 - 1,000 | 3,000 | +| Tenant | PeopleManagerAPIs | 5 min | 1,001 - 5,000 | 6,000 | +| Tenant | PeopleManagerAPIs | 5 min | 5,001 - 15,000 | 9,000 | +| Tenant | PeopleManagerAPIs | 5 min | 15,001 - 50,000 | 12,000 | +| Tenant | PeopleManagerAPIs | 5 min | 50,000+ | 15,000 | + +> [!NOTE] +> Displayed limits are default values. Microsoft may change these limits at any time. Your experience may vary ### Application Throttling -In addition to throttling by user account, limits are also applied to each application. Every application in SharePoint Online has its own available resources, but multiple applications running against the same tenant ultimately share from the same resource bucket and in rare occurrences can cause rate limiting. -In these cases, SharePoint Online will attempt to prioritize interactive user requests over background activities. +In addition to throttling by user account, limits are also applied to applications in a tenant. -## Common throttling scenarios in SharePoint Online - +Every application has its own limits in a tenant, which are based on the number of licenses purchased per organization (see the plans listed on [SharePoint Limits](/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits#limits-by-plan) for licenses included). Every request that an application makes across all API endpoints, including [Microsoft Graph](/graph), CSOM, and REST, counts towards the application’s usage. -The most common causes of per-user throttling in SharePoint Online are client-side object model (CSOM) or Representational State Transfer (REST) code that performs too many actions too frequently. - +SharePoint provides various APIs. Different APIs have different costs depending on the complexity of the API. The cost of APIs is normalized by SharePoint and expressed by resource units. Application’s limits are also defined using resource units. -- **Sporadic traffic** - - Constant load or repetitive complex queries against SharePoint Online must be optimized for low impact. Failing to follow [best practices for scanning applications](https://aka.ms/ScanGuidance) that process files in bulk will likely result in throttling. These apps include sync engines, backup providers, search indexers, classification engines, data loss prevention tools, and any other tool which attempts to reason over the entirety of data and apply changes to it. - - - For example, after migrating files to SharePoint Online, you run a custom CSOM or REST script to update metadata on the files. The CSOM/REST script is updating a large number of files at a very high frequency, which triggers throttling. Similarly, an autocomplete UI widget using REST services, making too many calls to lists during each end user operation, may also cause throttling, depending on what other operations are consuming resources at the same time. - - ![Sporadic throttling](../images/a61afe25-9597-403f-b3fa-d3f630155021.png) - -- **Overwhelming traffic** - - A single process dramatically exceeds throttling limits, continually, over a long time period. - - - You used web services to build a tool to synchronize user profile properties. The tool updates user profile properties based on information from your line-of-business (LOB) human resources (HR) system. The tool makes calls at too high a frequency. - - - You're running a load-testing script on SharePoint Online and you get throttled. Load testing is not allowed on SharePoint Online. - - - You customized your team site on SharePoint Online, for example, by adding a status indicator on the Home page. This status indicator updates frequently, which causes the page to make too many calls to the SharePoint Online service - this triggered throttling. - - ![Steady throttling](../images/7849d413-381f-4558-9e50-b3cc9990d3e3.png) - -## Why can't you just tell me the exact throttling limits? - +For multitenant applications: -Setting and publishing exact throttling limits sounds very straightforward, but in fact it would result in more restrictive limits. We continually monitor resource usage on SharePoint Online. Depending on usage, we fine-tune thresholds so users can consume the maximum number of resources without degrading the reliability and performance of SharePoint Online. That's why it's so important for your CSOM or REST code to honor the retry-after header value; this lets your code run as fast as possible on any given day, and it lets your code back off "just enough" if it hits throttling limits. The code samples later in this article show you how to use the retry-after header. +1. Each tenant hosting the application is considered distinct, operating independently from others. Consequently, every application is subject to its own usage limits within each tenant as defined above. +1. The consumption of resource units by the application is to be measured on a per-tenant, per-application basis. This ensures that each tenant-application pair remains within the permissible resource limits specified for that particular tenant. +1. Should the application reach its resource limit within one tenant, this occurrence will not affect other instances of the application operating in different tenants. Each tenant's resource utilization is isolated, preventing cross-tenant impact. -## Best practices to handle throttling - +| Category | Type of throttling | Time interval | Tenant license count | Limit | +|--------------------|--------------------------------------|-------------------|--------------------------|------------| +| Per APP Per Tenant | [Resource Units](#resource-units) | 24 H | 0 - 1,000 | 1,200,000 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 24 H | 1,001 - 5,000 | 2,400,000 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 24 H | 5,001 - 15,000 | 3,600,000 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 24 H | 15,001 - 50,000 | 4,800,000 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 24 H | 50,000+ | 6,000,000 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 1 min | 0 - 1,000 | 1,250 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 1 min | 1,001 - 5,000 | 2,500 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 1 min | 5,001 - 15,000 | 3,750 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 1 min | 15,001 - 50,000 | 5,000 | +| Per APP Per Tenant | [Resource Units](#resource-units) | 1 min | 50,000+ | 6,250 | +| Per APP Per Tenant | Ingress | 1 H | no license bound | 400 GB | +| Per APP Per Tenant | Egress | 1 H | no license bound | 400 GB | +| Per APP Per Tenant | Specific Sharing APIs | 5 min | no license bound | 300 | -- Reduce the number of operations per request - -- Reduce the frequency of calls - -- Decorate your traffic so we know who you are (see section on traffic decoration best practice more on that below) +> [!NOTE] +> Displayed limits are default values. Microsoft may change these limits at any time. Your experience may vary -- Leverage the retry-after header - -If you do run into throttling, we require leveraging the retry-after header to ensure minimum delay till the throttle is removed. +### Other Limits + +| Category | Type of throttling | Time interval | Limit | +|-------------------------------|--------------------------------------|-------------------|-----------| +| SharePoint Embedded containers| [Resource Units](#resource-units) | 1 min | 3,000 | +| Per Site | Anonymous Link | 5 min | 3,000 | +| Per Site | Anonymous Egress (Download) | 2 H | 100 GB | +| Per Site | External sharing emails | 1 H | 200 | + +> [!NOTE] +> Displayed limits are default values. Microsoft may change these limits at any time. Your experience may vary + +## How to handle throttling? + +Below is a quick summary of the best practices to handle throttling: + +- Reduce the number of concurrent requests +- Avoid request spikes +- Choose [Microsoft Graph APIs](/graph) over CSOM and REST APIs when possible +- Use the `Retry-After` and `RateLimit` HTTP headers +- Decorate your traffic so we know who you are (see section on traffic decoration best practice, more on that below) +- Consider using [Graph Data Connect for SharePoint](https://techcommunity.microsoft.com/blog/microsoft_graph_data_connect_for_sharepo/links-about-microsoft-graph-data-connect-for-sharepoint/4069045) for broad site analytics +- Understand if [service prioritization in SharePoint](https://aka.ms/SharePointPrioritization) is the right fit for your scenario + +As stated earlier, [Microsoft Graph](/graph) is cloud born APIs that have the latest improvements and optimizations. In general, [Microsoft Graph](/graph) consumes fewer resources than CSOM and REST to achieve the same functionality. Hence, adopting [Microsoft Graph](/graph) can improve the application's performance and reduce throttling. + +If you do run into throttling, we require using the `Retry-After` HTTP header to ensure minimum delay until the throttle is removed. The `RateLimit` HTTP headers send you early signals when you're close to limits, and you can proactively reduce requests to avoid hitting the throttle. + +Delta with a token is the most efficient way to scan content in SharePoint, and we talk more in detail at the [best practices for scanning applications](https://aka.ms/ScanGuidance). To help applications that follow the guidance, we lower the resource unit cost of delta requests with a token to 1 resource unit, although it's a multi-item query. The delta request without a token is considered a multi-item query and costs 2 resource units per request. + +In [batching](/graph/json-batching), requests in a batch are evaluated individually by resource units. + +CSOM and REST don't have a predetermined resource unit cost, and they usually consume more resource units than [Microsoft Graph APIs](/graph) to achieve the same functionality. In addition to resource unit limits, CSOM and REST are also subject to other internal resource limits, so if applications call CSOM and REST, they may experience more throttling than the limits described in this document. We highly recommend you choose [Microsoft Graph APIs](/graph) over CSOM and REST APIs when possible. -Retry after is the fastest way to handle being throttled because SharePoint Online dynamically determines the right time to try again. In other words, aggressive retries work against you because even though the calls fail, they still accrue against your usage limits. Following the retry header will ensure the shortest delay. +Since application limits are in resource units, the actual request rate, such as requests per minute, depends on the application’s API choice and the corresponding API resource unit cost. In general, you can estimate the request rate using an average of 2 resource units per request, and divide resource unit limits by 2 to get the estimated request rate. -For information about ways to monitor your SharePoint Online activity, see [Diagnosing performance issues with SharePoint Online](https://support.office.com/article/3c364f9e-b9f6-4da4-a792-c8e8c8cd2e86). +Although each application has its limits within a tenant, and we allow tenants to run more than one application, multiple applications running against the same tenant share the same resource bucket, and in rare occurrences can cause rate limiting when too many applications send requests at the time. -For a broader discussion of throttling on the Microsoft Cloud, see [Throttling Pattern](https://msdn.microsoft.com/library/4baf5af2-32fc-47ab-8569-3e5c59a5ebd5.aspx). +### Retry-after header -## How to decorate your http traffic to avoid throttling? - +When applications experience throttling, SharePoint Online returns a `Retry-After` HTTP header in the request indicating how long in seconds the calling application should wait before retrying or making a new request. -To ensure and maintain high-availability, some traffic may be throttled. Throttling happens when system health is at stake and one of the criteria used for throttling is traffic decoration, which impacts directly on the prioritization of the traffic. Well decorated traffic will be prioritized over traffic which is not properly decorated. - -What is definition of undecorated traffic? +Honoring the `Retry-After` HTTP header is the fastest way to handle being throttled because SharePoint Online dynamically determines the right time to try again. -- Traffic is undecorated if there is no AppID/AppTitle and User Agent string in CSOM or REST API call to SharePoint Online. The User Agent string should be in a specific format as described below. +Throttled requests count towards usage limits, so failure to honor `Retry-After` may result in more throttling. In other words, aggressive retries work against calling applications because even though the calls fail, they still count toward usage limits. Honoring the `Retry-After` HTTP header will ensure the shortest delay and reduce wasting quotas in throttled requests. + +### RateLimit headers - preview + +In addition to the `Retry-After` header in the response to throttled requests, SharePoint Online also returns the [IETF RateLimit headers](https://github.com/ietf-wg-httpapi/ratelimit-headers) for selected limits in certain conditions to help applications manage rate limiting. We recommend applications to take advantage of these headers to avoid hitting the throttle. + +- `RateLimit-Limit` contains the limit in the current time window. +- `RateLimit-Remaining` indicates the remaining quota in the current window. +- `RateLimit-Reset` indicates the number of seconds until the quota is refilled. + +> [!NOTE] +> These headers are currently in **beta** and subject to change. At the time when the headers were adopted, the IETF specification was in draft. The current implementation is based on the [draft-03](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers-03) of the IETF specification. There is the potential for changes when the specification is final, and we will adapt to those changes in the future. + +The `RateLimit` headers are returned on a **best-efforts** basis, so applications may not receive the headers under all conditions. Additionally, there are other limits that aren't presented in the `RateLimit` headers, so applications can get throttled even before reaching the limit described in the `RateLimit` headers. +Below is the list of limits that we support the `RateLimit` headers for. The policies and values are subject to change: + +| limit | Condition | limit value | Description | +|----------------------------|---------------------------|---------------|------------------------------------------------------------------------------------------------------------------| +| App 1-minute resource unit | Usage >= 80% of the limit | Resource unit | When an application consumes 80% or more of its app 1-minute limit, the limit, remaining, and reset are returned.| + +Below are some examples to help you understand the `RateLimit` headers: + +- An application has consumed 90% of its resource unit quota (1,080 out of 1,200), and its consumption is within all the limits that apply to it. The request succeeds and the `RateLimit` headers are returned. + + ``` + HTTP/1.1 200 Ok + RateLimit-Limit: 1200 + RateLimit-Remaining: 120 + RateLimit-Reset: 5 + ``` + +- An application has consumed 100% of its resource unit quota, so it gets throttled due to this policy. The request is throttled, and the `RateLimit` headers are returned. The `Retry-After` matches the `RateLimit-Reset`. There are instances where the `Retry-After` returns a smaller value. In such cases, the general rule of thumb is to honor the greater of the two values. + + ``` + HTTP/1.1 429 Too Many Requests + Retry-After: 31 + RateLimit-Limit: 1200 + RateLimit-Remaining: 0 + RateLimit-Reset: 31 + ``` + +- An application has consumed 90% of its resource unit quota, but its consumption has already reached other limits that the `RateLimit` headers don't support. In this case, the request is throttled and the `RateLimit` headers aren't returned to avoid confusion, although the condition to return the headers is satisfied. + + ``` + HTTP/1.1 429 Too Many Requests + Retry-After: 9 + ``` + +Additional information can be found in [Prevent throttling in your application by using RateLimit headers in SharePoint Online](https://devblogs.microsoft.com/microsoft365dev/prevent-throttling-in-your-application-by-using-ratelimit-headers-in-sharepoint-online/) + +### How to decorate your HTTP traffic? + +Well-decorated traffic will be prioritized over traffic that isn't properly decorated. + +What is the definition of undecorated traffic? + +- Traffic is undecorated if there's no AppID/AppTitle and User Agent string in API calls to SharePoint Online. The User-Agent string should be in a specific format as described below. +- If you're developing a web application executing in the browser, most modern browsers don't allow overwriting the User Agent string, and you don't need to implement it. What are the recommendations? -- If you have created an application, the recommendation is to register and use AppID and AppTitle – This will ensure the best overall experience and best path for any future issue resolution. Include also the User Agent string information as defined in following step. +- If you've created an application, the recommendation is to register and use AppID and AppTitle – This will ensure the best overall experience and best path for any future issue resolution. Include also the User Agent string information as defined in the following step. + + > [!NOTE] + > Refer to the [Microsoft identity documentation](/azure/active-directory/develop/), such as the [Quickstart: Register an application with the Microsoft identity platform](/azure/active-directory/develop/quickstart-register-app) page, for information on creating an Azure AD application. -- Make sure to include User Agent string in your API call to SharePoint with following naming convention +- Make sure to include the User-Agent string in your API call to SharePoint with the following naming convention -| Type | User Agent | Description | -|---|---|---| -| ISV Application | ISV|CompanyName|AppName/Version | Identify as ISV and include Company Name, App Name separated by a pipe character and then adding Version number separated with a slash character | +| Type | User Agent | Description | +|------------------------|----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| ISV Application | ISV|CompanyName|AppName/Version | Identify as ISV and include Company Name, App Name separated by a pipe character and then add Version number separated with a slash character | | Enterprise application | NONISV|CompanyName|AppName/Version | Identify as NONISV and include Company Name, App Name separated by a pipe character and then adding Version number separated with a slash character | -- If you are building your own JavaScript libraries, which are used to call SharePoint Online APIs, make sure that you include the User Agent information to your http request and potentially register your web application also as an Application, where suitable. +- If you're building your own JavaScript libraries, which are used to call SharePoint Online APIs, make sure that you include the User-Agent information to your HTTP request and potentially register your web application also as an Application, where suitable. > [!NOTE] -> Format of the user agent string is expected to follow [RFC2616](http://www.ietf.org/rfc/rfc2616.txt), so please follow up on the above guidance on the right separators. It is also fine to append existing user agent string with the requested information. +> The format of the user agent string is expected to follow [RFC2616](http://www.ietf.org/rfc/rfc2616.txt), so please follow up on the above guidance on the right separators. It is also fine to append the existing user agent string with the requested information. -> [!NOTE] -> If you are developing front end components executing in the browser, most of modern browsers don't allow overwriting the user agent string and you don't need to implement this. - -### Example of decorating traffic with User agent when using Client Side Object Model (CSOM) - -```cs -// Get access to source site -using (var ctx = new ClientContext("https://contoso.sharepoint.com/sites/team")) -{ - //Provide account and pwd for connecting to SharePoint Online - var passWord = new SecureString(); - foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c); - ctx.Credentials = new SharePointOnlineCredentials("contoso@contoso.onmicrosoft.com", passWord); - - // Add our User Agent information - ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e) - { - e.WebRequestExecutor.WebRequest.UserAgent = "NONISV|Contoso|GovernanceCheck/1.0"; - }; - - // Normal CSOM Call with custom User-Agent information - Web site = ctx.Web; - ctx.Load(site); - ctx.ExecuteQuery(); -} -``` - -### Example of decorating traffic with User agent when using REST APIs - -Following sample is in c# format, but the similar User Agent information is recommended to be used even for the JavaScript libraries used in the SharePoint Online pages. - -```cs -HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "/_api/web/lists"); -endpointRequest.Method = "GET"; -endpointRequest.UserAgent = "NONISV|Contoso|GovernanceCheck/1.0"; -endpointRequest.Accept = "application/json;odata=verbose"; -endpointRequest.Headers.Add("Authorization", "Bearer " + accessToken); -HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse(); -``` - -### CSOM Code sample: ExecuteQueryWithIncrementalRetry extension method -> [!NOTE] -> You'll need to use SharePoint Online CSOM version 16.1.8316.1200 (December 2018 version) or higher. - -Add this extension method in a static class and use `ExecuteQueryWithIncrementalRetry` instead of `ExecuteQuery` to make your code handle throttling requests. - -```cs -public static void ExecuteQueryWithIncrementalRetry(this ClientContext clientContext, int retryCount, int delay) -{ - int retryAttempts = 0; - int backoffInterval = delay; - int retryAfterInterval = 0; - bool retry = false; - ClientRequestWrapper wrapper = null; - if (retryCount <= 0) - throw new ArgumentException("Provide a retry count greater than zero."); - if (delay <= 0) - throw new ArgumentException("Provide a delay greater than zero."); - - // Do while retry attempt is less than retry count - while (retryAttempts < retryCount) - { - try - { - if (!retry) - { - clientContext.ExecuteQuery(); - return; - } - else - { - //increment the retry count - retryAttempts++; - - // retry the previous request using wrapper - if (wrapper != null && wrapper.Value != null) - { - clientContext.RetryQuery(wrapper.Value); - return; - } - // retry the previous request as normal - else - { - clientContext.ExecuteQuery(); - return; - } - } - } - catch (WebException ex) - { - var response = ex.Response as HttpWebResponse; - // Check if request was throttled - http status code 429 - // Check is request failed due to server unavailable - http status code 503 - if (response != null && (response.StatusCode == (HttpStatusCode)429 || response.StatusCode == (HttpStatusCode)503)) - { - wrapper = (ClientRequestWrapper)ex.Data["ClientRequest"]; - retry = true; - - // Determine the retry after value - use the retry-after header when available - string retryAfterHeader = response.GetResponseHeader("Retry-After"); - if (!string.IsNullOrEmpty(retryAfterHeader)) - { - if (!Int32.TryParse(retryAfterHeader, out retryAfterInterval)) - { - retryAfterInterval = backoffInterval; - } - } - else - { - retryAfterInterval = backoffInterval; - } - - // Delay for the requested seconds - Thread.Sleep(retryAfterInterval * 1000); - - // Increase counters - backoffInterval = backoffInterval * 2; - } - else - { - throw; - } - } - } - throw new MaximumRetryAttemptedException($"Maximum retry attempts {retryCount}, has be attempted."); -} - -[Serializable] -public class MaximumRetryAttemptedException : Exception -{ - public MaximumRetryAttemptedException(string message) : base(message) { } -} -``` +## Common throttling scenarios in SharePoint Online + +The most common causes of per-user throttling in SharePoint Online are client-side object model (CSOM) or Representational State Transfer (REST) code that performs too many actions too frequently. + +- **Sporadic traffic** + + Constant load or repetitive complex queries against SharePoint Online must be optimized for low impact. Failing to follow [best practices for scanning applications](https://aka.ms/ScanGuidance) that process files in bulk will likely result in throttling. These apps include sync engines, backup providers, search indexers, classification engines, data loss prevention tools, and any other tool, that attempts to reason over the entirety of data and apply changes to it. + +- **Overwhelming traffic** + + A single process dramatically exceeds throttling limits, continually, over a long period. + + - You used web services to build a tool to synchronize user profile properties. The tool updates user profile properties based on information from your line-of-business (LOB) human resources (HR) system. The tool makes calls at too high a frequency. + - You're running a load-testing script on SharePoint Online and you get throttled. Load testing isn't allowed on SharePoint Online. + - You customized your team site on SharePoint Online, for example, by adding a status indicator on the Home page. This status indicator updates frequently, which causes the page to make too many calls to the SharePoint Online service - this triggered throttling. + - Running the OneDrive Sync client while also running migration applications or applications that crawl sites and write back data can result in high request volumes that may trigger throttling. + +- **Unsupported use cases** + + Unsupported use of SharePoint Online may result in throttling. Using SharePoint and OneDrive as an intermediary service between Microsoft 365 and another repository is an example of an unsupported use case. + +- **Creating multiple AppIDs for the same application** + + Don't create separate AppIDs where the applications essentially perform the same operations, such as backup or data loss prevention. Applications running against the same tenant ultimately share the same resources as the tenant. Historically, some applications have tried this approach to get around the application throttling but ended up exhausting the tenant’s resource and causing multiple applications to be throttled in the tenant. + +## Scenario specific limits + +### When using app-only authentication with Sites.Read.All permission + +When you're using SharePoint Online search APIs with app-only authentication and the app has **Sites.Read.All** permission (or stronger), the app will be registered with full permissions, and is allowed to query all your SharePoint Online content (including the user’s private OneDrive for Business content). + +To ensure the service remains fast and reliable, queries using such permission are throttled at 25 requests per second. The search query will return an HTTP 429 response. When waiting for throttling recovery, you should ensure to pause all search query requests you may be making to the service using a similar app-only permission. Making more calls while receiving throttle responses will extend the time it takes for your app to become unthrottled. + +### When searching using delegated user permissions + +Searching with delegated user permissions occurs when an application submits a search query request with the signed-in user's permissions. Examples of delegated requests are as follows: the search box on a SharePoint page, a search-based web part or custom application embedded on a SharePoint page, and a Power Automate workflow querying for item information. + +To ensure service stability, the service will throttle delegated user requests that exceed 10 requests per second per user. This per-user limit aggregates across all requests from all apps. If a single user sends more than 10 search query requests per second, an HTTP 429 is returned. The requesting application should wait the duration of the timeout specified in the response header before sending subsequent requests. When designing search-based applications, SharePoint pages, and workflows, implementors should make sure the page and application do not exceed 10 requests per second in aggregate and handle 429 throttling responses. For more information and guidance on page design and search optimization, see [Optimize search requests in SharePoint Online modern site pages](/microsoft-365/enterprise/modern-search-optimization) and [Use the Page Diagnostics tool for SharePoint Online](/microsoft-365/enterprise/page-diagnostics-for-spo). + +### When searching for people search results + +When searching using a result source that requests people results, we may throttle any requests exceeding an organization-wide limit of 25 requests per second. This limit applies to all SharePoint search CSOM and REST requests using either the out-of-the-box "Local People Results" result source or a custom people search result source. + +If you have applications or components that are causing your people search requests to get throttled, we recommend that you: + +1. Consider if the requests are necessary for your application. For example, if you're using a custom search site, that makes many simultaneous queries, check whether some of those requests can be removed without any significant impact on your organization's search experience. Alternatively, consider trying our modern people search experience in [Microsoft Search](/microsoftsearch/get-started-search-in-sharepoint-online) by searching from the [SharePoint](https://sharepoint.com/) start page. People search in Microsoft Search has been optimized for better performance and more relevant results. +1. Avoid making concurrent requests. For example, instead of issuing 10 requests all at once, issue them consecutively - only issue the next query after the previous one has been completed. You may need to consider caching these results if you need them quickly, for example of a page load. +1. Try consolidating the requests into a single query. For example, instead of making 10 simultaneous queries for `WorkEmail:user1@constoso.com`, `WorkEmail:user2@constoso.com`,..., `WorkEmail:user10@contoso.com`, try the single query, `WorkEmail:user1@constoso.com WorkEmail:user2@constoso.com ... WorkEmail:user10@contoso.com`. +1. Consider using the [Microsoft Graph API](/graph/search-concept-person) if a high-request-volume scenario (in excess of 25 requests per second) is truly necessary. + +### When accessing OneDrive sites + +When a client makes excessive attempts to access many OneDrive site collections that do not exist, we may throttle requests from that client's IP address. The client will receive an HTTP 429 response when accessing any OneDrive site collection during the throttling period. + +### Multi-Geo Customers and throttling + +When a customer enables throttling, each gets their own limits (usage measurement not shared across geos). For the limits that are dependant on licenses count, the total tenant user licenses count is used (total users across all geos). ## What should you do if you get blocked in SharePoint Online? - -Blocking is the most extreme form of throttling. We rarely ever block a tenant, unless we detect long-term, extremely excessive traffic that may threaten the overall health of the SharePoint Online service. We apply blocks to prevent excessive traffic from degrading the performance and reliability of SharePoint Online. A block - which is usually placed at the app or user level - prevents the offending process from running until you fix the problem. If we block your subscription, you must take action to modify the offending processes before the block can be removed. - -If we block your subscription we will notify you of the block in the Office 365 Message Center. The message describes what caused the block, provides guidance on how to resolve the offending issue, and tells you who to contact to get the block removed. +Blocking is the most extreme form of throttling. We rarely ever block a tenant unless we detect long-term, excessive traffic that may threaten the overall health of the SharePoint Online service. We apply blocks to prevent excessive traffic from degrading the performance and reliability of SharePoint Online. A block - which is placed at the app or user level - prevents the offending process from running until you fix the problem. If we block your subscription, you must take action to modify the offending processes before the block can be removed. + +If we block your subscription, we'll notify you of the block in the Office 365 Message Center. The message describes what caused the block, provides guidance on how to resolve the offending issue, and tells you who to contact to get the block removed. ## See also - -- [Diagnosing performance issues with SharePoint Online](https://support.office.com/article/3c364f9e-b9f6-4da4-a792-c8e8c8cd2e86) - -- [Capacity planning and load testing SharePoint Online](https://support.office.com/article/capacity-planning-and-load-testing-sharepoint-online-c932bd9b-fb9a-47ab-a330-6979d03688c0) - -- [GitHub: SharePoint Online Throttling code sample](https://github.com/OfficeDev/PnP/tree/dev/Samples/Core.Throttling) +- [Service Prioritization in SharePoint](https://aka.ms/SharePointPrioritization) +- [Diagnosing performance issues with SharePoint Online](https://support.office.com/article/3c364f9e-b9f6-4da4-a792-c8e8c8cd2e86) +- [Capacity planning and load testing SharePoint Online](https://support.office.com/article/capacity-planning-and-load-testing-sharepoint-online-c932bd9b-fb9a-47ab-a330-6979d03688c0) +- [Microsoft Graph dev center](/graph) +- [Microsoft Graph throttling guidance](/graph/throttling) +- [Prevent throttling in your application by using RateLimit headers in SharePoint Online](https://devblogs.microsoft.com/microsoft365dev/prevent-throttling-in-your-application-by-using-ratelimit-headers-in-sharepoint-online/) +- [Four options for site analytics](https://techcommunity.microsoft.com/blog/microsoft_graph_data_connect_for_sharepo/four-options-for-sharepoint-site-analytics/4076416) diff --git a/docs/general-development/how-to-back-up-and-restore-a-search-service-application-in-sharepoint-using.md b/docs/general-development/how-to-back-up-and-restore-a-search-service-application-in-sharepoint-using.md index 8c9e0a3f5..818bbb861 100644 --- a/docs/general-development/how-to-back-up-and-restore-a-search-service-application-in-sharepoint-using.md +++ b/docs/general-development/how-to-back-up-and-restore-a-search-service-application-in-sharepoint-using.md @@ -1,9 +1,9 @@ --- title: Back up and restore a search service application in SharePoint using VSS -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to back up and restore a search service application in SharePoint using VSS and provides prerequisites and steps. +ms.date: 06/09/2022 ms.assetid: 87ee28e6-8170-4dba-8c9d-f04ab9e632dc -localization_priority: Normal +ms.localizationpriority: medium --- @@ -144,7 +144,7 @@ The following procedures are intended to help developers with creating a backup/ 1. Perform backups of the SSA databases and the index by following these steps: 1. On the server with the SSA databases, execute the following command at a command line, where _destination backup folder_ is the full path of the folder for the backup files, _backup log file_ is the full path and name of the backup log file, and _SSA manifest file_ is the path and file name of the SSA manifest file. - ```shell + ```console betest.exe /v /b /d "destination backup folder" /s "backup log file" /x "SSA manifest file" ``` @@ -157,7 +157,7 @@ The following procedures are intended to help developers with creating a backup/ 1. Verify that the file is created. 1. On each server that has an index component, execute the following at a command line, where _destination backup folder_ is the full path of the folder for the backup files, _backup log file_ is the full path and name of the backup log file, and _index manifest file_ is the path and file name of the index manifest. - ```shell + ```console betest.exe /v /b /d "destination backup folder" /s "backup log file" /x "index manifest file" ``` @@ -177,7 +177,7 @@ The following procedures are intended to help developers with creating a backup/ 1. On the same server, execute the following at a command line to restore the SSA databases, where _destination backup folder_ is the full path of the folder for the backup files, _backup log file_ is the full path and name of the backup log file, and _SSA manifest file_ is the path and file name of the SSA manifest file. - ```shell + ```console betest.exe /v /r /d "destination backup folder" /s "backup log file" /x SSA_manifest_file ``` @@ -209,7 +209,7 @@ The following procedures are intended to help developers with creating a backup/ 1. On the same servers, execute the following at a command line, where _index manifest file_ is the path and file name of the index manifest that you created in the backup procedure. - ```shell + ```console betest.exe /v /r /d "destination backup folder" /s "backup log file" /x "index manifest file" ``` diff --git a/docs/general-development/how-to-back-up-and-restore-sharepoint-using-a-vss-requestor.md b/docs/general-development/how-to-back-up-and-restore-sharepoint-using-a-vss-requestor.md index 9feefdf56..045f47664 100644 --- a/docs/general-development/how-to-back-up-and-restore-sharepoint-using-a-vss-requestor.md +++ b/docs/general-development/how-to-back-up-and-restore-sharepoint-using-a-vss-requestor.md @@ -1,9 +1,9 @@ --- title: Back up and restore SharePoint using a VSS requestor -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to back up and restore using a Volume Shadow Copy Service (VSS) requestor for Microsoft SharePoint. +ms.date: 06/09/2022 ms.assetid: cab5ba90-bd23-4cec-82d7-529e3f86ba88 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/how-to-brand-snippets-by-using-css-in-sharepoint.md b/docs/general-development/how-to-brand-snippets-by-using-css-in-sharepoint.md index a3526b067..b72aa8ae3 100644 --- a/docs/general-development/how-to-brand-snippets-by-using-css-in-sharepoint.md +++ b/docs/general-development/how-to-brand-snippets-by-using-css-in-sharepoint.md @@ -1,14 +1,17 @@ --- title: Brand snippets by using CSS in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to style snippets by using CSS in SharePoint and provides example snippets with instructions on how to use them. +ms.date: 06/09/2022 ms.assetid: d18d07b6-1a6b-4589-a65c-932b67cef595 -localization_priority: Priority +ms.localizationpriority: high --- # Brand snippets by using CSS in SharePoint +> [!IMPORTANT] +> This extensibility option is **only** available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. We do not recommend using classic experience or these branding techniques anymore. + To style a snippet, you override the default styles with custom CSS. You can use CSS IDs and element selectors to override all the default styles applied to elements, or you can use an HTML editor or a tool such as the F12 developer tools in Internet Explorer to identify and override specific default styles. ## Introduction to styling snippets with CSS diff --git a/docs/general-development/how-to-build-and-deploy-workflow-custom-actions.md b/docs/general-development/how-to-build-and-deploy-workflow-custom-actions.md index d514c03b1..290823cc4 100644 --- a/docs/general-development/how-to-build-and-deploy-workflow-custom-actions.md +++ b/docs/general-development/how-to-build-and-deploy-workflow-custom-actions.md @@ -1,19 +1,20 @@ --- title: Build and deploy workflow custom actions -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to create custom workflow actions in SharePoint and provides an example that creates, packages, and deploys a custom activity. +ms.date: 06/09/2022 ms.assetid: 9d2fa681-30c2-4549-9df2-ea9ed757fda9 -localization_priority: Priority +ms.localizationpriority: high --- # Build and deploy workflow custom actions Learn how to model business processes whose requirements are not met by the existing library of workflow actions in SharePoint Designer by creating custom workflow actions in SharePoint. + SharePoint Designer provides a collection of workflow actions that are available through the Workflow Designer user interface (UI). Although the range of workflow actions that are included in SharePoint Designer) is extensive, it is nevertheless finite. In some cases, you may need to model a business process whose requirements are not met by the existing library of workflow actions that are available in SharePoint Designer. - - +> [!NOTE] +> SharePoint 2010 workflows have been retired since August 1, 2020 for new tenants and removed from existing tenants on November 1, 2020. If you’re using SharePoint 2010 workflows, we recommend migrating to Power Automate or other supported solutions. For more info, see [SharePoint 2010 workflow retirement](https://support.microsoft.com/office/sharepoint-2010-workflow-retirement-1ca3fff8-9985-410a-85aa-8120f626965f). Recognizing that business processes often have specialized requirements, SharePoint lets you create custom workflow actions. You can develop these custom actions by using Visual Studio, and then package and deploy them to SharePoint. At that point, the custom action becomes available to workflow authors in SharePoint Designer, exactly as if it were among the library of existing actions. This capability lets you customize the functionality in your workflow authoring environment to match any of your specialized business processes. diff --git a/docs/general-development/how-to-build-search-driven-mobile-apps-with-the-navigation-and-event-logging-res.md b/docs/general-development/how-to-build-search-driven-mobile-apps-with-the-navigation-and-event-logging-res.md index 80eb41f0c..a24fee190 100644 --- a/docs/general-development/how-to-build-search-driven-mobile-apps-with-the-navigation-and-event-logging-res.md +++ b/docs/general-development/how-to-build-search-driven-mobile-apps-with-the-navigation-and-event-logging-res.md @@ -1,9 +1,9 @@ --- title: Build search-driven mobile apps with the Navigation and Event Logging REST interfaces -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to build search-driven mobile apps for mobile devices that run on non-Windows operating systems. +ms.date: 06/09/2022 ms.assetid: 5b313130-500c-4ccf-80ea-b102f30e5afb -localization_priority: Normal +ms.localizationpriority: medium --- @@ -50,7 +50,7 @@ Typically the **Home** page is displayed when the app starts up. The **Home** pa -![Build search-driven mobile apps](../images/SP15_Buildsearch-drivenmobileappspages_home.gif) +![Diagram that shows the Mobile App communicating with a REST navigation HTTP call to Share Point, which gives a Navigation structure response back.](../images/SP15_Buildsearch-drivenmobileappspages_home.gif) @@ -92,7 +92,7 @@ The **Category** page displays many items in a selected category. Each item list -![Build search-driven mobile apps](../images/Buildsearch-drivenmobileappspages.gif) +![Diagram that shows the Mobile App communicating with a REST search query to Share Point, which gives the search results back.](../images/Buildsearch-drivenmobileappspages.gif) diff --git a/docs/general-development/how-to-catch-exceptions.md b/docs/general-development/how-to-catch-exceptions.md index 0211a16cb..e49b400fd 100644 --- a/docs/general-development/how-to-catch-exceptions.md +++ b/docs/general-development/how-to-catch-exceptions.md @@ -1,12 +1,12 @@ --- title: Catch exceptions +description: You place the sections of code that might throw exceptions in a try block and place code that handles exceptions in a catch block. The order of catch statements is important. When an exception occurs, it is passed up the stack and each catch block is given the opportunity to handle it. ms.date: 09/25/2017 keywords: errors,how to,howdoi,howto f1_keywords: - errors,how to,howdoi,howto -ms.prod: sharepoint ms.assetid: de5fdb67-201b-4d7a-90a8-99ab7e51ea4e -localization_priority: Normal +ms.localizationpriority: medium --- @@ -18,7 +18,7 @@ You place the sections of code that might throw exceptions in a try block and pl -```cs +```csharp catch (SoapException e) { @@ -41,7 +41,7 @@ End Try If no type-specific catch block exists, the exception is caught by a general catch block, if one exists. For example, you can catch general exceptions by adding the following code: -```cs +```csharp catch (Exception e) { @@ -63,7 +63,7 @@ You place catch blocks targeted to specific types of exceptions before a general ## Example -```cs +```csharp using System; using System.Text; diff --git a/docs/general-development/how-to-change-the-preview-page-in-sharepoint-design-manager.md b/docs/general-development/how-to-change-the-preview-page-in-sharepoint-design-manager.md index 171d814e8..9e0aa988f 100644 --- a/docs/general-development/how-to-change-the-preview-page-in-sharepoint-design-manager.md +++ b/docs/general-development/how-to-change-the-preview-page-in-sharepoint-design-manager.md @@ -1,13 +1,17 @@ --- title: Change the preview page in SharePoint Design Manager -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to set, create, and change the preview page in Design Manager in SharePoint, and provides additional resources. +ms.date: 06/09/2022 ms.assetid: e5dfd8df-65de-44fc-aa97-23b4685d33ee -localization_priority: Priority +ms.localizationpriority: high --- # Change the preview page in SharePoint Design Manager + +> [!IMPORTANT] +> This extensibility option is **only** available for classic SharePoint experiences. You cannot use this option with modern experiences in SharePoint Online, like with communication sites. We do not recommend using classic experience or these branding techniques anymore. + Learn how to set, create, and change the preview page in Design Manager in SharePoint. The preview page is the page of your site that you use to see how your design looks. You can set the preview page to be either a specific page within your site or a generic preview. If you choose the generic preview, you'll see your master page with only a placeholder for content. You'll also see a message in the banner that you're currently previewing the master page without any content. If you choose a specific page, you'll see the page content rendered with the master page and the appropriate page layout. diff --git a/docs/general-development/how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md b/docs/general-development/how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md index 8f3e86493..34bc54174 100644 --- a/docs/general-development/how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md +++ b/docs/general-development/how-to-configure-and-use-push-notifications-in-sharepoint-apps-for-windows.md @@ -1,1378 +1,1133 @@ --- title: Configure and use push notifications in SharePoint apps for Windows Phone -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Create a solution in SharePoint Server for sending push notifications and develop a Windows Phone app for receiving the notifications. +ms.date: 06/09/2022 ms.assetid: 68fa2138-86d9-4e35-9c7c-5cd292087b80 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Configure and use push notifications in SharePoint apps for Windows Phone Create a solution in SharePoint Server for sending push notifications and develop a Windows Phone app for receiving the notifications. + Using the Microsoft Push Notification Service (MPNS), Windows Phone apps can receive notifications through the Internet of events triggered on Microsoft SharePoint Server. The phone app doesn't have to poll the server for changes to, for example, the items in a list on which the phone app is based. The app can be registered to receive notifications from the server, and an event receiver can initiate a notification and send it to the receiving app for handling. The push notification is relayed to Windows Phone devices by MPNS. - - - Windows Phone 7 doesn't support running multiple apps simultaneously. Other than the components of the Windows Phone operating system (OS) itself, only one app can be running on the phone at a time. An event relevant to a given phone app might occur (such as, for example, a list item being added to a list) when the app isn't running in the foreground on the phone (that is, when the app is tombstoned or closed). You could develop a background service on the phone with a periodic task that might check for changes to the list on the server, but this approach would consume resources (such as network bandwidth and battery power) on the phone. With MPNS and the components that support notifications built into the Windows Phone 7 OS, the phone itself can receive a notification relevant to the context of a given app—even when that app isn't running—and the user can be given the opportunity to start the relevant app in response to the notification. (For more information about push notifications, see [Push Notifications Overview for Windows Phone](https://msdn.microsoft.com/library/ff402558%28VS.92%29.aspx) in the MSDN Library.) -In this topic, you create a server-side solution for sending push notifications to a phone app based on a change in the list on which the app is based. You will then create the phone app for receiving these notifications. - - - +In this topic, you create a server-side solution for sending push notifications to a phone app based on a change in the list on which the app is based. You will then create the phone app for receiving these notifications. ## Create a server-side solution to send push notifications based on a list item event - The server-side solution can be either a SharePoint app deployed in an isolated **SPWeb** object, or a SharePoint farm solution packaged as a SharePoint solution package (that is, a .wsp file) that contains a Web-scoped Feature. In the procedures in this section, you will develop a simple SharePoint solution that creates a target list to be used by a Windows Phone app and that activates the push notification mechanism on the server. In the subsequent section, you will develop the Windows Phone app for receiving notifications from the server-side solution. - - - ### To create the server-side project - 1. Start Visual Studio 2012 by using the **Run as Administrator** option. - - -2. Choose **File**, **New**, **Project**. - +1. Choose **File**, **New**, **Project**. + The **New Project** dialog box appears. - - -3. In the **New Project** dialog box, expand the **SharePoint** node under **Visual C#**, and then choose the **15** node. - - -4. In the **Templates** pane, select **SharePoint Project** and specify a name for the project, such asPushNotificationsList. - - -5. Choose the **OK** button. The SharePoint Customization Wizard appears. This wizard enables you to select the target site for developing and debugging the project and the trust level of the solution. - - -6. Specify the URL of a SharePoint Server site. Select a site that you will be able to use later in the development of the SharePoint list app for Windows Phone. - - -7. Select **Deploy as a farm solution**, and then click **Finish** to create the project. - - + +1. In the **New Project** dialog box, expand the **SharePoint** node under **Visual C#**, and then choose the **15** node. +1. In the **Templates** pane, select **SharePoint Project** and specify a name for the project, such asPushNotificationsList. +1. Choose the **OK** button. The SharePoint Customization Wizard appears. This wizard enables you to select the target site for developing and debugging the project and the trust level of the solution. +1. Specify the URL of a SharePoint Server site. Select a site that you will be able to use later in the development of the SharePoint list app for Windows Phone. +1. Select **Deploy as a farm solution**, and then click **Finish** to create the project. + Next, add a class file to the project and create a couple of classes to encapsulate and manage push notifications. - - - ### To create the classes for managing push notifications - 1. In **Solution Explorer**, choose the node representing the project (named PushNotificationsList if you follow the naming convention used in these procedures). - - -2. On the **Project** menu, choose **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. - - -3. Specify PushNotification.cs as the name of the file and click **Add**. The class file is added to the solution and opened for editing. - - -4. Replace the contents of the file with the following code. - -```cs - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using Microsoft.SharePoint; - -namespace PushNotificationsList -{ - internal static class WP7Constants +1. On the **Project** menu, choose **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. +1. Specify PushNotification.cs as the name of the file and click **Add**. The class file is added to the solution and opened for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using Microsoft.SharePoint; + + namespace PushNotificationsList { - internal static readonly string[] WP_RESPONSE_HEADERS = - { - "X-MessageID", - "X-DeviceConnectionStatus", - "X-SubscriptionStatus", - "X-NotificationStatus" - }; - } - - public enum TileIntervalValuesEnum - { - ImmediateTile = 1, - Delay450SecondsTile = 11, - Delay900SecondsTile = 21, - } - - public enum ToastIntervalValuesEnum - { - ImmediateToast = 2, - Delay450SecondsToast = 12, - Delay900SecondsToast = 22, - } + internal static class WP7Constants + { + internal static readonly string[] WP_RESPONSE_HEADERS = + { + "X-MessageID", + "X-DeviceConnectionStatus", + "X-SubscriptionStatus", + "X-NotificationStatus" + }; + } - public enum RawIntervalValuesEnum - { - ImmediateRaw = 3, - Delay450SecondsRaw = 13, - Delay900SecondsRaw = 23 - } + public enum TileIntervalValuesEnum + { + ImmediateTile = 1, + Delay450SecondsTile = 11, + Delay900SecondsTile = 21, + } - public enum NotificationTypeEnum - { - Tile = 1, - Toast = 2, - Raw = 3 - } + public enum ToastIntervalValuesEnum + { + ImmediateToast = 2, + Delay450SecondsToast = 12, + Delay900SecondsToast = 22, + } - class PushNotification - { - public PushNotificationResponse PushToast(SPPushNotificationSubscriber subscriber, string toastTitle, string toastMessage, string toastParam, ToastIntervalValuesEnum intervalValue) + public enum RawIntervalValuesEnum { - // Construct toast notification message from parameter values. - string toastNotification = "" + - "" + - "" + - "" + toastTitle + "" + - "" + toastMessage + "" + - "" + toastParam + "" + - " " + - ""; - - return SendPushNotification(NotificationTypeEnum.Toast, subscriber, toastNotification, (int)intervalValue); + ImmediateRaw = 3, + Delay450SecondsRaw = 13, + Delay900SecondsRaw = 23 } - public PushNotificationResponse PushRaw(SPPushNotificationSubscriber subscriber, string rawMessage, RawIntervalValuesEnum intervalValue) + public enum NotificationTypeEnum { - return SendPushNotification(NotificationTypeEnum.Raw, subscriber, rawMessage, (int)intervalValue); + Tile = 1, + Toast = 2, + Raw = 3 } - private PushNotificationResponse SendPushNotification(NotificationTypeEnum notificationType, SPPushNotificationSubscriber subscriber, string message, int intervalValue) + class PushNotification { - // Create HTTP Web Request object. - string subscriptionUri = subscriber.ServiceToken; - HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri); - - // MPNS expects a byte array, so convert message accordingly. - byte[] notificationMessage = Encoding.Default.GetBytes(message); - - // Set the notification request properties. - sendNotificationRequest.Method = WebRequestMethods.Http.Post; - sendNotificationRequest.ContentLength = notificationMessage.Length; - sendNotificationRequest.ContentType = "text/xml"; - sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString()); - - switch (notificationType) - { - case NotificationTypeEnum.Tile: - sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token"); - break; - case NotificationTypeEnum.Toast: - sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast"); - break; - case NotificationTypeEnum.Raw: - // A value for the X-WindowsPhone-Target header is not specified for raw notifications. - break; - } - - sendNotificationRequest.Headers.Add("X-NotificationClass", intervalValue.ToString()); - - // Merge byte array payload with headers. - using (Stream requestStream = sendNotificationRequest.GetRequestStream()) + public PushNotificationResponse PushToast(SPPushNotificationSubscriber subscriber, string toastTitle, string toastMessage, string toastParam, ToastIntervalValuesEnum intervalValue) { - requestStream.Write(notificationMessage, 0, notificationMessage.Length); + // Construct toast notification message from parameter values. + string toastNotification = "" + + "" + + "" + + "" + toastTitle + "" + + "" + toastMessage + "" + + "" + toastParam + "" + + " " + + ""; + + return SendPushNotification(NotificationTypeEnum.Toast, subscriber, toastNotification, (int)intervalValue); } - string statCode = string.Empty; - PushNotificationResponse notificationResponse; - - try + public PushNotificationResponse PushRaw(SPPushNotificationSubscriber subscriber, string rawMessage, RawIntervalValuesEnum intervalValue) { - // Send the notification and get the response. - HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse(); - statCode = Enum.GetName(typeof(HttpStatusCode), response.StatusCode); - - // Create PushNotificationResponse object. - notificationResponse = new PushNotificationResponse((int)intervalValue, subscriber.ServiceToken); - notificationResponse.StatusCode = statCode; - foreach (string header in WP7Constants.WP_RESPONSE_HEADERS) - { - notificationResponse.Properties[header] = response.Headers[header]; - } + return SendPushNotification(NotificationTypeEnum.Raw, subscriber, rawMessage, (int)intervalValue); } - catch (Exception ex) + + private PushNotificationResponse SendPushNotification(NotificationTypeEnum notificationType, SPPushNotificationSubscriber subscriber, string message, int intervalValue) { - statCode = ex.Message; - notificationResponse = new PushNotificationResponse((int)intervalValue, subscriber.ServiceToken); - notificationResponse.StatusCode = statCode; - } + // Create HTTP Web Request object. + string subscriptionUri = subscriber.ServiceToken; + HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri); - return notificationResponse; - } - } + // MPNS expects a byte array, so convert message accordingly. + byte[] notificationMessage = Encoding.Default.GetBytes(message); - /// - /// Object used for returning notification request results. - /// - class PushNotificationResponse - { - private DateTime timestamp; - private int notificationIntervalValue; - private string statusCode = string.Empty; - private string serviceToken; - private Dictionary properties; + // Set the notification request properties. + sendNotificationRequest.Method = WebRequestMethods.Http.Post; + sendNotificationRequest.ContentLength = notificationMessage.Length; + sendNotificationRequest.ContentType = "text/xml"; + sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString()); - public PushNotificationResponse(int numericalIntervalValue, string srvcToken) - { - timestamp = DateTime.UtcNow; - notificationIntervalValue = numericalIntervalValue; - serviceToken = srvcToken; - properties = new Dictionary(); - } + switch (notificationType) + { + case NotificationTypeEnum.Tile: + sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token"); + break; + case NotificationTypeEnum.Toast: + sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast"); + break; + case NotificationTypeEnum.Raw: + // A value for the X-WindowsPhone-Target header is not specified for raw notifications. + break; + } - public DateTime TimeStamp - { - get { return timestamp; } - } + sendNotificationRequest.Headers.Add("X-NotificationClass", intervalValue.ToString()); - public int NotificationIntervalValue - { - get { return notificationIntervalValue; } - } + // Merge byte array payload with headers. + using (Stream requestStream = sendNotificationRequest.GetRequestStream()) + { + requestStream.Write(notificationMessage, 0, notificationMessage.Length); + } - public string StatusCode - { - get { return statusCode; } - set { statusCode = value; } - } + string statCode = string.Empty; + PushNotificationResponse notificationResponse; - public string ServiceToken - { - get { return serviceToken; } + try + { + // Send the notification and get the response. + HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse(); + statCode = Enum.GetName(typeof(HttpStatusCode), response.StatusCode); + + // Create PushNotificationResponse object. + notificationResponse = new PushNotificationResponse((int)intervalValue, subscriber.ServiceToken); + notificationResponse.StatusCode = statCode; + foreach (string header in WP7Constants.WP_RESPONSE_HEADERS) + { + notificationResponse.Properties[header] = response.Headers[header]; + } + } + catch (Exception ex) + { + statCode = ex.Message; + notificationResponse = new PushNotificationResponse((int)intervalValue, subscriber.ServiceToken); + notificationResponse.StatusCode = statCode; + } + + return notificationResponse; + } } - public Dictionary Properties + /// + /// Object used for returning notification request results. + /// + class PushNotificationResponse { - get { return properties; } + private DateTime timestamp; + private int notificationIntervalValue; + private string statusCode = string.Empty; + private string serviceToken; + private Dictionary properties; + + public PushNotificationResponse(int numericalIntervalValue, string srvcToken) + { + timestamp = DateTime.UtcNow; + notificationIntervalValue = numericalIntervalValue; + serviceToken = srvcToken; + properties = new Dictionary(); + } + + public DateTime TimeStamp + { + get { return timestamp; } + } + + public int NotificationIntervalValue + { + get { return notificationIntervalValue; } + } + + public string StatusCode + { + get { return statusCode; } + set { statusCode = value; } + } + + public string ServiceToken + { + get { return serviceToken; } + } + + public Dictionary Properties + { + get { return properties; } + } } } -} -``` + ``` + +1. Save the file. -5. Save the file. - - In this code, the **PushToast** and **PushRaw** methods take parameter arguments appropriate for the given type of notification to send, process those arguments, and then call the **SendPushNotification** method, which does the work of sending the notification using the Microsoft Push Notification Service. (In this sample code, a method for sending tile notifications has not been implemented.) The **PushNotificationResponse** class is simply a mechanism for encapsulating the result received from the notification request. Here, the class adds some information to the object (cast as an **HttpWebResponse** object) returned by the **GetResponse** method of the **HttpWebRequest** object. The event receiver you create in the following procedure uses this **PushNotificationResponse** class to update a notifications results list on the server. - - - + Now create an event receiver class that will send push notifications to devices that have been registered to receive them. (You will bind this event receiver to the Jobs list that is created in a later procedure.) - - - ### To create the event receiver class for a list - 1. In **Solution Explorer**, choose the node representing the project. - - -2. On the **Project** menu, click **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. - - -3. Specify ListItemEventReceiver.cs as the name of the file and click **Add**. The class file is added to the solution and opened for editing. - - -4. Replace the contents of the file with the following code. - -```cs - -using System; -using System.Security.Permissions; -using System.Text; -using Microsoft.SharePoint; -using Microsoft.SharePoint.Utilities; - -namespace PushNotificationsList -{ - /// - /// List Item Events - /// - public class ListItemEventReceiver : SPItemEventReceiver +1. On the **Project** menu, click **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. +1. Specify ListItemEventReceiver.cs as the name of the file and click **Add**. The class file is added to the solution and opened for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using System.Security.Permissions; + using System.Text; + using Microsoft.SharePoint; + using Microsoft.SharePoint.Utilities; + + namespace PushNotificationsList { - internal static string ResultsList = "Push Notification Results"; - /// - /// An item was added. + /// List Item Events /// - public override void ItemAdded(SPItemEventProperties properties) + public class ListItemEventReceiver : SPItemEventReceiver { - SPWeb spWeb = properties.Web; - SPPushNotificationSubscriberCollection pushSubscribers = spWeb.PushNotificationSubscribers; - PushNotification pushNotification = new PushNotification(); + internal static string ResultsList = "Push Notification Results"; - SPListItem listItem = properties.ListItem; + /// + /// An item was added. + /// + public override void ItemAdded(SPItemEventProperties properties) + { + SPWeb spWeb = properties.Web; + SPPushNotificationSubscriberCollection pushSubscribers = spWeb.PushNotificationSubscribers; + PushNotification pushNotification = new PushNotification(); - string jobAssignment = "[Unassigned]"; + SPListItem listItem = properties.ListItem; - // This event receiver is intended to be associated with a specific list, - // but the list may not have an "AssignedTo" field, so using try/catch here. - try - { - jobAssignment = listItem["AssignedTo"].ToString(); - } - catch { } + string jobAssignment = "[Unassigned]"; - PushNotificationResponse pushResponse = null; + // This event receiver is intended to be associated with a specific list, + // but the list may not have an "AssignedTo" field, so using try/catch here. + try + { + jobAssignment = listItem["AssignedTo"].ToString(); + } + catch { } - foreach (SPPushNotificationSubscriber ps in pushSubscribers) - { - // Send a toast notification to be displayed on subscribed phones on which the app is not running. - pushResponse = pushNotification.PushToast(ps, "New job for:", jobAssignment, string.Empty, ToastIntervalValuesEnum.ImmediateToast); - UpdateNotificationResultsList(spWeb, ps.User.Name, pushResponse); + PushNotificationResponse pushResponse = null; + + foreach (SPPushNotificationSubscriber ps in pushSubscribers) + { + // Send a toast notification to be displayed on subscribed phones on which the app is not running. + pushResponse = pushNotification.PushToast(ps, "New job for:", jobAssignment, string.Empty, ToastIntervalValuesEnum.ImmediateToast); + UpdateNotificationResultsList(spWeb, ps.User.Name, pushResponse); + + // Also send a raw notification to be displayed on subscribed phones on which the app is running when the item is added. + pushResponse = pushNotification.PushRaw(ps, string.Format("New job for: {0}", jobAssignment), RawIntervalValuesEnum.ImmediateRaw); + UpdateNotificationResultsList(spWeb, ps.User.Name, pushResponse); + } - // Also send a raw notification to be displayed on subscribed phones on which the app is running when the item is added. - pushResponse = pushNotification.PushRaw(ps, string.Format("New job for: {0}", jobAssignment), RawIntervalValuesEnum.ImmediateRaw); - UpdateNotificationResultsList(spWeb, ps.User.Name, pushResponse); + base.ItemAdded(properties); } - base.ItemAdded(properties); - } + private void UpdateNotificationResultsList(SPWeb spWeb, string subscriberName, PushNotificationResponse pushResponse) + { + SPList resultsList = spWeb.Lists.TryGetList(ResultsList); - private void UpdateNotificationResultsList(SPWeb spWeb, string subscriberName, PushNotificationResponse pushResponse) - { - SPList resultsList = spWeb.Lists.TryGetList(ResultsList); + if (resultsList == null) + return; - if (resultsList == null) - return; + try + { + SPListItem resultItem = resultsList.Items.Add(); + resultItem["Title"] = subscriberName; + resultItem["Notification Time"] = pushResponse.TimeStamp; + resultItem["Status Code"] = pushResponse.StatusCode; + resultItem["Service Token"] = pushResponse.ServiceToken; + + StringBuilder builder = new StringBuilder(); + foreach (string key in pushResponse.Properties.Keys) + { + builder.AppendFormat("{0}: {1}; ", key, pushResponse.Properties[key]); + } + resultItem["Headers"] = builder.ToString(); - try - { - SPListItem resultItem = resultsList.Items.Add(); - resultItem["Title"] = subscriberName; - resultItem["Notification Time"] = pushResponse.TimeStamp; - resultItem["Status Code"] = pushResponse.StatusCode; - resultItem["Service Token"] = pushResponse.ServiceToken; - - StringBuilder builder = new StringBuilder(); - foreach (string key in pushResponse.Properties.Keys) + resultItem["Interval Value"] = pushResponse.NotificationIntervalValue; + resultItem.Update(); + } + catch { - builder.AppendFormat("{0}: {1}; ", key, pushResponse.Properties[key]); + // Could log to ULS here if adding list item fails. } - resultItem["Headers"] = builder.ToString(); - - resultItem["Interval Value"] = pushResponse.NotificationIntervalValue; - resultItem.Update(); - } - catch - { - // Could log to ULS here if adding list item fails. } } } -} -``` + ``` + +1. Save the file. -5. Save the file. - - In this code, after an item is added to the list to which the event receiver is bound, push notifications are sent to subscribers that have registered to receive notifications. The value of the AssignedTo field from the added list item is included in the notification message sent to subscribers. For the toast notification, the values of the **toastTitle** parameter (for the **PushToast** method defined in the preceding procedure) and the **toastMessage** parameter are set. These values correspond to the **Text1** and **Text2** properties in the XML schema that defines toast notifications. - - - + An empty string is simply being passed as the value of the **toastParam** parameter, which corresponds to the **Param** property in the XML schema for toast notifications. You could use this parameter to specify, for example, a page of the phone app to open when the user clicks the notification in the phone. In the sample phone app developed later in this topic for receiving these notifications from the server, the **Param** property is not used. The List form (List.xaml) in the app is simply opened when the user clicks the notification. - + > [!NOTE] > The **Param** property for toast notifications is supported only in Windows Phone OS version 7.1 or greater. - - - For the raw notification in this sample, a string is passed that contains the value of the AssignedTo field from the added list item. - - - + Note that the toast notification will be displayed on subscribed phones (if the phone app for which the notification is intended is not running), and the message displayed will be truncated if it is longer than approximately 41 characters. Raw notifications in MPNS are limited to 1024 bytes (1 kilobyte). (The exact number of characters that can be sent depends on the kind of encoding used, such as UTF-8). Tile notifications are also subject to size limitations. Large amounts of data can't be sent using any of the notifications types. The best use of these notifications is not as a mechanism for transferring data, but as a way to send short messages to subscribed phones so that certain actions can be taken on the phone. Those actions, such as refreshing a list on the phone with data from the server, may involve larger amounts of data, depending on the design of the Windows Phone app. - - - + The **PushNotificationResponse** object that is returned from a notification request is passed to the **UpdateNotificationResultsList** method. This method adds information about the request to a SharePoint list named Push Notification Results (if the list exists). This is simply a demonstration of one way to use the returned object. You can put the returned object to more sophisticated uses in a production solution. You might, for example, examine the returned object for particular status codes when a notification is sent to a given user (such as the user designated for the assignment in the AssignedTo field) and take the appropriate action. In a production application, you probably wouldn't store all of this information in a list on the server. The information is being stored here to help you understand the properties associated with MPNS notifications. - - - + Next, you create a simple SharePoint list, named Jobs, that contains a job category, a description of a job, and the person to whom the job is assigned. Also, you create an auxiliary list, named Push Notification Results, for storing information related to notification requests sent to subscribing phones. - - - + In the following procedure, you create a class, **ListCreator**, that includes a **CreateJobsList** method for creating and configuring the Jobs list when the solution is activated on the server. The class also adds the **ItemAdded** event receiver (created earlier in the **ListItemEventReceiver** class) to the **EventReceivers** collection associated with the list. The **ListCreator** class also includes a method for creating the Push Notification Results SharePoint list. - - - ### To create a class for adding and configuring the lists - 1. In **Solution Explorer**, choose the node representing the project (again, named PushNotificationsList if you follow the naming convention used in these procedures). - - -2. On the **Project** menu, click **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. - - -3. Specify ListCreator.cs as the name of the file and click **Add**. The class file is added to the solution and opened for editing. - - -4. Replace the contents of the file with the following code. - -```cs - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml; -using Microsoft.SharePoint; - -namespace PushNotificationsList -{ - class ListCreator +1. On the **Project** menu, click **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. +1. Specify ListCreator.cs as the name of the file and click **Add**. The class file is added to the solution and opened for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Xml; + using Microsoft.SharePoint; + + namespace PushNotificationsList { - internal void CreateJobsList(SPWeb spWeb) + class ListCreator { - string listTitle = "Jobs"; - string listDescription = "List of jobs and assignments."; - Dictionary columns = new Dictionary(); - - // The "Title" column will be added based on the GenericList template. That field - // will be used as the category name for the job (e.g., Shopping), so only need to add - // the remaining fields. - columns.Add("Description", SPFieldType.Text); - columns.Add("AssignedTo", SPFieldType.Text); - - // Creating list (or retrieving GUID for list if it already exists). - Guid listId = CreateCustomList(spWeb, listTitle, listDescription, columns, false); - if (listId.Equals(Guid.Empty)) - return; + internal void CreateJobsList(SPWeb spWeb) + { + string listTitle = "Jobs"; + string listDescription = "List of jobs and assignments."; + Dictionary columns = new Dictionary(); - SPList list = spWeb.Lists[listId]; + // The "Title" column will be added based on the GenericList template. That field + // will be used as the category name for the job (e.g., Shopping), so only need to add + // the remaining fields. + columns.Add("Description", SPFieldType.Text); + columns.Add("AssignedTo", SPFieldType.Text); - // Add event receiver (if the current Jobs list is not already associated with the receiver). - bool ReceiverExists = false; - string receiverClassName = "PushNotificationsList.ListItemEventReceiver"; + // Creating list (or retrieving GUID for list if it already exists). + Guid listId = CreateCustomList(spWeb, listTitle, listDescription, columns, false); + if (listId.Equals(Guid.Empty)) + return; - for (int i = 0; i < list.EventReceivers.Count; i++) - { - SPEventReceiverDefinition rd = list.EventReceivers[i]; - if (rd.Class == receiverClassName && rd.Type == SPEventReceiverType.ItemAdded) + SPList list = spWeb.Lists[listId]; + + // Add event receiver (if the current Jobs list is not already associated with the receiver). + bool ReceiverExists = false; + string receiverClassName = "PushNotificationsList.ListItemEventReceiver"; + + for (int i = 0; i < list.EventReceivers.Count; i++) { - ReceiverExists = true; - break; + SPEventReceiverDefinition rd = list.EventReceivers[i]; + if (rd.Class == receiverClassName && rd.Type == SPEventReceiverType.ItemAdded) + { + ReceiverExists = true; + break; + } + } + + if (ReceiverExists == false) + { + SPEventReceiverDefinition eventReceiver = list.EventReceivers.Add(); + // Must specify information here for this specific assembly. + eventReceiver.Assembly = "PushNotificationsList, + Version=1.0.0.0, Culture=Neutral, + PublicKeyToken=[YOUR TOKEN VALUE HERE]"; + eventReceiver.Class = receiverClassName; + eventReceiver.Name = "ItemAdded Event"; + eventReceiver.Type = SPEventReceiverType.ItemAdded; + eventReceiver.SequenceNumber = 10000; + eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous; + eventReceiver.Update(); } } - if (ReceiverExists == false) + internal void CreateNotificationResultsList(SPWeb spWeb) { - SPEventReceiverDefinition eventReceiver = list.EventReceivers.Add(); - // Must specify information here for this specific assembly. - eventReceiver.Assembly = "PushNotificationsList, - Version=1.0.0.0, Culture=Neutral, - PublicKeyToken=[YOUR TOKEN VALUE HERE]"; - eventReceiver.Class = receiverClassName; - eventReceiver.Name = "ItemAdded Event"; - eventReceiver.Type = SPEventReceiverType.ItemAdded; - eventReceiver.SequenceNumber = 10000; - eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous; - eventReceiver.Update(); + string listTitle = "Push Notification Results"; + string listDescription = "List for results from push notification operations."; + + Dictionary columns = new Dictionary(); + columns.Add("Notification Time", SPFieldType.Text); + columns.Add("Status Code", SPFieldType.Text); + columns.Add("Service Token", SPFieldType.Text); + columns.Add("Headers", SPFieldType.Text); + columns.Add("Interval Value", SPFieldType.Integer); + + // Creating the list for storing notification results. + CreateCustomList(spWeb, listTitle, listDescription, columns, true); } - } - internal void CreateNotificationResultsList(SPWeb spWeb) - { - string listTitle = "Push Notification Results"; - string listDescription = "List for results from push notification operations."; - - Dictionary columns = new Dictionary(); - columns.Add("Notification Time", SPFieldType.Text); - columns.Add("Status Code", SPFieldType.Text); - columns.Add("Service Token", SPFieldType.Text); - columns.Add("Headers", SPFieldType.Text); - columns.Add("Interval Value", SPFieldType.Integer); - - // Creating the list for storing notification results. - CreateCustomList(spWeb, listTitle, listDescription, columns, true); - } - - /// - /// Creates a SharePoint list (based on the Generic List template). - /// - /// The target website for the list. - /// The title of the list. - /// A description for the list. - /// A Dictionary object containing field names and types. - /// Indicates whether to overwrite an existing list of the same name on the site. - /// A GUID for the created (or existing) list. - internal Guid CreateCustomList(SPWeb spWeb, string listTitle, string listDescription, Dictionary columns, bool replaceExistingList) - { - SPList list = spWeb.Lists.TryGetList(listTitle); - - if (list != null) + /// + /// Creates a SharePoint list (based on the Generic List template). + /// + /// The target website for the list. + /// The title of the list. + /// A description for the list. + /// A Dictionary object containing field names and types. + /// Indicates whether to overwrite an existing list of the same name on the site. + /// A GUID for the created (or existing) list. + internal Guid CreateCustomList(SPWeb spWeb, string listTitle, string listDescription, Dictionary columns, bool replaceExistingList) { - if (replaceExistingList == true) + SPList list = spWeb.Lists.TryGetList(listTitle); + + if (list != null) { - try + if (replaceExistingList == true) { - list.Delete(); + try + { + list.Delete(); + } + catch + { + return Guid.Empty; + } } - catch + else { - return Guid.Empty; + return list.ID; } } - else + + try { - return list.ID; - } - } + Guid listId = spWeb.Lists.Add(listTitle, listDescription, SPListTemplateType.GenericList); + list = spWeb.Lists[listId]; + SPView view = list.DefaultView; - try - { - Guid listId = spWeb.Lists.Add(listTitle, listDescription, SPListTemplateType.GenericList); - list = spWeb.Lists[listId]; - SPView view = list.DefaultView; + foreach (string key in columns.Keys) + { + list.Fields.Add(key, columns[key], false); + view.ViewFields.Add(key); + } - foreach (string key in columns.Keys) + list.Update(); + view.Update(); + + return listId; + } + catch { - list.Fields.Add(key, columns[key], false); - view.ViewFields.Add(key); + return Guid.Empty; } - - list.Update(); - view.Update(); - - return listId; - } - catch - { - return Guid.Empty; } } } -} -``` - + ``` Be sure to specify the appropriate Public Key Token value for particular your assembly. To add a tool to Visual Studio for getting the Public Key Token value for your assembly, see [How to: Create a Tool to Get the Public Key of an Assembly](https://msdn.microsoft.com/library/ee539398.aspx) in the MSDN Library. Note that you will have to compile your project at least once to be able to get the Public Key Token value for your output assembly. - - -5. Save the file. - - + +1. Save the file. + In this code, the **CreateJobsList** method of the **ListCreator** class creates the list (or gets the list if it exists on the server) and binds the event receiver created in an earlier procedure to the list by adding it to the **EventReceivers** class associated with the list. The **CreateNotificationResultsList** method creates the Push Notification Results list. - - - + Next you add a Feature to your project in order to perform initialization operations on the server when your solution is deployed and activated. You add an event receiver class to the Feature to handle the **FeatureActivated** and **FeatureDeactivating** events. - - - ### To add a Feature to your project - 1. In Visual Studio 2012, on the **View** menu, point to **Other Windows** and then click **Packaging Explorer**. - - -2. In the **Packaging Explorer**, right-click the node representing your project and click **Add Feature**. A new Feature (named "Feature1" by default) is added to your project, under a **Features** node (in **Solution Explorer**). - - -3. Now, in **Solution Explorer**, under the **Features** node, right-click the newly added Feature (that is, **Feature1**), and click **Add Event Receiver**. An event receiver class file (Feature1.EventReceiver.cs) is added to the Feature and opened for editing. - - -4. Within the implementation (demarcated by opening and closing braces) of the **Feature1EventReceiver** class, add the following code. - -```cs - -internal const string PushNotificationFeatureId = "41E1D4BF-B1A2-47F7-AB80-D5D6CBBA3092"; -``` +1. In the **Packaging Explorer**, right-click the node representing your project and click **Add Feature**. A new Feature (named "Feature1" by default) is added to your project, under a **Features** node (in **Solution Explorer**). +1. Now, in **Solution Explorer**, under the **Features** node, right-click the newly added Feature (that is, **Feature1**), and click **Add Event Receiver**. An event receiver class file (Feature1.EventReceiver.cs) is added to the Feature and opened for editing. +1. Within the implementation (demarcated by opening and closing braces) of the **Feature1EventReceiver** class, add the following code. + ```csharp + internal const string PushNotificationFeatureId = "41E1D4BF-B1A2-47F7-AB80-D5D6CBBA3092"; + ``` This string variable stores the identifier for the Push Notification Feature on the server. - - > **Tip:** - > You can obtain a list of unique identifiers for the Features on a SharePoint Server by executing the following Windows PowerShell cmdlet: > `Get-SPFeature | Sort -Property DisplayName`> The Push Notification Feature appears as "PhonePNSubscriber" in the results returned by this cmdlet. -5. The event receiver class file is created with some default method declarations for handling Feature events. The method declarations in the file are initially commented out. Replace the **FeatureActivated** method in the file with the following code. - -```cs - public override void FeatureActivated(SPFeatureReceiverProperties properties) -{ - base.FeatureActivated(properties); - SPWeb spWeb = (SPWeb)properties.Feature.Parent; - - ListCreator listCreator = new ListCreator(); - listCreator.CreateJobsList(spWeb); - listCreator.CreateNotificationResultsList(spWeb); - - // Then activate the Push Notification Feature on the server. - // The Push Notification Feature is not activated by default in a SharePoint Server installation. - spWeb.Features.Add(new Guid(PushNotificationFeatureId), false); -} -``` - -6. Replace the **FeatureDeactivating** method in the file with the following code. - -```cs - -public override void FeatureDeactivating(SPFeatureReceiverProperties properties) -{ - base.FeatureDeactivating(properties); - SPWeb spWeb = (SPWeb)properties.Feature.Parent; - - // Deactivate the Push Notification Feature on the server - // when the PushNotificationsList Feature is deactivated. - spWeb.Features.Remove(new Guid(PushNotificationFeatureId), false); -} -``` - -7. Save the file. - - + + > [!TIP] + > You can obtain a list of unique identifiers for the Features on a SharePoint Server by executing the following Windows PowerShell cmdlet: > `Get-SPFeature | Sort -Property DisplayName`> The Push Notification Feature appears as "PhonePNSubscriber" in the results returned by this cmdlet. + +1. The event receiver class file is created with some default method declarations for handling Feature events. The method declarations in the file are initially commented out. Replace the **FeatureActivated** method in the file with the following code. + + ```csharp + public override void FeatureActivated(SPFeatureReceiverProperties properties) + { + base.FeatureActivated(properties); + SPWeb spWeb = (SPWeb)properties.Feature.Parent; + + ListCreator listCreator = new ListCreator(); + listCreator.CreateJobsList(spWeb); + listCreator.CreateNotificationResultsList(spWeb); + + // Then activate the Push Notification Feature on the server. + // The Push Notification Feature is not activated by default in a SharePoint Server installation. + spWeb.Features.Add(new Guid(PushNotificationFeatureId), false); + } + ``` + +1. Replace the **FeatureDeactivating** method in the file with the following code. + + ```csharp + public override void FeatureDeactivating(SPFeatureReceiverProperties properties) + { + base.FeatureDeactivating(properties); + SPWeb spWeb = (SPWeb)properties.Feature.Parent; + + // Deactivate the Push Notification Feature on the server + // when the PushNotificationsList Feature is deactivated. + spWeb.Features.Remove(new Guid(PushNotificationFeatureId), false); + } + ``` + +1. Save the file. + In the implementation of the **FeatureActivated** event handler here, an instance of the **ListCreator** class is instantiated and its **CreateJobsList** and **CreateNotificationResultsList** methods are called, using the **SPWeb** where the Feature is deployed and activated as the location in which the lists will be created. In addition, because push notification functionality is not enabled by default in a standard installation of SharePoint Server, the event handler activates the Push Notification Feature on the server. In the **FeatureDeactivating** event handler, push notification functionality is deactivated when the application has been deactivated. It isn't necessary to handle this event. You may or may not want to deactivate push notifications on the server when the application is deactivated, depending on the circumstances of your installation and whether other applications on the target site make use of push notifications. - - - ## Create a Windows Phone SharePoint list app to receive push notifications - In this section, you create a Windows Phone app from the Windows Phone SharePoint List Application template, specifying the SharePoint list created in the preceding section as the target list for the app. You then develop a **Notifications** class for subscribing to push notifications, implementing handlers for notification events, and storing information related to notifications on the phone. You also add a XAML page to your app with controls to allow users to register or unregister for push notifications. - - - + To follow the procedures in this section, first perform the steps in the procedure described in [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) to create a Visual Studio project from the Windows Phone SharePoint List Application template, using the Jobs list created in the preceding section as the target SharePoint list for the project. For the purposes of the procedures in this section, it is assumed that the name specified for the project isSPListAppForNotifications. - - - ### To create the class for managing subscriptions and received notifications - 1. In **Solution Explorer**, choose the node representing the project (named SPListAppForNotifications). - - -2. On the **Project** menu, click **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. - - -3. Specify "Notifications.cs" as the name of the file and click **Add**. The class file is added to the solution and opened for editing. - - -4. Replace the contents of the file with the following code. - -```cs - -using System; -using System.Linq; -using System.Net; -using System.Windows; -using Microsoft.Phone.Notification; -using Microsoft.SharePoint.Client; -using System.Diagnostics; -using System.Collections.Generic; -using Microsoft.Phone.Shell; -using System.IO; -using System.IO.IsolatedStorage; - -namespace SPListAppForNotifications -{ - public class Notifications +1. On the **Project** menu, click **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. +1. Specify "Notifications.cs" as the name of the file and click **Add**. The class file is added to the solution and opened for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using System.Linq; + using System.Net; + using System.Windows; + using Microsoft.Phone.Notification; + using Microsoft.SharePoint.Client; + using System.Diagnostics; + using System.Collections.Generic; + using Microsoft.Phone.Shell; + using System.IO; + using System.IO.IsolatedStorage; + + namespace SPListAppForNotifications { - static HttpNotificationChannel httpChannel; - private const string RegStatusKey = "RegistrationStatus"; - public static string DeviceAppIdKey = "DeviceAppInstanceId"; - public static string ChannelName = "JobsListNotificationChannel"; - public static ClientContext Context { get; set; } - - public static void OpenNotificationChannel(bool isInitialRegistration) + public class Notifications { - try - { - // Get channel if it was created in a previous session of the app. - httpChannel = HttpNotificationChannel.Find(ChannelName); + static HttpNotificationChannel httpChannel; + private const string RegStatusKey = "RegistrationStatus"; + public static string DeviceAppIdKey = "DeviceAppInstanceId"; + public static string ChannelName = "JobsListNotificationChannel"; + public static ClientContext Context { get; set; } - // If channel is not found, create one. - if (httpChannel == null) + public static void OpenNotificationChannel(bool isInitialRegistration) + { + try { - httpChannel = new HttpNotificationChannel(ChannelName); + // Get channel if it was created in a previous session of the app. + httpChannel = HttpNotificationChannel.Find(ChannelName); - // Add event handlers. When the Open method is called, the ChannelUriUpdated event will fire. - // A call is made to the SubscribeToService method in the ChannelUriUpdated event handler. - AddChannelEventHandlers(); - httpChannel.Open(); - } - else - { - // The channel exists and is already open. Add handlers for channel events. - // The ChannelUriUpdated event won't fire in this case. - AddChannelEventHandlers(); + // If channel is not found, create one. + if (httpChannel == null) + { + httpChannel = new HttpNotificationChannel(ChannelName); - // If app instance is registering for first time - // (instead of just starting up again), then call SubscribeToService. - if (isInitialRegistration) + // Add event handlers. When the Open method is called, the ChannelUriUpdated event will fire. + // A call is made to the SubscribeToService method in the ChannelUriUpdated event handler. + AddChannelEventHandlers(); + httpChannel.Open(); + } + else { - SubscribeToService(); + // The channel exists and is already open. Add handlers for channel events. + // The ChannelUriUpdated event won't fire in this case. + AddChannelEventHandlers(); + + // If app instance is registering for first time + // (instead of just starting up again), then call SubscribeToService. + if (isInitialRegistration) + { + SubscribeToService(); + } } } + catch (Exception ex) + { + ShowMessage(ex.Message, "Error Opening Channel"); + CloseChannel(); + } } - catch (Exception ex) - { - ShowMessage(ex.Message, "Error Opening Channel"); - CloseChannel(); - } - } - - private static void AddChannelEventHandlers() - { - httpChannel.ChannelUriUpdated += new EventHandler(httpChannel_ChannelUriUpdated); - httpChannel.ErrorOccurred += new EventHandler(httpChannel_ExceptionOccurred); - httpChannel.ShellToastNotificationReceived += new EventHandler(httpChannel_ShellToastNotificationReceived); - httpChannel.HttpNotificationReceived += new EventHandler(httpChannel_HttpNotificationReceived); - } - - private static void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e) - { - UpdateChannelUriOnServer(); - SubscribeToService(); - } - - private static void httpChannel_ExceptionOccurred(object sender, NotificationChannelErrorEventArgs e) - { - // Simply showing the exception error. - ShowMessage(e.Message, "Channel Event Error"); - } - static void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e) - { - if (e.Collection != null) + private static void AddChannelEventHandlers() { - Dictionary collection = (Dictionary)e.Collection; - ShellToast toast = new ShellToast(); - toast.Title = collection["wp:Text1"]; - toast.Content = collection["wp:Text2"]; - - // Note that the Show method for a toast notification won't - // display the notification in the UI of the phone when the app - // that calls the method is running (as the foreground app on the phone). - // toast.Show(); - //Toast and Raw notification will be displayed if user is running the app. Be default only Toast notification - // will be displayed when the app is tombstoned - - // Showing the toast notification with the ShowMessage method. - ShowMessage(string.Format("Title: {0}\\r\\nContent: {1}", toast.Title, toast.Content), "Toast Notification"); + httpChannel.ChannelUriUpdated += new EventHandler(httpChannel_ChannelUriUpdated); + httpChannel.ErrorOccurred += new EventHandler(httpChannel_ExceptionOccurred); + httpChannel.ShellToastNotificationReceived += new EventHandler(httpChannel_ShellToastNotificationReceived); + httpChannel.HttpNotificationReceived += new EventHandler(httpChannel_HttpNotificationReceived); } - } - - static void httpChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e) - { - Stream messageStream = e.Notification.Body; - string message = string.Empty; - // Replacing NULL characters in stream. - using (var reader = new StreamReader(messageStream)) + private static void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e) { - message = reader.ReadToEnd().Replace('\\0', ' '); + UpdateChannelUriOnServer(); + SubscribeToService(); } - // Simply displaying the raw notification. - ShowMessage(message, "Raw Notification"); - } + private static void httpChannel_ExceptionOccurred(object sender, NotificationChannelErrorEventArgs e) + { + // Simply showing the exception error. + ShowMessage(e.Message, "Channel Event Error"); + } - private static void SubscribeToService() - { - Guid deviceAppInstanceId = GetSettingValue(DeviceAppIdKey, false); + static void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e) + { + if (e.Collection != null) + { + Dictionary collection = (Dictionary)e.Collection; + ShellToast toast = new ShellToast(); + toast.Title = collection["wp:Text1"]; + toast.Content = collection["wp:Text2"]; + + // Note that the Show method for a toast notification won't + // display the notification in the UI of the phone when the app + // that calls the method is running (as the foreground app on the phone). + // toast.Show(); + //Toast and Raw notification will be displayed if user is running the app. Be default only Toast notification + // will be displayed when the app is tombstoned + + // Showing the toast notification with the ShowMessage method. + ShowMessage(string.Format("Title: {0}\\r\\nContent: {1}", toast.Title, toast.Content), "Toast Notification"); + } + } - Context.Load(Context.Web, w => w.Title, w => w.Description); + static void httpChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e) + { + Stream messageStream = e.Notification.Body; + string message = string.Empty; - PushNotificationSubscriber pushSubscriber = Context.Web.RegisterPushNotificationSubscriber(deviceAppInstanceId, httpChannel.ChannelUri.AbsoluteUri); + // Replacing NULL characters in stream. + using (var reader = new StreamReader(messageStream)) + { + message = reader.ReadToEnd().Replace('\\0', ' '); + } - Context.Load(pushSubscriber); + // Simply displaying the raw notification. + ShowMessage(message, "Raw Notification"); + } - Context.ExecuteQueryAsync - ( - (object sender, ClientRequestSucceededEventArgs args) => - { - SetRegistrationStatus(true); + private static void SubscribeToService() + { + Guid deviceAppInstanceId = GetSettingValue(DeviceAppIdKey, false); - // Indicate that tile and toast notifications can be - // received by phone shell when phone app is not running. - if (!httpChannel.IsShellTileBound) - httpChannel.BindToShellTile(); + Context.Load(Context.Web, w => w.Title, w => w.Description); - if (!httpChannel.IsShellToastBound) - httpChannel.BindToShellToast(); + PushNotificationSubscriber pushSubscriber = Context.Web.RegisterPushNotificationSubscriber(deviceAppInstanceId, httpChannel.ChannelUri.AbsoluteUri); - ShowMessage( - string.Format("Subscriber successfully registered: {0}", pushSubscriber.User.LoginName), - "Success"); - }, - (object sender, ClientRequestFailedEventArgs args) => - { - ShowMessage(args.Exception.Message, "Error Subscribing"); - }); - } + Context.Load(pushSubscriber); - private static void UpdateChannelUriOnServer() - { - Guid deviceAppInstanceId = GetSettingValue(DeviceAppIdKey, false); + Context.ExecuteQueryAsync + ( + (object sender, ClientRequestSucceededEventArgs args) => + { + SetRegistrationStatus(true); - Context.Load(Context.Web, w => w.Title, w => w.Description); + // Indicate that tile and toast notifications can be + // received by phone shell when phone app is not running. + if (!httpChannel.IsShellTileBound) + httpChannel.BindToShellTile(); - PushNotificationSubscriber subscriber = Context.Web.GetPushNotificationSubscriber(deviceAppInstanceId); + if (!httpChannel.IsShellToastBound) + httpChannel.BindToShellToast(); - Context.Load(subscriber); + ShowMessage( + string.Format("Subscriber successfully registered: {0}", pushSubscriber.User.LoginName), + "Success"); + }, + (object sender, ClientRequestFailedEventArgs args) => + { + ShowMessage(args.Exception.Message, "Error Subscribing"); + }); + } - Context.ExecuteQueryAsync( - (object sender1, ClientRequestSucceededEventArgs args1) => - { - subscriber.ServiceToken = httpChannel.ChannelUri.AbsolutePath; - subscriber.Update(); - Context.ExecuteQueryAsync( - (object sender2, ClientRequestSucceededEventArgs args2) => - { - ShowMessage("Channel URI updated on server.", "Success"); - }, - (object sender2, ClientRequestFailedEventArgs args2) => - { - ShowMessage(args2.Exception.Message, "Error Upating Channel URI"); - }); - }, - (object sender1, ClientRequestFailedEventArgs args1) => - { - // This condition can be ignored. Getting to this point means the subscriber - // doesn't yet exist on the server, so updating the Channel URI is unnecessary. - //ShowMessage("Subscriber doesn't exist on server.", "DEBUG"); - }); - } + private static void UpdateChannelUriOnServer() + { + Guid deviceAppInstanceId = GetSettingValue(DeviceAppIdKey, false); - public static void UnSubscribe() - { - Context.Load(Context.Web, w => w.Title, w => w.Description); - Guid deviceAppInstanceId = GetSettingValue(DeviceAppIdKey, false); + Context.Load(Context.Web, w => w.Title, w => w.Description); - Context.Web.UnregisterPushNotificationSubscriber(deviceAppInstanceId); + PushNotificationSubscriber subscriber = Context.Web.GetPushNotificationSubscriber(deviceAppInstanceId); - Context.ExecuteQueryAsync - ( - (object sender, ClientRequestSucceededEventArgs args) => - { - CloseChannel(); - SetRegistrationStatus(false); - //SetInitializationStatus(false); - ShowMessage("Subscriber successfully unregistered.", "Success"); - }, - (object sender, ClientRequestFailedEventArgs args) => - { - ShowMessage(args.Exception.Message, "Error Unsubscribing"); - }); - } + Context.Load(subscriber); - public static void ClearSubscriptionStore() - { - Context.Load(Context.Web, w => w.Title, w => w.Description); - List subscriptionStore = Context.Web.Lists.GetByTitle("Push Notification Subscription Store"); - Context.Load(subscriptionStore); - ListItemCollection listItems = subscriptionStore.GetItems(new CamlQuery()); - Context.Load(listItems); - - Context.ExecuteQueryAsync - ( - (object sender1, ClientRequestSucceededEventArgs args1) => - { - foreach (ListItem listItem in listItems.ToList()) + Context.ExecuteQueryAsync( + (object sender1, ClientRequestSucceededEventArgs args1) => { - listItem.DeleteObject(); - } - Context.ExecuteQueryAsync( + subscriber.ServiceToken = httpChannel.ChannelUri.AbsolutePath; + subscriber.Update(); + Context.ExecuteQueryAsync( (object sender2, ClientRequestSucceededEventArgs args2) => - { - // Close channel if open and set registration status for current app instance. - CloseChannel(); - SetRegistrationStatus(false); - - ShowMessage("Subscriber store cleared.", "Success"); - }, + { + ShowMessage("Channel URI updated on server.", "Success"); + }, (object sender2, ClientRequestFailedEventArgs args2) => - { - ShowMessage(args2.Exception.Message, "Error Deleting Subscribers"); - }); - }, - (object sender1, ClientRequestFailedEventArgs args1) => - { - ShowMessage(args1.Exception.Message, "Error Loading Subscribers List"); - }); - } + { + ShowMessage(args2.Exception.Message, "Error Upating Channel URI"); + }); + }, + (object sender1, ClientRequestFailedEventArgs args1) => + { + // This condition can be ignored. Getting to this point means the subscriber + // doesn't yet exist on the server, so updating the Channel URI is unnecessary. + //ShowMessage("Subscriber doesn't exist on server.", "DEBUG"); + }); + } - private static void CloseChannel() - { - if (httpChannel == null) return; - try + public static void UnSubscribe() { - httpChannel.UnbindToShellTile(); - httpChannel.UnbindToShellToast(); - httpChannel.Close(); + Context.Load(Context.Web, w => w.Title, w => w.Description); + Guid deviceAppInstanceId = GetSettingValue(DeviceAppIdKey, false); + + Context.Web.UnregisterPushNotificationSubscriber(deviceAppInstanceId); + + Context.ExecuteQueryAsync + ( + (object sender, ClientRequestSucceededEventArgs args) => + { + CloseChannel(); + SetRegistrationStatus(false); + //SetInitializationStatus(false); + ShowMessage("Subscriber successfully unregistered.", "Success"); + }, + (object sender, ClientRequestFailedEventArgs args) => + { + ShowMessage(args.Exception.Message, "Error Unsubscribing"); + }); } - catch (Exception ex) + + public static void ClearSubscriptionStore() { - ShowMessage(ex.Message, "Error Closing Channel"); + Context.Load(Context.Web, w => w.Title, w => w.Description); + List subscriptionStore = Context.Web.Lists.GetByTitle("Push Notification Subscription Store"); + Context.Load(subscriptionStore); + ListItemCollection listItems = subscriptionStore.GetItems(new CamlQuery()); + Context.Load(listItems); + + Context.ExecuteQueryAsync + ( + (object sender1, ClientRequestSucceededEventArgs args1) => + { + foreach (ListItem listItem in listItems.ToList()) + { + listItem.DeleteObject(); + } + Context.ExecuteQueryAsync( + (object sender2, ClientRequestSucceededEventArgs args2) => + { + // Close channel if open and set registration status for current app instance. + CloseChannel(); + SetRegistrationStatus(false); + + ShowMessage("Subscriber store cleared.", "Success"); + }, + (object sender2, ClientRequestFailedEventArgs args2) => + { + ShowMessage(args2.Exception.Message, "Error Deleting Subscribers"); + }); + }, + (object sender1, ClientRequestFailedEventArgs args1) => + { + ShowMessage(args1.Exception.Message, "Error Loading Subscribers List"); + }); } - } - public static void SaveDeviceAppIdToStorage() - { - if (!IsolatedStorageSettings.ApplicationSettings.Contains(DeviceAppIdKey)) + private static void CloseChannel() { - Guid DeviceAppId = Guid.NewGuid(); - SetSettingValue(DeviceAppIdKey, DeviceAppId, false); + if (httpChannel == null) return; + try + { + httpChannel.UnbindToShellTile(); + httpChannel.UnbindToShellToast(); + httpChannel.Close(); + } + catch (Exception ex) + { + ShowMessage(ex.Message, "Error Closing Channel"); + } } - } - - public static bool GetRegistrationStatus() - { - bool status = GetSettingValue(RegStatusKey, false); - return status; - } - private static void SetRegistrationStatus(bool isRegistered) - { - SetSettingValue(RegStatusKey, isRegistered, false); - } + public static void SaveDeviceAppIdToStorage() + { + if (!IsolatedStorageSettings.ApplicationSettings.Contains(DeviceAppIdKey)) + { + Guid DeviceAppId = Guid.NewGuid(); + SetSettingValue(DeviceAppIdKey, DeviceAppId, false); + } + } - private static T GetSettingValue(string key, bool fromTransientStorage) - { - if (fromTransientStorage == false) + public static bool GetRegistrationStatus() { - if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) - return (T)IsolatedStorageSettings.ApplicationSettings[key]; - return default(T); + bool status = GetSettingValue(RegStatusKey, false); + return status; } - if (PhoneApplicationService.Current.State.ContainsKey(key)) - return (T)PhoneApplicationService.Current.State[key]; - return default(T); - } + private static void SetRegistrationStatus(bool isRegistered) + { + SetSettingValue(RegStatusKey, isRegistered, false); + } - private static void SetSettingValue(string key, T value, bool toTransientStorage) - { - if (toTransientStorage == false) + private static T GetSettingValue(string key, bool fromTransientStorage) { - if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) - IsolatedStorageSettings.ApplicationSettings[key] = value; - else - IsolatedStorageSettings.ApplicationSettings.Add(key, value); + if (fromTransientStorage == false) + { + if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) + return (T)IsolatedStorageSettings.ApplicationSettings[key]; + return default(T); + } - IsolatedStorageSettings.ApplicationSettings.Save(); + if (PhoneApplicationService.Current.State.ContainsKey(key)) + return (T)PhoneApplicationService.Current.State[key]; + return default(T); } - else + + private static void SetSettingValue(string key, T value, bool toTransientStorage) { - if (PhoneApplicationService.Current.State.ContainsKey(key)) - PhoneApplicationService.Current.State[key] = value; + if (toTransientStorage == false) + { + if (IsolatedStorageSettings.ApplicationSettings.Contains(key)) + IsolatedStorageSettings.ApplicationSettings[key] = value; + else + IsolatedStorageSettings.ApplicationSettings.Add(key, value); + + IsolatedStorageSettings.ApplicationSettings.Save(); + } else - PhoneApplicationService.Current.State.Add(key, value); + { + if (PhoneApplicationService.Current.State.ContainsKey(key)) + PhoneApplicationService.Current.State[key] = value; + else + PhoneApplicationService.Current.State.Add(key, value); + } } - } - // Method for showing messages on UI thread coming from a different originating thread. - private static void ShowMessage(string message, string caption) - { - Deployment.Current.Dispatcher.BeginInvoke(() => + // Method for showing messages on UI thread coming from a different originating thread. + private static void ShowMessage(string message, string caption) { - MessageBox.Show(message, caption, MessageBoxButton.OK); - }); + Deployment.Current.Dispatcher.BeginInvoke(() => + { + MessageBox.Show(message, caption, MessageBoxButton.OK); + }); + } } } -} -``` + ``` + +1. Save the file. -5. Save the file. - - In this code, the **OpenNotificationChannel** creates a notification channel for receiving notifications from MPNS. Event handlers are attached to the channel object for dealing with notification events, and then the channel is opened. In this sample, the **HttpNotificationReceived** event (for receiving raw notifications) is implemented. Raw notifications can be received only when the phone app is running. The handler for the **ShellToastNotificationReceived** event (for receiving toast notifications) is also implemented here to demonstrate its use. Tile notifications can be received only when the subscribing phone app is not running, so there's no need to implement an event handler in the app for receiving tile notifications. - - - + The **SubscribeToService** method executes the **RegisterPushNotificationSubscriber** method of the **SPWeb** object asynchronously (passing a value to identify the phone app and a URI value associated with the notification channel) to register with the SharePoint Server to receive push notifications. If the registration is successful, the Windows Phone shell is set to receive (and display) toast and tile notifications on the particular notification channel registered with the SharePoint Server when the phone app itself is not running. - - - + The **UnSubscribe** method in this code calls the **UnregisterPushNotificationSubscriber** method of the SPWeb object. The development guidelines for Windows Phone apps recommend that users be allowed to choose whether to subscribe to push notifications or not. In a later procedure, you will add a mechanism for the user to register or unregister for notifications and that registration state is preserved between sessions of the app, making it unnecessary to ask to register every time the app is started. The **GetRegistrationStatus** method is made available so that the phone app can determine whether the user has registered (in an earlier session) to receive push notifications and the notification channel is subsequently opened. The **SaveDeviceAppIdToStorage** saves the identifier (represented as a GUID) for the app instance on a given Windows Phone to isolated storage. - - - + The **ClearSubscriptionStore** method is included here as a demonstration of one way of clearing the subscribers from the subscription store on the SharePoint Server. Subscribers to push notifications are stored in a SharePoint list named "Push Notification Subscription Store". A button for calling this method of the **Notifications** class is added to the notifications settings page added to the app in a later procedure. - - - + Note that the operations that involve accessing the SharePoint Server to configure settings or prepare for notifications (such as the **RegisterPushNotificationSubscriber** method) can take time to complete, depending on the conditions of the network and the accessibility of the server. These operations are therefore executed asynchronously (specifically, by using the **ExecuteQueryAsync** method of a **ClientContext** object) to allow the app to continue other processes and to keep the UI responsive to the user. - - - + Next, add a page to the app with controls that allow a user to register for or unregister from push notifications from the server. - - - ### To add a notification settings page to the app - 1. In **Solution Explorer**, choose the node representing the project (named SPListAppForNotifications if you follow the naming convention in these procedures). - - -2. On the **Project** menu, click **Add New Item**. The **Add New Item** dialog box appears. - - -3. In the **Templates** pane, choose **Windows Phone Portrait Page** template. SpecifySettings.xaml as the name of the file for the page and click **Add**. The page is added to the project and opened for editing. - - -4. In the XAML view for the page, replace the content between the closing bracket of the XML tag that defines the **PhoneApplicationPage** element and the closing tag of the element ( ``), with the following markup. - -``` - - - - - - - - - - - - - - - - - - Notification Registration +1. On the **Project** menu, click **Add New Item**. The **Add New Item** dialog box appears. +1. In the **Templates** pane, choose **Windows Phone Portrait Page** template. SpecifySettings.xaml as the name of the file for the page and click **Add**. The page is added to the project and opened for editing. +1. In the XAML view for the page, replace the content between the closing bracket of the XML tag that defines the **PhoneApplicationPage** element and the closing tag of the element ( ``), with the following markup. + + ```xml + + + + + + + + + + + + + + + - -
    - - - - - - -``` + > The code examples in this article define custom code in the page markup but do not use the code-behind class that Visual Studio creates for the page. + +1. Open the shortcut menu for the FollowPeople.aspx page, and then choose **Set as Startup Item**. +1. In the markup of the FollowPeople.aspx file, paste the following code between the "Main" `asp:Content` tags. This code defines controls and script references. + + ```HTML +

    +
    + + + + + + + ``` > [!NOTE] - > The "Get followers and followed people" example doesn't use the button control or the form digest control, which is only required for operations that update server content. A form digest generates a message digest used for security validation. + > The "Get followers and followed people" example doesn't use the button control or the form digest control, which is only required for operations that update server content. A form digest generates a message digest used for security validation. + +1. Replace the comment between the `script` tags with the code example from one of the following scenarios: -10. Replace the comment between the **script** tags with the code example from one of the following scenarios: - - - [Start or stop following people](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#bk_FollowPeople) - - [Get followers and followed people](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#bk_GetFollowers) - -11. To test the solution, on the menu bar, choose **Debug**, **Start Debugging**. - - + - [Start or stop following people](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#code-example-start-or-stop-following-people-by-using-the-sharepoint-javascript-object-model) + - [Get followers and followed people](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#code-example-get-followers-and-followed-people-by-using-the-sharepoint-javascript-object-model) + +1. To test the solution, on the menu bar, choose **Debug**, **Start Debugging**. ## Code example: Start or stop following people by using the SharePoint JavaScript object model - The following code example makes the current user start following or stop following a target user. It shows how to: - - - - Check whether the current user is following a target user by using the [isFollowed](https://msdn.microsoft.com/library/2c1f62e6-fb75-ad4d-c081-36408b418c21%28Office.15%29.aspx) method. - - - Get the count of people who the current user is following by using the [getFollowedCount](https://msdn.microsoft.com/library/97b53b4f-481a-cf41-1854-8f3ff860b2bb%28Office.15%29.aspx) method. - - - Start following the target user by using the [follow](https://msdn.microsoft.com/library/40d14320-27ba-2941-b0e2-be3b5a407c89%28Office.15%29.aspx) method. - - - Stop following the target user by using the [stopFollowing](https://msdn.microsoft.com/library/65b0e9be-dc5e-09fb-c57f-7a933de09a4c%28Office.15%29.aspx) method. - - > [!NOTE] -> Paste the following code between the **script** tags that you added in the [Create a farm solution and application page](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#bk_CreateSolution) procedure. Then, change the placeholder value for the **targetUser** variable before you run the code. - - - - - -``` +> Paste the following code between the **script** tags that you added in the [Create a farm solution and application page](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#create-a-farm-solution-and-application-page-in-visual-studio-2012) procedure. Then, change the placeholder value for the **targetUser** variable before you run the code. +```javascript // Replace the placeholder value with the account name of the target user. var targetUser = 'domain\\userName'; @@ -202,32 +146,18 @@ function requestFailed(sender, args) { } ``` - ## Code example: Get followers and followed people by using the SharePoint JavaScript object model - The following code example gets the people who the current user is following and gets the people who are followed by the current user. It shows how to: - - - - Get the people who the current user is following by using the [getFollowed](https://msdn.microsoft.com/library/432a7cec-6add-fdb1-a79f-a93414ee8cd3%28Office.15%29.aspx) method. - - - Get the people who are following the current user by using the [getFollowers](https://msdn.microsoft.com/library/ae4a944b-c043-05fb-c74b-101d2ce4a813%28Office.15%29.aspx) method and passing **1** to represent **User** actor types. - - - Iterate through the groups of people and get each person's display name, personal site URI, and picture URI. - -> [!NOTE] -> Paste the following code between the **script** tags that you added in the [Create a farm solution and application page](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#bk_CreateSolution) procedure. - - - - -``` +> [!NOTE] +> Paste the following code between the `script` tags that you added in the [Create a farm solution and application page](how-to-follow-people-by-using-the-javascript-object-model-in-sharepoint.md#create-a-farm-solution-and-application-page-in-visual-studio-2012) procedure. +```javascript var followed; var followers; @@ -288,15 +218,7 @@ function requestFailed(sender, args) { } ``` - ## See also - - - -- [Follow people in SharePoint](follow-people-in-sharepoint.md) - - -- [How to: Follow people by using the .NET client object model in SharePoint](how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md) - - +- [Follow people in SharePoint](follow-people-in-sharepoint.md) +- [How to: Follow people by using the .NET client object model in SharePoint](how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md) diff --git a/docs/general-development/how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md b/docs/general-development/how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md index 6d22330ea..32228a4de 100644 --- a/docs/general-development/how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md +++ b/docs/general-development/how-to-follow-people-by-using-the-net-client-object-model-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Follow people by using the .NET client object model in SharePoint +description: Learn how to work with Following People features by using the SharePoint .NET client object model. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 0fdb7ca5-d408-4256-b52b-886c4bc3b5b8 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -108,7 +108,7 @@ This code example uses the [SocialFollowResult](https://msdn.microsoft.com/libr -```cs +```csharp using System; using System.Collections.Generic; @@ -221,7 +221,7 @@ The following code example gets the people who the current user is following, ge -```cs +```csharp using System; using System.Collections.Generic; diff --git a/docs/general-development/how-to-get-an-entire-workbook-or-a-snapshot.md b/docs/general-development/how-to-get-an-entire-workbook-or-a-snapshot.md index 7f2826741..a09b638b0 100644 --- a/docs/general-development/how-to-get-an-entire-workbook-or-a-snapshot.md +++ b/docs/general-development/how-to-get-an-entire-workbook-or-a-snapshot.md @@ -1,32 +1,32 @@ --- title: Get an entire workbook or a snapshot +description: This example shows how to get an entire workbook, a snapshot of the entire file, or just a snapshot of the viewable sheets or objects in the file by using Excel Web Services. ms.date: 09/25/2017 keywords: how to,howdoi,howto f1_keywords: - how to,howdoi,howto -ms.prod: sharepoint ms.assetid: 39115503-8352-4589-87f4-cfa9c07260b6 -localization_priority: Normal +ms.localizationpriority: medium --- # Get an entire workbook or a snapshot This example shows how to get an entire workbook, a snapshot of the entire file, or just a snapshot of the viewable sheets or objects in the file by using Excel Web Services. Getting the workbook or a snapshot is useful if you want to save a copy of the up-to-date workbook, store it somewhere, send it to someone, and so on. - - - + + + A snapshot is a workbook generated by Excel Calculation Services, and it represents the current state of the workbook in the Excel Services session. Some snapshots (known as "published item snapshots") contain only those portions of the Excel file that an author selects as viewable when saving the file to the server. Snapshots contain the layout and formats of the original file, and up-to-date values calculated by Excel Calculation Services, but they do not contain Excel formulas or external data connections. Excel Services opens the Excel file on the server, refreshes data sources, and calculates all Excel formulas. When a user or application requests a snapshot, Excel Services then generates and sends a snapshot back through the Web service API. You can acquire a snapshot of a workbook you already saved to the server, even if you do not have the rights to access the actual file on the server. - - - + + + You use the Web service's **GetWorkbook** method to get either the entire workbook or one of the snapshot types. For example, the following code returns a snapshot of the entire Excel workbook. It uses the **WorkbookType.FullSnapshot** enumeration as the second argument in the **GetWorkbook** method. -```cs +```csharp byte[] workbook = xlService.GetWorkbook(sessionId, WorkbookType.FullSnapshot, out status); ``` @@ -41,7 +41,7 @@ Dim workbook() As Byte = xlService.GetWorkbook(sessionId, WorkbookType.FullSnaps The **GetWorkbook** method returns a byte array, in the same Excel file format as the one loaded into the session.To get a snapshot of the items that the Excel workbook author selected as viewable when saving the workbook from Excel to the server, use the **WorkbookType.PublishedItemsSnapshot** enumeration as shown here: -```cs +```csharp byte[] workbook = xlService.GetWorkbook(sessionId, WorkbookType.PublishedItemsSnapshot, out status); ``` @@ -55,7 +55,7 @@ Dim workbook() As Byte = xlService.GetWorkbook(sessionId, WorkbookType.FullSnaps To get a snapshot of the entire workbook in its current session state, use the **WorkbookType.FullWorkbook** enumeration: -```cs +```csharp byte[] workbook = xlService.GetWorkbook(sessionId, WorkbookType.FullWorkbook, out status); ``` @@ -69,17 +69,17 @@ Dim workbook() As Byte = xlService.GetWorkbook(sessionId, WorkbookType.FullWorkb The **WorkbookType.FullWorkbook** option works only if the user has open rights to the file; if the user has view-only rights, the call will fail.In some cases, your code would need to save the result of a **GetWorkbook** call. For a discussion about how to save a workbook, see the [How to: Save a Workbook](https://msdn.microsoft.com/library/feb74f7a-2d8f-4672-911b-de85f8852aea%28Office.15%29.aspx) example.For more information about the **GetWorkbook** method and the **WorkbookType** enumeration, see the Excel Web Services reference documentation. ## Example -The following program (a console application) receives one command-line argument, which is the path to the workbook on the server. The program calls the Web service to open the workbook on the server and get a snapshot. It then writes it to standard output so that you can redirect it to a new snapshot file. - - - +The following program (a console application) receives one command-line argument, which is the path to the workbook on the server. The program calls the Web service to open the workbook on the server and get a snapshot. It then writes it to standard output so that you can redirect it to a new snapshot file. -```cs + + + +```csharp using System; using System.IO; using System.Text; using System.Web.Services.Protocols; -// TODO: Change the using GetSnapshot.myServer02 statement +// TODO: Change the using GetSnapshot.myServer02 statement // to point to the Web service you are referencing. using GetSnapshot.myServer02; @@ -96,18 +96,18 @@ namespace GetSnapshot Console.Error.WriteLine("Command line arguments should be: GetSnapshot [workbook_path] > [snapshot_filename]"); return; } - // Instantiate the Web service and + // Instantiate the Web service and // create a status array object. ExcelService xlService = new ExcelService(); Status[] status; - + xlService.Timeout = 600000; // Set credentials for requests. // Use the current user's logon credentials. - xlService.Credentials = + xlService.Credentials = System.Net.CredentialCache.DefaultCredentials; - - // Open the workbook, then call GetWorkbook + + // Open the workbook, then call GetWorkbook // and close the session. string sessionId = xlService.OpenWorkbook(args[0], "en-US", "en-US", out status); byte[] workbook = xlService.GetWorkbook(sessionId, WorkbookType.PublishedItemsSnapshot, out status); @@ -117,7 +117,7 @@ namespace GetSnapshot // Close the workbook. This also closes the session. status = xlService.CloseWorkbook(sessionId); - // Write the resulting Excel file to stdout + // Write the resulting Excel file to stdout // as a binary stream. BinaryWriter binaryWriter = new BinaryWriter(Console.OpenStandardOutput()); binaryWriter.Write(workbook); @@ -132,8 +132,8 @@ namespace GetSnapshot catch (Exception e) { Console.WriteLine("Exception Message: {0}", e.Message); - } - } + } + } } } ``` @@ -145,7 +145,7 @@ Imports System Imports System.IO Imports System.Text Imports System.Web.Services.Protocols -' TODO: Change the using GetSnapshot.myServer02 statement +' TODO: Change the using GetSnapshot.myServer02 statement ' to point to the Web service you are referencing. Imports GetSnapshot.myServer02 @@ -157,7 +157,7 @@ Namespace GetSnapshot Console.Error.WriteLine("Command line arguments should be: GetSnapshot [workbook_path] > [snapshot_filename]") Return End If - ' Instantiate the Web service and + ' Instantiate the Web service and ' create a status array object. Dim xlService As New ExcelService() Dim status() As Status @@ -167,7 +167,7 @@ Namespace GetSnapshot ' Use the current user's logon credentials. xlService.Credentials = System.Net.CredentialCache.DefaultCredentials - ' Open the workbook, then call GetWorkbook + ' Open the workbook, then call GetWorkbook ' and close the session. Dim sessionId As String = xlService.OpenWorkbook(args(0), "en-US", "en-US", status) Dim workbook() As Byte = xlService.GetWorkbook(sessionId, WorkbookType.PublishedItemsSnapshot, status) @@ -177,7 +177,7 @@ Namespace GetSnapshot ' Close the workbook. This also closes the session. status = xlService.CloseWorkbook(sessionId) - ' Write the resulting Excel file to stdout + ' Write the resulting Excel file to stdout ' as a binary stream. Dim binaryWriter As New BinaryWriter(Console.OpenStandardOutput()) binaryWriter.Write(workbook) @@ -194,10 +194,10 @@ Namespace GetSnapshot End Namespace ``` -Use the following command line and arguments to run the GetSnapshot application: - - - +Use the following command line and arguments to run the GetSnapshot application: + + + @@ -206,10 +206,10 @@ Use the following command line and arguments to run the GetSnapshot application: GetSnapshot.exe [workbook_path] > [snapshot_filename] ``` -For example: - - - +For example: + + + @@ -218,20 +218,20 @@ C:\\>GetSnapshot.exe http://myServer02/reports/reports/OriginalWorkbook.xlsx > S ``` If you use the previous command-line example, the GetSnapshot tool places a new file in the "C:\\" directory. - + > [!NOTE] -> he workbook that you want to get a snapshot of must be in a trusted location. - - - +> he workbook that you want to get a snapshot of must be in a trusted location. + + + ## Robust programming Make sure you add a Web reference to an Excel Web Services site you have access to. Change the `using GetSnapshot.myServer02;` statement to point to the Web service site you are referencing. - - - + + + ## See also @@ -239,37 +239,37 @@ Make sure you add a Web reference to an Excel Web Services site you have access #### Tasks - - - + + + [How to: Trust a Location](how-to-trust-a-location.md) #### Concepts - - - + + + [Accessing the SOAP API](accessing-the-soap-api.md) #### Other resources - - - + + + [Step 1: Creating the Web Service Client Project](step-1-creating-the-web-service-client-project.md) - - - + + + [Step 2: Adding a Web Reference](step-2-adding-a-web-reference.md) - - - + + + [Step 3: Accessing the Web Service](step-3-accessing-the-web-service.md) - - - + + + [Step 4: Building and Testing the Application](step-4-building-and-testing-the-application.md) - - - + + + [Walkthrough: Developing a Custom Application Using Excel Web Services](walkthrough-developing-a-custom-application-using-excel-web-services.md) diff --git a/docs/general-development/how-to-get-values-from-ranges.md b/docs/general-development/how-to-get-values-from-ranges.md index 1e50df7ca..83b3eb4a9 100644 --- a/docs/general-development/how-to-get-values-from-ranges.md +++ b/docs/general-development/how-to-get-values-from-ranges.md @@ -1,12 +1,12 @@ --- title: Get values from ranges +description: "Excel Web Services exposes four methods for getting values from an Excel workbook: GetCell, GetCellA1, GetRange, and GetRangeA1." ms.date: 09/25/2017 keywords: get range,how to,howdoi,howto f1_keywords: - get range,how to,howdoi,howto -ms.prod: sharepoint ms.assetid: ab2c0f60-b7df-46a1-9105-eb85ce817431 -localization_priority: Priority +ms.localizationpriority: high --- @@ -26,7 +26,7 @@ Methods that have the A1 suffix ( **GetCellA1** and **GetRangeA1**) use a differ If you want to access an Excel range by using a numeric coordinate system, you should use the methods that do not have the A1 suffix. It is easier to use range coordinates when you have code that iterates through a set of cells in a loop, or when the range coordinates are calculated dynamically as part of the algorithm.The row and column coordinates of a cell are 0-based. Therefore, "0,0" will return cell A1, as in this example: -```cs +```csharp // Call the GetCell method to retrieve a value from a cell. // The cell is in the first row and first column; that is, cell A1 @@ -49,7 +49,7 @@ If you are getting values from multiple adjacent cells, you may want to consider 1. Use the **GetCell** method to get a value from a cell in the open workbook by using numeric range coordinates; for example: -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); @@ -98,7 +98,7 @@ Dim rangeResult2() As Object = xlservice.GetCell(sessionId, sheetName, 0, 8, Fal 2. Use the **GetRange** method to get values from a range in the open workbook by using numeric range coordinates. -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); @@ -157,7 +157,7 @@ Next x 1. Use the **GetCellA1** method to get a value from a cell in the open workbook, using the Excel "A1" range specification; for example: -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); @@ -201,7 +201,7 @@ Dim rangeResult() As Object = xlservice.GetCellA1(sessionId, sheetName, "Monthly -```cs +```csharp object[] rangeResults = xlservice.GetRangeA1(sessionId, "Sheet1", "B2:D3", true, out outStatus); foreach (object[] rangeResult in rangeResults) diff --git a/docs/general-development/how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md b/docs/general-development/how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md index 727e50a4e..84d5f4ad6 100644 --- a/docs/general-development/how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md +++ b/docs/general-development/how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md @@ -1,328 +1,218 @@ --- title: Implement business logic and data validation in a Windows Phone app for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Implement data validation in a Windows Phone app created by using the Windows Phone SharePoint List Application template. +ms.date: 06/09/2022 ms.assetid: fbbedc38-9651-4cd6-b523-d93cbf1cd39d -localization_priority: Normal +ms.localizationpriority: medium --- - - # Implement business logic and data validation in a Windows Phone app for SharePoint Implement data validation in a Windows Phone app created by using the Windows Phone SharePoint List Application template. -In a Windows Phone app intended for production use, you likely need to validate data entered by users to, for example, enforce business logic relevant to your particular circumstances, or to ensure appropriate formatting of entered values, or simply to catch mistakes before saving values to a SharePoint list. Projects based on the Windows Phone SharePoint List Application template include default data validation logic, but such projects also provide a mechanism for developers to implement custom data validation. - - - +In a Windows Phone app intended for production use, you likely need to validate data entered by users to, for example, enforce business logic relevant to your particular circumstances, or to ensure appropriate formatting of entered values, or simply to catch mistakes before saving values to a SharePoint list. Projects based on the Windows Phone SharePoint List Application template include default data validation logic, but such projects also provide a mechanism for developers to implement custom data validation. -> **Important:** -> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). - - - - +> [!IMPORTANT] +> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). ## Default data validation rules - Some data types for fields in SharePoint lists are associated by default with simple formatting or data validation. If you enter an invalid URL for a field based on the Hyperlink or Picture field type in a SharePoint list and attempt to save your changes, you see a message indicating that the address you entered is invalid. If you enter a customer name as a value for a field based on the Date and Time field type, you receive a message directing you to enter a date within a valid range for the field. - -> [!NOTE] -> Date input validation is with respect to SharePoint date format. If the date format of the phone locale is required, customize the field and add validations accordingly. - - - -Some of these basic validation rules are also enforced by default in a Windows Phone app created from the Windows Phone SharePoint List Application template. If you enter anything other than a date value in a field that is bound to a SharePoint field of Date and Time type in the Edit form of a Windows Phone app based on a SharePoint list, you see a validation error message when the focus shifts from the **TextBox** control associated with the field. (See Figure 1.) - - - +> [!NOTE] +> Date input validation is with respect to SharePoint date format. If the date format of the phone locale is required, customize the field and add validations accordingly. -**Figure 1. Validation error cue in a Windows Phone app** +Some of these basic validation rules are also enforced by default in a Windows Phone app created from the Windows Phone SharePoint List Application template. If you enter anything other than a date value in a field that is bound to a SharePoint field of Date and Time type in the Edit form of a Windows Phone app based on a SharePoint list, you see a validation error message when the focus shifts from the `TextBox` control associated with the field. (See Figure 1.) - - - +### Figure 1. Validation error cue in a Windows Phone app - - - ![Validation error cue in a Windows Phone app](../images/49a93d59-6755-4afc-a703-ca8469b6fa74.gif) - - - -The text box labeled "Start Time" in the Edit form is bound to a Date and Time field in the SharePoint list on which this sample app is based. The validation error cue (in red text) shown in Figure 1 appears if an invalid date is entered in the text box (and the text box subsequently loses focus) because the **ValidatesOnNotifyDataErrors** property of the **Binding** object associated with the **Text** property of the **TextBox** control is set to **True** in the XAML declaration that defines the **TextBox** in the EditForm.xaml file. - - - - +The text box labeled "Start Time" in the Edit form is bound to a Date and Time field in the SharePoint list on which this sample app is based. The validation error cue (in red text) shown in Figure 1 appears if an invalid date is entered in the text box (and the text box subsequently loses focus) because the `ValidatesOnNotifyDataErrors` property of the `Binding` object associated with the `Text` property of the `TextBox` control is set to `True` in the XAML declaration that defines the `TextBox` in the **EditForm.xaml** file. ```XML - - Start Time* + Start Time* - - + TextWrapping="Wrap" /> + ``` -(If the **ValidatesOnNotifyDataErrors** property is set to **False**, the user has no indication that the entered data is invalid until the **Save** button is chosen. At that point, the user sees an error message regarding validation errors, because format validation on entered date values is still carried out by the base class from which the **EditItemViewModel** class is derived.) - - - +(If the `ValidatesOnNotifyDataErrors` property is set to `False`, the user has no indication that the entered data is invalid until the **Save** button is chosen. At that point, the user sees an error message regarding validation errors, because format validation on entered date values is still carried out by the base class from which the `EditItemViewModel` class is derived.) + But some fields may not provide any notification for invalid data in the Windows Phone app. And well-designed Visual Studio project templates are necessarily generalized to be used as a starting point for many different applications. The Windows Phone SharePoint List Application template can't include validation rules relevant to specific contexts and yet retain its value as a generalized template. Depending on your needs and the circumstances in which your particular Windows Phone app will be used, you likely will want to implement your own custom data-validation rules. - - - ## Implement custom data-validation rules - You can validate data entered by users of your Windows Phone app in several ways. A project created by using the Windows Phone SharePoint List Application template includes classes that serve as intermediaries between the forms (that is, the views) of the data in the Windows Phone app (for example, the EditForm.xaml file) and the data itself in the SharePoint list on which the app is based. These classes can be considered implementations of the ViewModel component of the [Model-View-ViewModel design pattern](https://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx) (Figure 2). (For more information about how the Windows Phone SharePoint List Application template conforms to the MVVM software design pattern, see [Architecture of the Windows Phone SharePoint List Application template](architecture-of-the-windows-phone-sharepoint-list-application-template.md).) - -> [!NOTE] -> The SharePoint list templates do not include default validations (such as percentage complete in a SharePoint task list, post check for a team discussion list, and SP decimal field type validation), but you can implement such validations. - - - +> [!NOTE] +> The SharePoint list templates do not include default validations (such as percentage complete in a SharePoint task list, post check for a team discussion list, and SP decimal field type validation), but you can implement such validations. **Figure 2. Template files in ViewModel component** - - - - - - - ![Template files in ViewModel component](../images/2df9591d-a837-4130-98e4-5863d0c717e8.gif) - - - -In applications designed based on the MVVM pattern, data validation is often handled in the data layer (that is, in the Model component). In projects created from the Windows Phone SharePoint List Application template, an extensible mechanism for data validation has been "pushed up" a layer and implemented in the ViewModel component, to make it easier for developers to manage data validation. In projects based on the template, therefore, the most suitable place for custom code that validates user input or otherwise manages data is in these ViewModel classes. In terms of data validation, the **EditItemViewModel** class and the **NewItemViewModel** class (the classes associated with the forms most likely to involve editing and updating list data) both provide an open implementation of a validation method (named **Validate**) that overrides the base validation method in the class from which these two classes are derived. - - - - +In applications designed based on the MVVM pattern, data validation is often handled in the data layer (that is, in the Model component). In projects created from the Windows Phone SharePoint List Application template, an extensible mechanism for data validation has been "pushed up" a layer and implemented in the ViewModel component, to make it easier for developers to manage data validation. In projects based on the template, therefore, the most suitable place for custom code that validates user input or otherwise manages data is in these ViewModel classes. In terms of data validation, the `EditItemViewModel` class and the `NewItemViewModel` class (the classes associated with the forms most likely to involve editing and updating list data) both provide an open implementation of a validation method (named `Validate()`) that overrides the base validation method in the class from which these two classes are derived. -```cs - +```csharp public override void Validate(string fieldName, object value) - { - base.Validate(fieldName, value); - } +{ + base.Validate(fieldName, value); +} ``` -This method provides a convenient mechanism to the developer for adding custom validation logic that targets individual fields. The general approach is to check the value of the **fieldName** argument passed to the **Validate** method to identify the field you want to associate with your custom validation code. You can, for example, use a **switch** statement in your implementation of this method to supply validation logic specific to various fields in the Edit form (EditForm.xaml) of your Windows app. - - - +This method provides a convenient mechanism to the developer for adding custom validation logic that targets individual fields. The general approach is to check the value of the `fieldName` argument passed to the `Validate()` method to identify the field you want to associate with your custom validation code. You can, for example, use a `switch` statement in your implementation of this method to supply validation logic specific to various fields in the Edit form (EditForm.xaml) of your Windows app. + For the following code example, assume that an installation of SharePoint Server has a Product Orders list created from the Custom List template. The list has been created with the columns and field types shown in Table 1. - - - **Table 1. Product Orders list** +| Column | Type | Required | +| :-------------------- | :------------------------- | :------- | +| Product (i.e., Title) | Single line of text (Text) | Yes | +| Description | Single line of text (Text) | No | +| Quantity | Number | Yes | +| Order Date | Date and Time (DateTime) | No | +| Fulfillment Date | Date and Time (DateTime) | No | +| Contact Number | Single line of text (Text) | No | -|**Column**|**Type**|**Required**| -|:-----|:-----|:-----| -|Product (i.e., Title)
    |Single line of text (Text)
    |Yes
    | -|Description
    |Single line of text (Text)
    |No
    | -|Quantity
    |Number
    |Yes
    | -|Order Date
    |Date and Time (DateTime)
    |No
    | -|Fulfillment Date
    |Date and Time (DateTime)
    |No
    | -|Contact Number
    |Single line of text (Text)
    |No
    | - Again, for the purposes of this example, assume that the following simple validation rules are to be enforced, based on the business logic employed at the fictitious company Contoso, Ltd., for a given product ordering system: - - - - Fulfillment dates for orders must be later than the date on which the order was placed. - - - If a customer wants to place an order for a product named Fuzzy Dice, the dice must be ordered in pairs. According to the peculiar rules at Contoso, Ltd., there is simply no such thing as a Fuzzy Die. - - - In the Product Orders list, the field type for phone numbers is "Single line of text" (that is, Text), which can be any text (up to 255 characters by default). For this sample, a formatting validation rule will be enforced that requires entered data to be in one of the common phone number formats; for example, "(555) 555-5555". - - ### To implement custom validation rules - 1. Assuming you have created a SharePoint list based on the Custom List template that includes the columns and types specified in Table 1, create a Windows Phone app by using the Windows Phone SharePoint List Application template in Visual Studio by following the steps detailed in [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md). - - -2. In **Solution Explorer**, in the ViewModels folder for the project, double-click the EditItemViewModel.cs file (or choose the file and press F7) to open the file for editing. - - -3. Add the following **using** directives to the list of directives at the top of the file. - -```cs - -using System.Globalization; -using System.Text.RegularExpressions; -``` +1. In **Solution Explorer**, in the ViewModels folder for the project, double-click the **EditItemViewModel.cs** file (or choose the file and press F7) to open the file for editing. +1. Add the following `using` directives to the list of directives at the top of the file. -4. Replace the default implementation of the **Validate** method in the file with the following code. - -```cs - -public override void Validate(string fieldName, object value) -{ - string fieldValue = value.ToString(); - if (!string.IsNullOrEmpty(fieldValue)) //Allowing for blank fields. - { - bool isProperValue = false; + ```csharp + using System.Globalization; + using System.Text.RegularExpressions; + ``` + +1. Replace the default implementation of the `Validate()` method in the file with the following code. - switch (fieldName) + ```csharp + public override void Validate(string fieldName, object value) + { + string fieldValue = value.ToString(); + if (!string.IsNullOrEmpty(fieldValue)) //Allowing for blank fields. { - case "Quantity": - // Enforce ordering Fuzzy Dice in pairs only. - int quantityOrdered; - isProperValue = Int32.TryParse(fieldValue, out quantityOrdered); - if (isProperValue) - { - if ((quantityOrdered % 2) != 0) // Odd number of product items ordered. + bool isProperValue = false; + + switch (fieldName) + { + case "Quantity": + // Enforce ordering Fuzzy Dice in pairs only. + int quantityOrdered; + isProperValue = Int32.TryParse(fieldValue, out quantityOrdered); + if (isProperValue) { - if ((string)this["Title"] == "Fuzzy Dice") + if ((quantityOrdered % 2) != 0) // Odd number of product items ordered. { - AddError("Item[Quantity]", "Fuzzy Dice must be ordered in pairs. - No such thing as a Fuzzy Die!"); + if ((string)this["Title"] == "Fuzzy Dice") + { + AddError("Item[Quantity]", "Fuzzy Dice must be ordered in pairs. + No such thing as a Fuzzy Die!"); + } + else + { + // Restriction on ordering in pairs doesn't apply to other products. + RemoveAllErrors("Item[Quantity]"); + } } else { - // Restriction on ordering in pairs doesn't apply to other products. RemoveAllErrors("Item[Quantity]"); } } - else + break; + case "Fulfillment_x0020_Date": + // Determine whether fulfillment date is later than order date. + DateTime fulfillmentDate; + isProperValue = DateTime.TryParse(fieldValue, CultureInfo.CurrentCulture, + DateTimeStyles.AssumeLocal, out fulfillmentDate); + if (isProperValue) { - RemoveAllErrors("Item[Quantity]"); + DateTime orderDate; + isProperValue = DateTime.TryParse((string)this["Order_x0020_Date"], + CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out orderDate); + + if (fulfillmentDate.CompareTo(orderDate) > 0) + { + RemoveAllErrors("Item[Fulfillment_x0020_Date]"); + } + else + { + AddError("Item[Fulfillment_x0020_Date]", + "Fulfillment Date must be later than Order Date."); + } } - } - break; - case "Fulfillment_x0020_Date": - // Determine whether fulfillment date is later than order date. - DateTime fulfillmentDate; - isProperValue = DateTime.TryParse(fieldValue, CultureInfo.CurrentCulture, - DateTimeStyles.AssumeLocal, out fulfillmentDate); - if (isProperValue) - { - DateTime orderDate; - isProperValue = DateTime.TryParse((string)this["Order_x0020_Date"], - CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out orderDate); - - if (fulfillmentDate.CompareTo(orderDate) > 0) + break; + case "Contact_x0020_Number": + // Check that contact number is in an appropriate format. + Regex rx = new Regex(@"^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"); + if (rx.IsMatch(fieldValue)) { - RemoveAllErrors("Item[Fulfillment_x0020_Date]"); + RemoveAllErrors("Item[Contact_x0020_Number]"); } else { - AddError("Item[Fulfillment_x0020_Date]", - "Fulfillment Date must be later than Order Date."); + //Specified Contact Number is not a valid phone number. + AddError("Item[Contact_x0020_Number]", "Specified Contact Number is invalid."); } - } - break; - case "Contact_x0020_Number": - // Check that contact number is in an appropriate format. - Regex rx = new Regex(@"^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"); - if (rx.IsMatch(fieldValue)) - { - RemoveAllErrors("Item[Contact_x0020_Number]"); - } - else - { - //Specified Contact Number is not a valid phone number. - AddError("Item[Contact_x0020_Number]", "Specified Contact Number is invalid."); - } - break; - default: - // Not adding custom validation for other fields. - break; + break; + default: + // Not adding custom validation for other fields. + break; + } } + + //And then proceed with default validation from base class. + base.Validate(fieldName, value); } + ``` - //And then proceed with default validation from base class. - base.Validate(fieldName, value); -} -``` + Keep in mind that the field names specified in this code sample are based on properties of the sample Product Orders list specified in Table 1. (Notice that in the XML schema for list fields in SharePoint Server, spaces in the names of fields are replaced with the string "_x0020_" for the **Name** attribute of the **Field** element that defines a given field. The template uses the **Name** attribute for a **Field** element as it is defined in the XML schema on the server, not the **DisplayName** attribute.) You can identify the field names of those fields for which you want to implement validation logic by looking at the **Binding** declarations of the **Text** properties for the **TextBox** objects defined in EditForm.xaml or by examining the **ViewFields** string of the **CamlQueryBuilder** class in the ListProvider.cs file. +1. Save the file. - Keep in mind that the field names specified in this code sample are based on properties of the sample Product Orders list specified in Table 1. (Notice that in the XML schema for list fields in SharePoint Server, spaces in the names of fields are replaced with the string "_x0020_" for the **Name** attribute of the **Field** element that defines a given field. The template uses the **Name** attribute for a **Field** element as it is defined in the XML schema on the server, not the **DisplayName** attribute.) You can identify the field names of those fields for which you want to implement validation logic by looking at the **Binding** declarations of the **Text** properties for the **TextBox** objects defined in EditForm.xaml or by examining the **ViewFields** string of the **CamlQueryBuilder** class in the ListProvider.cs file. - - -5. Save the file. - - The custom validation code in this sample is executed only if the **value** argument passed to the **Validate** method is not a null or empty string. As indicated in Table 1, the Fulfillment Date and Contact Number fields are not required to contain data (as the list is defined for the purposes of this sample in SharePoint Server), so we want to allow these fields to be blank. A simple check to determine whether the **value** argument is null is not sufficient, because the value passed could be a zero-length string (which doesn't equate to a null value), and for this sample we don't want to invalidate zero-length strings for fields that can be blank. The validation logic for the Quantity and Fulfillment Date fields includes additional checks of the values passed in to ensure that they are of the appropriate type. If the initial check here (before the **switch** statement) confirmed only that the value passed in were not null (instead of checking against the narrower condition of being a zero-length string), those validations would still not execute if the value were a zero-length string, but the logic to validate data for the **Contact Number** field *would* still execute if the value passed were a zero-length string. And in this sample we want to allow for the Contact Number field to be blank (a zero-length string), especially when a user starts editing a list item by opening the Edit form. - - - + If you build the project and deploy it to Windows Phone Emulator to run it, you can test your validation logic by entering data that violates your business rules into the fields of the list in the Edit form of the app. (See Figure 3.) - - - **Figure 3. Custom validation error cues** - - - - - - - ![Custom validation error cues](../images/fada902b-fa38-4ac8-8566-3693b736ac35.gif) - - - -The code in this sample, if it is included in the EditItemViewModel.cs file only, enforces these validation rules for data entered by users only on the Edit Form. If you want to enforce the validation rules both when users *add* new items as well as when they edit them, you must include the same validation logic in the **Validate** method in the NewItemViewModel.cs file (or, preferably, create a separate class file with a function that includes this validation logic and call that same function from the **Validate** methods in both the EditItemViewModel.cs file and the NewItemViewModel.cs file). - - - + +The code in this sample, if it is included in the EditItemViewModel.cs file only, enforces these validation rules for data entered by users only on the Edit Form. If you want to enforce the validation rules both when users *add* new items as well as when they edit them, you must include the same validation logic in the `Validate()` method in the NewItemViewModel.cs file (or, preferably, create a separate class file with a function that includes this validation logic and call that same function from the `Validate()` methods in both the EditItemViewModel.cs file and the NewItemViewModel.cs file). + The validation logic in this sample enforces given business rules by indicating to the user that entered data is not in a format permitted by the rules, but the entered data is not intercepted and changed by this code. To intercept and, for example, format phone numbers in a consistent way before saving the data to the SharePoint list, you can implement custom data conversion for entered phone numbers. For an explanation of custom data conversion for list item fields, see [How to: Support and convert SharePoint field types for Windows Phone apps](how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md). - - - ## See also - - - -- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) - - -- [Silverlight Data Binding](https://msdn.microsoft.com/library/cc278072.aspx) - - -- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) - - -- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) - - -- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) - - -- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=27570) - - -- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) - - +- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) +- [Silverlight Data Binding](https://msdn.microsoft.com/library/cc278072.aspx) +- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) +- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) +- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) +- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=29233) +- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) diff --git a/docs/general-development/how-to-include-mentions-tags-and-links-to-sites-and-documents-in-posts-in-sharep.md b/docs/general-development/how-to-include-mentions-tags-and-links-to-sites-and-documents-in-posts-in-sharep.md index ec72e850a..346038431 100644 --- a/docs/general-development/how-to-include-mentions-tags-and-links-to-sites-and-documents-in-posts-in-sharep.md +++ b/docs/general-development/how-to-include-mentions-tags-and-links-to-sites-and-documents-in-posts-in-sharep.md @@ -1,86 +1,85 @@ --- title: Include mentions, tags, and links to sites and documents in posts in SharePoint +description: Learn how to add SocialDataItem objects to microblog posts, which render as mentions, tags, or links in SharePoint social feeds. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 975da333-372b-4bf6-a3f4-7452db369f04 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Include mentions, tags, and links to sites and documents in posts in SharePoint Learn how to add [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) objects to microblog posts, which render as mentions, tags, or links in SharePoint social feeds. + In a social feed, the simplest form of post content contains only text, but you can also add links that render as mentions, tags, or links to websites, SharePoint sites, and documents. To do this, you add [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) objects to the [ContentItems](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.ContentItems.aspx) property of the [SocialPostCreationData](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.aspx) object that defines the post. Posts can contain multiple links. - + > [!NOTE] -> To add embedded pictures, videos, or documents to a post's content, you add a [SocialAttachment](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialAttachment.aspx) object to the [SocialPostCreationData.Attachment](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.Attachment.aspx) property. For more information, see [How to: Embed images, videos, and documents in posts in SharePoint](how-to-embed-images-videos-and-documents-in-posts-in-sharepoint-server.md). - - - +> To add embedded pictures, videos, or documents to a post's content, you add a [SocialAttachment](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialAttachment.aspx) object to the [SocialPostCreationData.Attachment](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.Attachment.aspx) property. For more information, see [How to: Embed images, videos, and documents in posts in SharePoint](how-to-embed-images-videos-and-documents-in-posts-in-sharepoint-server.md). + + + The API described in this article is from the .NET client object model. However, if you're using another API, such as the JavaScript object model, the object names or corresponding API might be different. See [Additional resources](#bk_addresources) for links to documentation for related APIs. - - - + + + ## Prerequisites for using the code examples to add links to a post in SharePoint The code examples in this article show how to add links to microblog posts. These examples are from console applications that use the following SharePoint assemblies: - - - + + + - Microsoft.SharePoint.Client - - + + - Microsoft.SharePoint.Client.Runtime - - + + - Microsoft.SharePoint.Client.UserProfilies - - + + For instructions about how to set up your development environment and create a console application, see [How to: Create and delete posts and retrieve the social feed by using the .NET client object model in SharePoint](how-to-create-and-delete-posts-and-retrieve-the-social-feed-by-using-the-net-cli.md). - - - + + + ## Example: Include links to websites, SharePoint sites, and documents in a post in SharePoint The following code example publishes a post that contains links to a website, a SharePoint site, and a document. It shows how to: - - - + + + - Create [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) objects that represent the links. Each instance sets the [SocialDataItemType](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItemType.aspx) field for the link type, the display text for the link, and the link URI. - - + + - Add placeholders to the post text to indicate where the link's display text should appear. - - + + - Add the link objects to the [ContentItems](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.ContentItems.aspx) property of the [SocialPostCreationData](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.aspx) object that's used to create the post. - + > [!NOTE] > Currently, SharePoint handles links to websites, SharePoint sites, and documents in the same way, but as a best practice, choose the [Site](https://msdn.microsoft.com/library/office/microsoft.sharepoint.client.social.socialdataitemtype.aspx) type and the [Document](https://msdn.microsoft.com/library/office/microsoft.sharepoint.client.social.socialdataitemtype.aspx) type for SharePoint sites and documents. - - - + + + In the social feed, clicking a link to a website, SharePoint site, or document opens the item in a separate browser window. - + > [!NOTE] -> Change the placeholder values for the URL variables before you run the code. - - - +> Change the placeholder values for the URL variables before you run the code. + + + -```cs +```csharp using System; using System.Collections.Generic; @@ -132,10 +131,10 @@ namespace IncludeLinksInPost // and then add the links to the post's content items. SocialPostCreationData postCreationData = new SocialPostCreationData(); postCreationData.ContentText = "Check out this {0}, {1}, and {2}."; - postCreationData.ContentItems = new SocialDataItem[3] { - websiteLink, - siteLink, - docLink + postCreationData.ContentItems = new SocialDataItem[3] { + websiteLink, + siteLink, + docLink }; try { @@ -167,31 +166,31 @@ namespace IncludeLinksInPost The following code example publishes a post that mentions a user. It shows how to: - - - + + + - Create a [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) object to represent a mention, which is a link to a user. The [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) specifies the [SocialDataItemType.User](https://msdn.microsoft.com/library/office/microsoft.sharepoint.client.social.socialdataitemtype.aspx) field and the mentioned person's account name. You can set the account name by using either the person's login or email address. - - + + - Add a placeholder to the post text to indicate where the mentioned person's display name should appear. - - + + - Add the [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) to the [ContentItems](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.ContentItems.aspx) property of the [SocialPostCreationData](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.aspx) object that's used to create the post. - - + + In the social feed, clicking a mention redirects to the mentioned person's **About** page. - + > [!NOTE] > Change the placeholder values for the **serverURL** and **accountName** variables before you run the code. - - - -```cs + + + +```csharp using System; using System.Collections.Generic; @@ -256,31 +255,31 @@ namespace IncludeMentionInPost The following code example publishes a post that includes a tag. It shows how to: - - - + + + - Create a [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) object to represent the tag. The [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) specifies the [SocialDataItemType.Tag](https://msdn.microsoft.com/library/office/microsoft.sharepoint.client.social.socialdataitemtype.aspx) field and the tag name, which must include a **#** character. - - + + - Add a placeholder to the post text to indicate where the tag should appear. - - + + - Add the [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) to the [ContentItems](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.ContentItems.aspx) property of the [SocialPostCreationData](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.aspx) object that's used to create the post. - - + + In the social feed, clicking a tag redirects to the tag's **About** page. If the tag doesn't already exist, the server creates it. - + > [!NOTE] > Change the placeholder values for the **serverURL** and **tagName** variables before you run the code. - - - -```cs + + + +```csharp using System; using System.Collections.Generic; @@ -347,18 +346,18 @@ namespace IncludeTagInPost - [Work with social feeds in SharePoint](work-with-social-feeds-in-sharepoint.md) - - + + - [SocialPostCreationData](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialPostCreationData.aspx) and [SocialDataItem](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialDataItem.aspx) in the client object models - - + + - [SocialPostCreationData](https://msdn.microsoft.com/library/f0e1fa3e-6fc9-48e0-5570-92091abfef33%28Office.15%29.aspx) and [SocialDataItem](https://msdn.microsoft.com/library/757e7b62-66a6-b03f-0ff0-769a42eb2b4a%28Office.15%29.aspx) in the JavaScript object model - - + + - [Social feed REST API reference for SharePoint](social-feed-rest-api-reference-for-sharepoint.md) - - + + - [SPSocialPostCreationData](https://msdn.microsoft.com/library/Microsoft.Office.Server.Social.SPSocialPostCreationData.aspx) and [SPSocialDataItem](https://msdn.microsoft.com/library/Microsoft.Office.Server.Social.SPSocialDataItem.aspx) in the server object model - - + + diff --git a/docs/general-development/how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md b/docs/general-development/how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md index 21e914aec..7b5605045 100644 --- a/docs/general-development/how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md +++ b/docs/general-development/how-to-integrate-maps-with-windows-phone-apps-and-sharepoint-lists.md @@ -1,291 +1,149 @@ --- title: Integrate maps with Windows Phone apps and SharePoint lists -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to integrate location information and maps in SharePoint lists and location-based web and mobile SharePoint Add-ins, by using the new Geolocation field, and by creating your own geolocation-based field types. +ms.date: 06/09/2022 ms.assetid: 7e0550bc-92d1-407f-b8ba-1371c63bd16e -localization_priority: Normal +ms.localizationpriority: medium --- - - # Integrate maps with Windows Phone apps and SharePoint lists -Learn how to integrate location information and maps in SharePoint lists and location-based web and mobile SharePoint Add-ins, by using the new Geolocation field, and by creating your own geolocation-based field types. -SharePoint introduces a new field type named Geolocation that enables you to annotate SharePoint lists with location information. In columns of type Geolocation, you can enter location information as a pair of latitude and longitude coordinates in decimal degrees or retrieve the coordinates of the user's current location from the browser, if the browser implements the W3C Geolocation API. In the list, SharePoint displays the location on a map powered by Bing Maps. Together, the Geolocation field and the Map View enable you to give a spatial context to any information by integrating data from SharePoint into a mapping experience, and let your users engage in new ways in your web and mobile apps and solutions. We'll help you create a simple Windows 7 mobile app which uses the SharePoint Geolocation field type feature to use mapping capabilities so you can display maps on mobile SharePoint Add-in list items. - - - +Learn how to integrate location information and maps in SharePoint lists and location-based web and mobile SharePoint Add-ins, by using the new Geolocation field, and by creating your own geolocation-based field types. -> **Important:** -> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). - - - +SharePoint introduces a new field type named Geolocation that enables you to annotate SharePoint lists with location information. In columns of type Geolocation, you can enter location information as a pair of latitude and longitude coordinates in decimal degrees or retrieve the coordinates of the user's current location from the browser, if the browser implements the W3C Geolocation API. In the list, SharePoint displays the location on a map powered by Bing Maps. Together, the Geolocation field and the Map View enable you to give a spatial context to any information by integrating data from SharePoint into a mapping experience, and let your users engage in new ways in your web and mobile apps and solutions. We'll help you create a simple Windows 7 mobile app which uses the SharePoint Geolocation field type feature to use mapping capabilities so you can display maps on mobile SharePoint Add-in list items. +> [!IMPORTANT] +> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). ## Prerequisites for creating a map-based Windows phone app - Ensure that you have the following installed: - - - - SharePoint - - - Visual Studio 2012 - - - Visual Studio Express 2010 with new the SharePoint phone templates from [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) - - - Access to a SharePoint list, with sufficient privileges to add a column - - - The Bing Maps key deployed to your server; see [How to: Set the Bing Maps key at the web and farm level in SharePoint](how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md) - - ## Step 1: Create a SharePoint field by using the Geolocation feature - The Geolocation column is not available by default in SharePoint lists. You have to write code to add the column to a SharePoint list. We'll show you how to add the Geolocation field to a list programmatically by using the SharePoint client object model. After you add the field to the list, you can add Geolocation field as a feature to the list. - - - ### To create the Visual Studio project - 1. Log on as an administrator to the server running SharePoint. - - -2. Start **Visual Studio** and choose **File**, **New Project**. The **New Project** dialog box opens. - - -3. In the **New Project** dialog box, choose **Visual C#**, choose **SharePoint**, and then choose the **SharePoint** Project type. - - -4. Name the project. In this example, we use **GeoList**. Choose the **OK** button. - - -5. In the **SharePoint Customization Wizard**, enter the URL for the site collection that uses the same SharePoint list that you want to access for phone development. - - -6. In **Solution Explorer**, open the shortcut menu for the **GeoList** project, and then choose **Add**, **New Item**. - - -7. In the **Add New Item** dialog box, choose **List**. Name the list. In this example, we use **ServiceCalls**. - - -8. In the **Choose List Settings** dialog box, add a display name. In this example, we use **Service Calls**. For **Choose to customize the list based on**, choose **Default (Blank)**, as shown in Figure 1. - - Then, choose **Finish**. - - - **Figure 1. Adding the SharePoint list by using the SharePoint List wizard** +1. Start **Visual Studio** and choose **File**, **New Project**. The **New Project** dialog box opens. +1. In the **New Project** dialog box, choose **Visual C#**, choose **SharePoint**, and then choose the **SharePoint** Project type. +1. Name the project. In this example, we use **GeoList**. Choose the **OK** button. +1. In the **SharePoint Customization Wizard**, enter the URL for the site collection that uses the same SharePoint list that you want to access for phone development. +1. In **Solution Explorer**, open the shortcut menu for the **GeoList** project, and then choose **Add**, **New Item**. +1. In the **Add New Item** dialog box, choose **List**. Name the list. In this example, we use **ServiceCalls**. +1. In the **Choose List Settings** dialog box, add a display name. In this example, we use **Service Calls**. For **Choose to customize the list based on**, choose **Default (Blank)**, as shown in Figure 1. - - - ![Adding the SharePoint list using the wizard](../images/SP15Con_HowToCreateMapBasedPhoneApp_Fig1.png) - + Then, choose **Finish**. - + **Figure 1. Adding the SharePoint list by using the SharePoint List wizard** - + ![Adding the SharePoint list using the wizard](../images/SP15Con_HowToCreateMapBasedPhoneApp_Fig1.png) ### To add a Feature to the SharePoint list - 1. In **Solution Explorer**, and then expand the **Features** node. - - -2. Open the shortcut menu for the **Feature1** node, and then choose **Add**, **Add Event Receiver**. - - -3. Uncomment the **FeatureActivated** method and **FeatureDeactivating** method, and then add the following code. - -```cs - -public override void FeatureActivated(SPFeatureReceiverProperties properties) -{ - SPWeb site = properties.Feature.Parent as SPWeb; - SPList list = site.Lists.TryGetList("Service Calls"); - if (list != null) +1. Open the shortcut menu for the **Feature1** node, and then choose **Add**, **Add Event Receiver**. +1. Uncomment the **FeatureActivated** method and **FeatureDeactivating** method, and then add the following code. + + ```csharp + public override void FeatureActivated(SPFeatureReceiverProperties properties) { - list.Fields.AddFieldAsXml( - "", - true, - SPAddFieldOptions.Default); - list.Update(); + SPWeb site = properties.Feature.Parent as SPWeb; + SPList list = site.Lists.TryGetList("Service Calls"); + if (list != null) + { + list.Fields.AddFieldAsXml( + "", + true, + SPAddFieldOptions.Default); + list.Update(); + } } -} -public override void FeatureDeactivating( - SPFeatureReceiverProperties properties) -{ - SPWeb site = properties.Feature.Parent as SPWeb; - SPList list = site.Lists.TryGetList("Service Calls"); - if (list != null) + public override void FeatureDeactivating( + SPFeatureReceiverProperties properties) { - list.Delete(); + SPWeb site = properties.Feature.Parent as SPWeb; + SPList list = site.Lists.TryGetList("Service Calls"); + if (list != null) + { + list.Delete(); + } } -} -``` + ``` -4. Build the solution by choosing the F6 key. - - +1. Build the solution by choosing the F6 key. ## Step 2: Deploy the list and enter data into the location-based SharePoint list - -In this step, you deploy the newly created list from Visual Studio and use the new Location field in SharePoint. - - - +In this step, you deploy the newly created list from Visual Studio and use the new Location field in SharePoint. ### To deploy the SharePoint list - - In **Solution Explorer**, open the shortcut menu for the **GeoList** project, and then choose **Deploy**. - - ### To enter data in the new SharePoint list with the Geolocation field - 1. After the list successfully deploys, open the site you are using for phone development. - - -2. Choose **More**, and then choose the **Service Calls** list. - - -3. Choose **Add New Item**. - - -4. Provide a title for the **Title** field. For this example, use **New Geolocation Item**. - - -5. Choose **Use Current Location** in the **Location** field, or you can choose **Specify Location**, and then enter values for **Longitude** and **Latitude**. - - -6. Choose **Save**. - - +1. Choose **More**, and then choose the **Service Calls** list. +1. Choose **Add New Item**. +1. Provide a title for the **Title** field. For this example, use **New Geolocation Item**. +1. Choose **Use Current Location** in the **Location** field, or you can choose **Specify Location**, and then enter values for **Longitude** and **Latitude**. +1. Choose **Save**. ## Step 3: Build a phone app for the location-based List - -In this step, you create a phone app that uses the SharePoint list you created previously in step 1 and step 2. - - - +In this step, you create a phone app that uses the SharePoint list you created previously in step 1 and step 2. 1. Log on to the Phone Development environment on the client side. - - -2. Start Visual Studio 2010 Express with the new SharePoint templates. - - -3. On the menu bar, choose **File**, **New Project**. - +1. Start Visual Studio 2010 Express with the new SharePoint templates. +1. On the menu bar, choose **File**, **New Project**. + The **New Project** dialog box opens. - - -4. In the **New Project** dialog box, choose **Visual C#**, **Silverlight for Windows Phone**, **Windows Phone SharePoint List Application**. - - -5. Name the project. In this example, we use GeoApp. Choose the **OK** button. - - -6. In the **SharePoint Phone Application Wizard**, enter the URL of the SharePoint site where you have deployed the list in **Step 2. Deploy the list and enter data into the location-based SharePoint list**, and then choose **Find Lists**. - - -7. Choose the **Service Calls** list, and then choose **Next**. - - -8. On the **Choose Views** page, choose **All Items**, and then choose **Next**. - - -9. On the **Choose Operations** page, choose **Display**, and then choose **Next**. - - -10. On the **Choose Fields** page, choose the field you want to see on your phone app, and then choose **Next**. - - -11. On the **Order Fields** page, reorder the fields as you need, and then choose **Finish**. - - + +1. In the **New Project** dialog box, choose **Visual C#**, **Silverlight for Windows Phone**, **Windows Phone SharePoint List Application**. +1. Name the project. In this example, we use GeoApp. Choose the **OK** button. +1. In the **SharePoint Phone Application Wizard**, enter the URL of the SharePoint site where you have deployed the list in **Step 2. Deploy the list and enter data into the location-based SharePoint list**, and then choose **Find Lists**. +1. Choose the **Service Calls** list, and then choose **Next**. +1. On the **Choose Views** page, choose **All Items**, and then choose **Next**. +1. On the **Choose Operations** page, choose **Display**, and then choose **Next**. +1. On the **Choose Fields** page, choose the field you want to see on your phone app, and then choose **Next**. +1. On the **Order Fields** page, reorder the fields as you need, and then choose **Finish**. ## Step 4: Test and validate your app - In this step, you can run your app and validate it. - - - 1. In Visual Studio, choose **Debug**, **Start Debugging**. - - -2. When prompted, log on, using credentials that have admin rights on the server running SharePoint. - - -3. For this example, choose the first entry, **Brian Cox**. - - -4. Choose the **Map It** link found in the **Location** field. - - -5. On the **Allow maps to access and use your location** privacy policy screen, choose **Allow**, as shown in Figure 2. - - **Figure 2. Mobile app request to have access to your current location** - - - - ![Allow privacy policy for maps](../images/SP15Con_HowToCreateMapBasedPhoneApp_Fig2.png) - +1. When prompted, log on, using credentials that have admin rights on the server running SharePoint. +1. For this example, choose the first entry, **Brian Cox**. +1. Choose the **Map It** link found in the **Location** field. +1. On the **Allow maps to access and use your location** privacy policy screen, choose **Allow**, as shown in Figure 2. - The map view is displayed, as shown in Figure 3. - + **Figure 2. Mobile app request to have access to your current location** - **Figure 3.Mobile App display location in Bing map** + ![Allow privacy policy for maps](../images/SP15Con_HowToCreateMapBasedPhoneApp_Fig2.png) - + The map view is displayed, as shown in Figure 3. - ![Map view on mobile app](../images/SP15Con_HowToCreateMapBasedPhoneApp_Fig3.png) - + **Figure 3.Mobile App display location in Bing map** -> [!NOTE] -> The user's experience of the Geolocation field can be different on mobile devices than in browsers. The **Use Specific Location** option, available in the browser, is not available for mobile devices. For mobile devices, only one option is available: **Use my location**. - - - + ![Map view on mobile app](../images/SP15Con_HowToCreateMapBasedPhoneApp_Fig3.png) +> [!NOTE] +> The user's experience of the Geolocation field can be different on mobile devices than in browsers. The **Use Specific Location** option, available in the browser, is not available for mobile devices. For mobile devices, only one option is available: **Use my location**. ## See also - - - -- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) - - -- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) - - -- [How to: Extend the Geolocation field type using client-side rendering](how-to-extend-the-geolocation-field-type-using-client-side-rendering.md) - - -- [How to: Add a Geolocation column to a list programmatically in SharePoint](how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md) - - -- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) - - -- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=27570) - - -- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) - - +- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) +- [Integrating location and map functionality in SharePoint](integrating-location-and-map-functionality-in-sharepoint.md) +- [How to: Extend the Geolocation field type using client-side rendering](how-to-extend-the-geolocation-field-type-using-client-side-rendering.md) +- [How to: Add a Geolocation column to a list programmatically in SharePoint](how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md) +- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) +- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=29233) +- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) diff --git a/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-net-client-object.md b/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-net-client-object.md index d85693646..bc1d68ae4 100644 --- a/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-net-client-object.md +++ b/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-net-client-object.md @@ -1,154 +1,110 @@ --- title: Read and write to the social feed by using the .NET client object model in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Create a console application that reads and writes to the social feed by using the SharePoint .NET client object model. +ms.date: 01/05/2020 ms.assetid: 3c15ede5-8a59-47e6-a0b2-c17ec6bf4ae1 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Read and write to the social feed by using the .NET client object model in SharePoint Create a console application that reads and writes to the social feed by using the SharePoint .NET client object model. ## Prerequisites for creating a console application that reads and writes to the social feed by using the SharePoint .NET client object model - The console application that you'll create retrieves a target user's feed and prints the root post from each thread in a numbered list. Then, it publishes a simple text reply to the selected thread. The same method ( [CreatePost](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFeedManager.CreatePost.aspx) ) is used to publish both posts and replies to the feed. - - - + To create the console application, you'll need the following: - - - - SharePoint with My Site configured, with personal sites created for the current user and a target user, and with a few posts written by the target user - - - Visual Studio 2012 - - - **Full Control** access permissions to the User Profile service application for the logged-on user - + > [!NOTE] > If you're not developing on the computer that is running SharePoint, get the [SharePoint Client Components](https://www.microsoft.com/download/details.aspx?id=35585) download that contains SharePoint client assemblies. - - - - ### Core concepts to know about working with SharePoint social feeds - Table 1 contains links to articles that describe core concepts you should know before you get started. - - - **Table 1. Core concepts for working with SharePoint social feeds** - -|**Article title**|**Description**| -|:-----|:-----| -| [Get started developing with social features in SharePoint](get-started-developing-with-social-features-in-sharepoint.md)
    |Find out how to get started programming with social feeds and microblog posts, following people and content (documents, sites, and tags.md), and working with user profiles.
    | -| [Work with social feeds in SharePoint](work-with-social-feeds-in-sharepoint.md)
    |Learn about common programming tasks for working with social feeds and the API that you use to perform the tasks.
    | - +| Article title | Description | +| :------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [Get started developing with social features in SharePoint](get-started-developing-with-social-features-in-sharepoint.md) | Find out how to get started programming with social feeds and microblog posts, following people and content (documents, sites, and tags.md), and working with user profiles. | +| [Work with social feeds in SharePoint](work-with-social-feeds-in-sharepoint.md) | Learn about common programming tasks for working with social feeds and the API that you use to perform the tasks. | ## Create the console application in Visual Studio 2012 and add references to client assemblies - - 1. On your development computer, open Visual Studio 2012. - - -2. On the menu bar, choose **File**, **New**, **Project**. - - -3. In the **New Project** dialog box, choose **.NET Framework 4.5** from the drop-down list at the top of the dialog box. - - -4. From the **Templates** list, choose **Windows**, and then choose the **Console Application** template. - - -5. Name the project ReadWriteMySite, and then choose the **OK** button. - - -6. Add references to the client assemblies, as follows: - - a. In **Solution Explorer**, open the shortcut menu for the **ReadWriteMySite** project, and then choose **Add Reference**. - - b. In the **Reference Manager** dialog box, choose the following assemblies: - - - **Microsoft.SharePoint.Client** - - - **Microsoft.SharePoint.Client.Runtime** - - - **Microsoft.SharePoint.Client.UserProfiles** - - If you are developing on the computer that is running SharePoint, the assemblies are in the **Extensions** category. Otherwise, browse to the location that has the client assemblies you downloaded (see [SharePoint Client Components](https://www.microsoft.com/download/details.aspx?id=35585)). - - -7. In the Program.cs file, add the following **using** statements. - -```cs +1. On the menu bar, choose **File**, **New**, **Project**. +. In the **New Project** dialog box, choose **.NET Framework 4.5** from the drop-down list at the top of the dialog box. +1. From the **Templates** list, choose **Windows**, and then choose the **Console Application** template. +1. Name the project ReadWriteMySite, and then choose the **OK** button. +1. Add references to the client assemblies, as follows: + + 1. In **Solution Explorer**, open the shortcut menu for the **ReadWriteMySite** project, and then choose **Add Reference**. + 1. In the **Reference Manager** dialog box, choose the following assemblies: + + - **Microsoft.SharePoint.Client** + - **Microsoft.SharePoint.Client.Runtime** + - **Microsoft.SharePoint.Client.UserProfiles** + + If you are developing on the computer that is running SharePoint, the assemblies are in the **Extensions** category. Otherwise, browse to the location that has the client assemblies you downloaded (see [SharePoint Client Components](https://www.microsoft.com/download/details.aspx?id=35585)). + +1. In the Program.cs file, add the following `using` statements. + +```csharp using Microsoft.SharePoint.Client; using Microsoft.SharePoint.Client.Social; ``` - ## Retrieve the social feed for a target user by using the SharePoint .NET client object model - - 1. Declare variables for the server URL and target user's account credentials. - - ```cs + + ```csharp const string serverUrl = "http://serverName/"; const string targetUser = "domainName\\userName"; ``` > [!NOTE] > Remember to replace the `http://serverName/` and `domainName\\userName` placeholder values before you run the code. - -2. In the **Main** method, initialize the SharePoint client context. - - ```cs + +1. In the `Main()` method, initialize the SharePoint client context. + + ```csharp ClientContext clientContext = new ClientContext(serverUrl); ``` -3. Create the [SocialFeedManager](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFeedManager.aspx) instance. - - ```cs +1. Create the [SocialFeedManager](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFeedManager.aspx) instance. + + ```csharp SocialFeedManager feedManager = new SocialFeedManager(clientContext); ``` -4. Specify the parameters for the feed content that you want to retrieve. - - ```cs +1. Specify the parameters for the feed content that you want to retrieve. + + ```csharp SocialFeedOptions feedOptions = new SocialFeedOptions(); feedOptions.MaxThreadCount = 10; ``` The default options return the first 20 threads in the feed, sorted by last modified date. - -5. Get the target user's feed. - - ```cs + +1. Get the target user's feed. + + ```csharp ClientResult feed = feedManager.GetFeedFor(targetUser, feedOptions); clientContext.ExecuteQuery(); ``` - [GetFeedFor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFeedManager.GetFeedFor.aspx) returns a **ClientResult** object that stores the collection of threads in its [Value]( https://msdn.microsoft.com/library/ee543385.aspx ) property. - - + [GetFeedFor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFeedManager.GetFeedFor.aspx) returns a `ClientResult` object that stores the collection of threads in its [Value]( https://msdn.microsoft.com/library/ee543385.aspx ) property. ## Iterate through and read from the social feed by using the SharePoint .NET client object model - -The following code iterates through the threads in the feed. It checks whether each thread has the [CanReply](https://docs.microsoft.com/previous-versions/office/sharepoint-csom/jj163554(v=office.15)) attribute and then gets the thread identifier and the text of the root post. The code also creates a dictionary to store the thread identifier (which is used to reply to a thread) and writes the text of the root post to the console. +The following code iterates through the threads in the feed. It checks whether each thread has the [CanReply](/previous-versions/office/sharepoint-csom/jj163554(v=office.15)) attribute and then gets the thread identifier and the text of the root post. The code also creates a dictionary to store the thread identifier (which is used to reply to a thread) and writes the text of the root post to the console. -```cs +```csharp Dictionary idDictionary = new Dictionary(); for (int i = 0; i < feed.Value.Threads.Length; i++) { @@ -162,55 +118,49 @@ for (int i = 0; i < feed.Value.Threads.Length; i++) } ``` - ## Post a reply to the social feed by using the SharePoint .NET client object model - - 1. (UI-related only) Get the thread to reply to and prompt for the user's reply. - -```cs -Console.Write("Which post number do you want to reply to? "); -string threadToReplyTo = ""; -int threadNumber = int.Parse(Console.ReadLine()) - 1; -idDictionary.TryGetValue(threadNumber, out threadToReplyTo); -Console.Write("Type your reply: "); -``` -2. Define the reply. The following code gets the reply's text from the console application. - -```cs -SocialPostCreationData postCreationData = new SocialPostCreationData(); -postCreationData.ContentText = Console.ReadLine(); -``` + ```csharp + Console.Write("Which post number do you want to reply to? "); + string threadToReplyTo = ""; + int threadNumber = int.Parse(Console.ReadLine()) - 1; + idDictionary.TryGetValue(threadNumber, out threadToReplyTo); + Console.Write("Type your reply: "); + ``` -3. Publish the reply. The _threadToReplyTo_ parameter represents of the thread's [Id](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialThread.Id.aspx) property. - -```cs -feedManager.CreatePost(threadToReplyTo, postCreationData); -clientContext.ExecuteQuery(); -``` +1. Define the reply. The following code gets the reply's text from the console application. + + ```csharp + SocialPostCreationData postCreationData = new SocialPostCreationData(); + postCreationData.ContentText = Console.ReadLine(); + ``` + +1. Publish the reply. The _threadToReplyTo_ parameter represents of the thread's [Id](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialThread.Id.aspx) property. + + ```csharp + feedManager.CreatePost(threadToReplyTo, postCreationData); + clientContext.ExecuteQuery(); + ``` > [!NOTE] > The [CreatePost](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.Social.SocialFeedManager.CreatePost.aspx) method is also used to publish a root post to the current user's feed by passing **null** for the first parameter. -4. (UI-related only) Exit the program. - - ```cs +1. (UI-related only) Exit the program. + + ```csharp Console.WriteLine("Your reply was published."); Console.ReadKey(false); ``` -5. To test the console application, on the menu bar, choose **Debug**, **Start Debugging**. - - +1. To test the console application, on the menu bar, choose **Debug**, **Start Debugging**. ## Code example: Retrieve a feed and reply to a post by using the SharePoint .NET client object model - The following example is the complete code from the Program.cs file. - -```cs + +```csharp using System; using System.Collections.Generic; using System.Linq; @@ -271,7 +221,7 @@ namespace ReadWriteMySite // Define properties for the reply. SocialPostCreationData postCreationData = new SocialPostCreationData(); postCreationData.ContentText = Console.ReadLine(); - + // Post the reply and make the changes on the server. feedManager.CreatePost(threadToReplyTo, postCreationData); clientContext.ExecuteQuery(); @@ -285,27 +235,13 @@ namespace ReadWriteMySite } ``` - ## Next steps - To learn how to do more read tasks and write tasks with the social feed by using the .NET client object model, see the following: - - - -- [How to: Create and delete posts and retrieve the social feed by using the .NET client object model in SharePoint](how-to-create-and-delete-posts-and-retrieve-the-social-feed-by-using-the-net-cli.md) - - +- [How to: Create and delete posts and retrieve the social feed by using the .NET client object model in SharePoint](how-to-create-and-delete-posts-and-retrieve-the-social-feed-by-using-the-net-cli.md) ## See also - - - -- [Get started developing with social features in SharePoint](get-started-developing-with-social-features-in-sharepoint.md) - - -- [Work with social feeds in SharePoint](work-with-social-feeds-in-sharepoint.md) - - +- [Get started developing with social features in SharePoint](get-started-developing-with-social-features-in-sharepoint.md) +- [Work with social feeds in SharePoint](work-with-social-feeds-in-sharepoint.md) diff --git a/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-rest-service-in-s.md b/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-rest-service-in-s.md index 8e9df7ab8..a57a42744 100644 --- a/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-rest-service-in-s.md +++ b/docs/general-development/how-to-learn-to-read-and-write-to-the-social-feed-by-using-the-rest-service-in-s.md @@ -1,9 +1,9 @@ --- title: Read and write to the social feed by using the REST service in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to create a SharePoint-hosted app that uses the REST service to publish a post and get a personal feed for the current user. +ms.date: 06/13/2022 ms.assetid: 1da8d484-3666-42c3-8a8f-8b3ef93e96e9 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -17,7 +17,7 @@ Create a SharePoint-hosted app that uses the REST service to publish a post and This article assumes that you create the SharePoint Add-in by using Napa on an Office 365 Developer Site. If you're using this development environment, you've already met the prerequisites. > [!NOTE] -> Go to [Set up a development environment for SharePoint Add-ins on Office 365](https://msdn.microsoft.com/library/b22ce52a-ae9e-4831-9b68-c9210af6dc54%28Office.15%29.aspx) to find out how to sign up for a Developer Site and start using Napa. +> Go to [Set up a development environment for SharePoint Add-ins on Office 365](/sharepoint/dev/sp-add-ins/set-up-a-development-environment-for-sharepoint-add-ins-on-office-365) to find out how to sign up for a Developer Site and start using Napa. diff --git a/docs/general-development/how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md b/docs/general-development/how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md index e419899e4..13960ed2c 100644 --- a/docs/general-development/how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md +++ b/docs/general-development/how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md @@ -1,204 +1,156 @@ --- title: Locate and copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll -ms.date: 09/25/2017 +description: If you want to programmatically add an Excel Web Access web part to a SharePoint page and programmatically change the Excel Web Access web part, you must add a reference to the required SharePoint DLLs. +ms.date: 01/05/2020 keywords: how to,howdoi,howto,WebUI DLL f1_keywords: - how to,howdoi,howto,WebUI DLL -ms.prod: sharepoint ms.assetid: 09ad5d5e-1678-45e4-8159-23ef56f84215 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Locate and copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll -If you want to programmatically add an Excel Web Access web part to a SharePoint page and programmatically change the Excel Web Access web part, you must add a reference to the required SharePoint DLLs. For example: - - - - +If you want to programmatically add an Excel Web Access web part to a SharePoint page and programmatically change the Excel Web Access web part, you must add a reference to the required SharePoint DLLs. For example: - Microsoft.Office.Excel.WebUI.dll - - - Microsoft.Office.Excel.WebUI.Internal.dll - - - Microsoft.SharePoint.dll - - On the computer running Microsoft SharePoint Server 2010, you can find a copy of Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll in the global assembly cache. Before you can add a reference to Microsoft.Office.Excel.WebUI.dll by using the **Add Reference** dialog box in Microsoft Visual Studio, you must first copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll from the global assembly cache to a folder. Then, you can use the **Browse** tab in the **Add Reference** dialog box to browse to the folder that contains the copy of Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll. - - - - -The following steps show how to: -- Locate Microsoft.Office.Excel.WebUI.dll. - - + +The following steps show how to: + +- Locate Microsoft.Office.Excel.WebUI.dll. - Copy Microsoft.Office.Excel.WebUI.dll from the global assembly cache to a folder of your choice. - -> [!NOTE] -> Repeat the steps to copy Microsoft.Office.Excel.WebUI.Internal.dll from the global assembly cache to a folder. - - - +> [!NOTE] +> Repeat the steps to copy Microsoft.Office.Excel.WebUI.Internal.dll from the global assembly cache to a folder. ### To locate Microsoft.Office.Excel.WebUI.dll +1. To start the command-prompt console, click **Start**, and then click **Run**. +1. In the **Open** field text box, type `cmd`. -1. To start the command-prompt console, click **Start**, and then click **Run**. - - -2. In the **Open** field text box, typecmd. - The command-prompt console appears. - - -3. Use the **cd** command to navigate to the "C:\\Windows\\assembly" directory: - - > [!NOTE] - > The directory structure on your computer might be slightly different. This example uses a computer that has Windows Server 2008 installed. +1. Use the **cd** command to navigate to the **C:\Windows\assembly** directory: - ``` - - cd C:\\Windows\\assembly - ``` + > [!NOTE] + > The directory structure on your computer might be slightly different. This example uses a computer that has Windows Server 2008 installed. -4. Use the **dir** command to display the contents of the "C:\\Windows\\assembly" directory: - - ``` - C:\\Windows\\assembly>dir + ```console + cd C:\Windows\assembly ``` +1. Use the **dir** command to display the contents of the **C:\Windows\assembly** directory: - You will see contents similar to the following: - + ```console + C:\Windows\assembly>dir + ``` + You will see contents similar to the following: -``` - Volume in drive C has no label. - - Directory of C:\\Windows\\assembly + ```console + Volume in drive C has no label. + + Directory of C:\\Windows\\assembly + + 02/20/2010 09:22 AM GAC + 02/20/2010 09:39 AM GAC_32 + 02/20/2010 09:32 AM GAC_64 + 02/22/2010 05:05 PM GAC_MSIL + 02/22/2010 05:35 PM NativeImages_v2.0.50727_32 + 02/22/2010 04:33 PM NativeImages_v2.0.50727_64 + 02/20/2010 10:34 AM NativeImages_v4.0.30219_32 + 02/20/2010 10:35 AM NativeImages_v4.0.30219_64 + 02/22/2010 05:04 PM temp + 02/22/2010 05:05 PM tmp + 0 File(s) 0 bytes + 10 Dir(s) 104,032,665,600 bytes free + ``` -02/20/2010 09:22 AM GAC -02/20/2010 09:39 AM GAC_32 -02/20/2010 09:32 AM GAC_64 -02/22/2010 05:05 PM GAC_MSIL -02/22/2010 05:35 PM NativeImages_v2.0.50727_32 -02/22/2010 04:33 PM NativeImages_v2.0.50727_64 -02/20/2010 10:34 AM NativeImages_v4.0.30219_32 -02/20/2010 10:35 AM NativeImages_v4.0.30219_64 -02/22/2010 05:04 PM temp -02/22/2010 05:05 PM tmp - 0 File(s) 0 bytes - 10 Dir(s) 104,032,665,600 bytes free -``` +1. Use the **cd** command again to change the directory and navigate to the **gac_msil** directory: -5. Use the **cd** command again to change the directory and navigate to the gac_msil directory: - -``` - -C:\\Windows\\assembly>cd gac_msil -``` + ```console + C:\\Windows\\assembly>cd gac_msil + ``` -6. Use the **dir** command to display the content of the "C:\\Windows\\assembly\\GAC_MSIL" directory: - -``` - C:\\Windows\\assembly\\GAC_MSIL>dir -``` +1. Use the **dir** command to display the content of the **C:\Windows\assembly\GAC_MSIL** directory: + ```console + C:\\Windows\\assembly\\GAC_MSIL>dir + ``` You will see contents similar to the following: - - - -``` - Volume in drive C has no label. -Directory of C:\\Windows\\assembly\\GAC_MSIL -... -02/20/2010 07:57 AM Microsoft.Office.Excel.Server.Udf -02/20/2010 07:57 AM Microsoft.Office.Excel.Server.WebServices -02/20/2010 07:57 AM Microsoft.Office.Excel.WebUI -02/20/2010 07:57 AM Microsoft.Office.Excel.WebUI.Internal -... -02/20/2010 07:57 AM Microsoft.SharePoint -... -0 File(s) 0 bytes - 739 Dir(s) 100,594,409,472 bytes free -``` + ```console + Volume in drive C has no label. + Directory of C:\\Windows\\assembly\\GAC_MSIL + ... + 02/20/2010 07:57 AM Microsoft.Office.Excel.Server.Udf + 02/20/2010 07:57 AM Microsoft.Office.Excel.Server.WebServices + + 02/20/2010 07:57 AM Microsoft.Office.Excel.WebUI + 02/20/2010 07:57 AM Microsoft.Office.Excel.WebUI.Internal + ... + 02/20/2010 07:57 AM Microsoft.SharePoint + ... + 0 File(s) 0 bytes + 739 Dir(s) 100,594,409,472 bytes free + ``` -7. Now that you have located Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll, you can copy them to a folder of your choice. - - +1. Now that you have located **Microsoft.Office.Excel.WebUI.dll** and **Microsoft.Office.Excel.WebUI.Internal.dll**, you can copy them to a folder of your choice. ### To copy Microsoft.Office.Excel.WebUI.dll +1. Use the **cd** command again to change the directory to **Microsoft.Office.Excel.WebUI**: -1. Use the **cd** command again to change the directory to "Microsoft.Office.Excel.WebUI": - -``` - -C:\\Windows\\assembly\\GAC_MSIL>cd Microsoft.Office.Excel.WebUI -``` + ```console + C:\Windows\assembly\GAC_MSIL>cd Microsoft.Office.Excel.WebUI + ``` -2. Use the **dir** command to display the contents: - -``` - C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI>dir -``` +1. Use the **dir** command to display the contents: + ```console + C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI>dir + ``` You will see contents similar to the following: - - -``` - Volume in drive C has no label. -Directory of C:\\Windows\\assembly\\GAC_MSIL\Microsoft.Office.Excel.WebUI + ```console + Volume in drive C has no label. + Directory of C:\\Windows\\assembly\\GAC_MSIL\Microsoft.Office.Excel.WebUI -02/20/2010 07:57 AM . -02/20/2010 07:57 AM .. -02/20/2010 07:57 AM 14.0.0.0__71e9bce111e9429c - 0 File(s) 0 bytes - 3 Dir(s) 104,006,115,328 bytes free -``` + 02/20/2010 07:57 AM . + 02/20/2010 07:57 AM .. + 02/20/2010 07:57 AM 14.0.0.0__71e9bce111e9429c + 0 File(s) 0 bytes + 3 Dir(s) 104,006,115,328 bytes free + ``` -3. Use the **cd** command again to change the directory: - -``` - -C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI>cd 14.0.0.0__71e9bce111e9429c -``` +1. Use the **cd** command again to change the directory: -4. Use the **copy** command to copy Microsoft.Office.Excel.WebUI.dll to a folder of your choice. - - In the following example, Microsoft.Office.Excel.WebUI.dll is copied to "C:\\WebUIAssembly", where "C:\\WebUIAssembly" is a folder that you created previously: - + ```console + C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI>cd 14.0.0.0__71e9bce111e9429c + ``` +1. Use the **copy** command to copy **Microsoft.Office.Excel.WebUI.dll** to a folder of your choice. -``` - C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI\\14.0.0.0__71e9bce111e9429c>copy Microsoft.Office.Excel.WebUI.dll c:\\WebUIAssembly - 1 file(s) copied. -``` + In the following example, **Microsoft.Office.Excel.WebUI.dll** is copied to **C:\WebUIAssembly**, where **C:\WebUIAssembly** is a folder that you created previously: + ```console + c:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI\14.0.0.0__71e9bce111e9429c>copy Microsoft.Office.Excel.WebUI.dll c:\WebUIAssembly + 1 file(s) copied. + ``` ## Example The following is an example of the result of using the command prompt to locate and copy Microsoft.Office.Excel.WebUI.dll to a folder. - - - -``` - -C:\\Windows\\assembly>dir +```console +C:\Windows\assembly>dir Volume in drive C has no label. -Directory of C:\\Windows\\assembly +Directory of C:\Windows\assembly 02/20/2010 09:22 AM GAC 02/20/2010 09:39 AM GAC_32 @@ -210,13 +162,13 @@ Directory of C:\\Windows\\assembly 02/20/2010 10:35 AM NativeImages_v4.0.30219_64 02/22/2010 05:04 PM temp 02/22/2010 05:05 PM tmp - 0 File(s) 0 bytes + 0 File(s) 0 bytes 10 Dir(s) 104,032,665,600 bytes free -C:\\Windows\\assembly>cd gac_msil +C:\Windows\assembly>cd gac_msil -C:\\Windows\\assembly\\GAC_MSIL>dir - Volume in drive C has no label. - Directory of C:\\Windows\\assembly\GAC_MSIL +C:\Windows\assembly\GAC_MSIL>dir + Volume in drive C has no label. + Directory of C:\Windows\assembly\GAC_MSIL ... 02/20/2010 07:57 AM Microsoft.Office.Excel.Server.Udf 02/20/2010 07:57 AM Microsoft.Office.Excel.Server.WebServices @@ -225,49 +177,34 @@ C:\\Windows\\assembly\\GAC_MSIL>dir 02/20/2010 07:57 AM Microsoft.Office.Excel.WebUI.Internal ... -C:\\Windows\\assembly\\GAC_MSIL>cd Microsoft.Office.Excel.WebUI +C:\Windows\assembly\GAC_MSIL>cd Microsoft.Office.Excel.WebUI -C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI>dir - Volume in drive C has no label. -Directory of C:\\Windows\\assembly\\GAC_MSIL\Microsoft.Office.Excel.WebUI +C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI>dir + Volume in drive C has no label. +Directory of C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI 02/20/2010 07:57 AM . 02/20/2010 07:57 AM .. 02/20/2010 07:57 AM 14.0.0.0__71e9bce111e9429c - 0 File(s) 0 bytes - 3 Dir(s) 104,006,115,328 bytes free + 0 File(s) 0 bytes + 3 Dir(s) 104,006,115,328 bytes free -C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI>cd 14.0.0.0__71e9bce111e9429c +C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI>cd 14.0.0.0__71e9bce111e9429c -C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI\\14.0.0.0__71e9bce111e9429c>copy Microsoft.Office.Excel.WebUI.dll c:\\WebUIAssembly +C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI\14.0.0.0__71e9bce111e9429c>copy Microsoft.Office.Excel.WebUI.dll c:\WebUIAssembly 1 file(s) copied. -C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.Office.Excel.WebUI\\14.0.0.0__71e9bce111e9429c> +C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Excel.WebUI\14.0.0.0__71e9bce111e9429c> ``` - ## See also - #### Tasks +- [How to: Programmatically Add an Excel Web Access web part to a Page](how-to-programmatically-add-an-excel-web-access-web-part-to-a-page.md) +- [How to: Trust a Location](how-to-trust-a-location.md) - - - - [How to: Programmatically Add an Excel Web Access web part to a Page](how-to-programmatically-add-an-excel-web-access-web-part-to-a-page.md) - - - - [How to: Trust a Location](how-to-trust-a-location.md) #### Concepts - - - - - [Excel Services Alerts](excel-services-alerts.md) - - - - [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) +- [Excel Services Alerts](excel-services-alerts.md) +- [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) diff --git a/docs/general-development/how-to-make-custom-css-files-themable-in-sharepoint.md b/docs/general-development/how-to-make-custom-css-files-themable-in-sharepoint.md index c65e36284..53e554125 100644 --- a/docs/general-development/how-to-make-custom-css-files-themable-in-sharepoint.md +++ b/docs/general-development/how-to-make-custom-css-files-themable-in-sharepoint.md @@ -1,224 +1,117 @@ --- title: Make custom CSS files themable in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to add comment-style markup to a CSS file so that it can be used in the SharePoint theming engine. +ms.date: 09/28/2023 ms.assetid: b8c82c77-c836-47f9-a11e-6c9c656d436b -localization_priority: Priority +ms.localizationpriority: high --- - - # Make custom CSS files themable in SharePoint Learn how to add comment-style markup to a CSS file so that it can be used in the SharePoint theming engine. ## Introduction to annotations - Annotations are special comment-style markup that tell the SharePoint theming engine how to theme properties in a CSS file. When a theme is applied to a site, the theming engine replaces the CSS property values with the appropriate theme values. In SharePoint, you can use annotations to change the color, font, or background image. You can also recolor an image. If you are using custom CSS files, you must add these annotations to the CSS files if you want to use them with the SharePoint theming engine. If you apply a theme to a site that uses custom CSS files, and you haven't added annotations, the CSS properties remain unchanged. This can result in a site that has a mismatched design. - - - + This article describes the available annotations and how to register CSS files. - - - + For more information about custom themes, see [How to: Deploy a custom theme in SharePoint](how-to-deploy-a-custom-theme-in-sharepoint.md) and [How to: Create a master page preview file in SharePoint](how-to-create-a-master-page-preview-file-in-sharepoint.md). - - - ## Add annotations to custom CSS files - Annotations tell the SharePoint theming engine how to theme properties in a CSS file. This section describes the available annotations and how they can be used. - - - ### ReplaceColor annotation - The **ReplaceColor** annotation replaces the color value with the specified theme color. It can be used with CSS properties that define a color value, such as **color**, **background-color**, **border**, and so on. - - - -The following shows the format for the **ReplaceColor** annotation. - - - +The following shows the format for the **ReplaceColor** annotation. - -``` - +```css /* [ReplaceColor(themeColor:"ColorSlot"[, themeShade:"ShadeValue"][, themeTint:"TintValue"][, opacity:"OpacityValue"])] */ - ``` -Replace _ColorSlot_ with the annotation name of the color slot to use. To see a list of available color slots, see the [Color slot mapping](color-palettes-and-fonts-in-sharepoint.md#colorSlots) section in [Color palettes and fonts in SharePoint](color-palettes-and-fonts-in-sharepoint.md). - - - +Replace `ColorSlot` with the annotation name of the color slot to use. To see a list of available color slots, see the [Color slot mapping](color-palettes-and-fonts-in-sharepoint.md#colorSlots) section in [Color palettes and fonts in SharePoint](color-palettes-and-fonts-in-sharepoint.md). + Use the optional **themeShade** parameter if you want to darken the theme color. Replace _ShadeValue_ with a numeric value from 0.0 (no change) to 1.0 (darkest). - - - + Use the optional **themeTint** parameter if you want to lighten the theme color. Replace _TintValue_ with a numeric value from 0.0 (no change) to 1.0 (lightest). - - - + Use the optional **opacity** parameter if you want to specify the opacity of the theme color. Replace _OpacityValue_ with a numeric value that specifies the opacity setting. The opacity setting ranges from 0.0 (fully transparent) to 1.0 (fully opaque). - - - + The following shows examples of the **ReplaceColor** annotation being used in a CSS file. - - - - -- `/* [ReplaceColor(themeColor:"BodyText")] */ color:#444;` - - -- `/* [ReplaceColor(themeColor:"BackgroundOverlay",opacity:"0.5")] */ background-color:#fff;` - - -- `/* [ReplaceColor(themeColor:"EmphasisBackground",themeTint:"0.05")] */ background-color:#f2faff;` - - + +- `/* [ReplaceColor(themeColor:"BodyText")] */ color:#444;` +- `/* [ReplaceColor(themeColor:"BackgroundOverlay",opacity:"0.5")] */ background-color:#fff;` +- `/* [ReplaceColor(themeColor:"EmphasisBackground",themeTint:"0.05")] */ background-color:#f2faff;` ### ReplaceFont annotation - The **ReplaceFont** annotation adds the specified theme font to the list of available fonts. It can be used with the **font** and **font-family** CSS properties. - - - -The following shows the format for the **ReplaceFont** annotation. - - - - +The following shows the format for the **ReplaceFont** annotation. -``` - +```css /* [ReplaceFont(themeFont:"FontSlot")] */ ``` Replace _FontSlot_ with the name of the font slot to use. To see a list of available font slots, see the [Font slots](color-palettes-and-fonts-in-sharepoint.md#fontSlot) section in [Color palettes and fonts in SharePoint](color-palettes-and-fonts-in-sharepoint.md). - - - + The following shows an example of the **ReplaceFont** annotation. In this example, if the **body** font slot is defined as Courier in the theme, Courier will be added as the first item in the list of available fonts in the **Choose the Look** wizard. - - - -- `/* [ReplaceFont(themeFont:"body")] */ font-family:"Segoe UI","Segoe",Tahoma,Helvetica,Arial,sans-serif;` - - +- `/* [ReplaceFont(themeFont:"body")] */ font-family:"Segoe UI","Segoe",Tahoma,Helvetica,Arial,sans-serif;` ### ReplaceBGImage annotation - The **ReplaceBGImage** annotation replaces the background image in the CSS file with the theme background image. It can be used with the **background** and **background-image** CSS properties. - - - -The following shows the format for the **ReplaceBGImage** annotation. The **ReplaceBGImage** annotation can also be used with the **AlphaImageLoader** filter to support earlier versions of Internet Explorer. - - - - +The following shows the format for the **ReplaceBGImage** annotation. The **ReplaceBGImage** annotation can also be used with the **AlphaImageLoader** filter to support earlier versions of Internet Explorer. -``` +```css /* [ReplaceBGImage] */ ``` - ### RecolorImage annotation - The **RecolorImage** annotation recolors the image specified. - - - -The following describes the format of the **RecolorImage** annotation. - - - - +The following describes the format of the **RecolorImage** annotation. -``` +```css /* [RecolorImage(themeColor:"ColorSlot"[, method:["Tinting"|"Blending"|"Filling"]][, includeRectangle: {x:x-Setting,y:y-Setting,width:RegionWidth,height:RegionHeight})] */ - ``` Replace _ColorSlot_ with the annotation name of the color slot. To see a list of available color slots, see the [Color slot mapping](color-palettes-and-fonts-in-sharepoint.md#colorSlots) section in [Color palettes and fonts in SharePoint](color-palettes-and-fonts-in-sharepoint.md). - - - + Use the optional **method** parameter if you want to specify the recoloring method. - - - + Use the optional **includeRectangle** parameter if you want to recolor only a specific region of an image. Replace _x-Setting_, _y-Setting_, _RegionWidth_, and _RegionHeight_ with the x-coordinate, y-coordinate, width, and height of the region that you want to recolor. - - - + The following shows examples of the **RecolorImage** annotation being used in a CSS file. - - - -- `/* [RecolorImage(themeColor:"SubtleBodyText",method:"Tinting")] */ background-image:url("/_layouts/15/images/tabtitlerowbottombg.png?rev=23");` - - -- `/* [RecolorImage(themeColor:"BodyText",method:"Filling",includeRectangle:{x:161,y:178,width:16;height:16})] */ background:url("/_layouts/15/images/spcommon.png?rev=23") no-repeat -161px -178px;` - - +- `/* [RecolorImage(themeColor:"SubtleBodyText",method:"Tinting")] */ background-image:url("/_layouts/15/images/tabtitlerowbottombg.png?rev=23");` +- `/* [RecolorImage(themeColor:"BodyText",method:"Filling",includeRectangle:{x:161,y:178,width:16;height:16})] */ background:url("/_layouts/15/images/spcommon.png?rev=23") no-repeat -161px -178px;` ## Upload the CSS file to the Themable folder in the Style library - Place the custom CSS files in the Themable folder in the Style library (not the Themable folder in the Master Page Gallery). Only CSS files that are stored in the Themable folder in the Style library are recognized by the theming engine. The Themable folder is created automatically for publishing sites. Otherwise, you can create the Themable folder in the correct location (http:// _SiteCollectionName_/Style Library/ _language_/Themable/). - + > [!NOTE] -> The name of the _language_ folder must be in the 4-digit format _ll-cc_ to identify the language and culture, respectively. For example, en-us or ar-sa. For more information, see [Language identifiers and OptionState Id values in Office 2013](https://technet.microsoft.com/library/cc179219.aspx). - - - +> The name of the _language_ folder must be in the 4-digit format _ll-cc_ to identify the language and culture, respectively. For example, en-us or ar-sa. For more information, see [Language identifiers and OptionState Id values in Office 2013](https://technet.microsoft.com/library/cc179219.aspx). CSS files must be checked in and published. If CSS files are changed, you must reapply the theme for the changes to be recognized. - - - ## Register the CSS file - -You must register the CSS file with a master page before the CSS file can be used by the theming engine. This directs the master page to the CSS file when you apply a theme to a site. To register a CSS file, you add a **** element to the **** element of the master page. The following shows the format of the **** element. - - - +You must register the CSS file with a master page before the CSS file can be used by the theming engine. This directs the master page to the CSS file when you apply a theme to a site. To register a CSS file, you add a **\** element to the `` element of the master page. The following shows the format of the **\** element. ```HTML - ``` -Replace _CSSFileLocation_ with the location of the CSS file. - - - -The following is an example of an **** element. - - - - +Replace _CSSFileLocation_ with the location of the CSS file. +The following is an example of an **\** element. ```HTML @@ -229,34 +122,12 @@ The following is an example of an **** element. > [!NOTE] > The **%$SPUrl** token cannot be used on SharePoint Foundation 2013. You must use a URL to specify the location of the CSS file. - - - - ## See also - - - -- [Themes overview for SharePoint](themes-overview-for-sharepoint.md) - - -- [How to: Deploy a custom theme in SharePoint](how-to-deploy-a-custom-theme-in-sharepoint.md) - - -- [Upgrade custom themes and CSS to SharePoint](upgrade-custom-themes-and-css-to-sharepoint.md) - - -- [How to: Create a master page preview file in SharePoint](how-to-create-a-master-page-preview-file-in-sharepoint.md) - - -- [Color palettes and fonts in SharePoint](color-palettes-and-fonts-in-sharepoint.md) - - -- [SharePoint Team Blog: Show off your style with SharePoint theming](https://blogs.office.com/b/sharepoint/archive/2012/10/29/show-off-your-style-with-sharepoint-theming.aspx) - - -- [SharePoint Design Manager branding and design capabilities](sharepoint-design-manager-branding-and-design-capabilities.md) - - +- [Themes overview for SharePoint](themes-overview-for-sharepoint.md) +- [How to: Deploy a custom theme in SharePoint](how-to-deploy-a-custom-theme-in-sharepoint.md) +- [Upgrade custom themes and CSS to SharePoint](upgrade-custom-themes-and-css-to-sharepoint.md) +- [How to: Create a master page preview file in SharePoint](how-to-create-a-master-page-preview-file-in-sharepoint.md) +- [Color palettes and fonts in SharePoint](color-palettes-and-fonts-in-sharepoint.md) +- [SharePoint Design Manager branding and design capabilities](sharepoint-design-manager-branding-and-design-capabilities.md) diff --git a/docs/general-development/how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md b/docs/general-development/how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md index 118366b16..0c5e761c7 100644 --- a/docs/general-development/how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md +++ b/docs/general-development/how-to-map-a-network-drive-to-the-sharepoint-master-page-gallery.md @@ -1,9 +1,9 @@ --- title: Map a network drive to the SharePoint Master Page Gallery -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes how to map a network drive to the Master Page Gallery in order to use Design Manager to upload design files in SharePoint. +ms.date: 06/13/2022 ms.assetid: 7d416f6e-2471-4d03-97ae-4e8d907784c6 -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/how-to-programmatically-add-an-excel-web-access-web-part-to-a-page.md b/docs/general-development/how-to-programmatically-add-an-excel-web-access-web-part-to-a-page.md index d76f30cf9..4c62a1f18 100644 --- a/docs/general-development/how-to-programmatically-add-an-excel-web-access-web-part-to-a-page.md +++ b/docs/general-development/how-to-programmatically-add-an-excel-web-access-web-part-to-a-page.md @@ -1,225 +1,168 @@ --- title: Programmatically add an Excel Web Access web part to a page -ms.date: 09/25/2017 +description: This example shows how to programmatically add an Excel Web Access web part to a SharePoint page. It also shows you how to display an Excel workbook programmatically in an Excel Web Access web part. +ms.date: 01/05/2020 keywords: how to,howdoi,howto,webpart f1_keywords: - how to,howdoi,howto,webpart -ms.prod: sharepoint ms.assetid: 858bb0f6-654a-4f12-ba0b-4776bda5ff6d -localization_priority: Normal +ms.localizationpriority: medium --- - - # Programmatically add an Excel Web Access web part to a page -This example shows how to programmatically add an Excel Web Access web part to a SharePoint page. It also shows you how to display an Excel workbook programmatically in an Excel Web Access web part. - - - +This example shows how to programmatically add an Excel Web Access web part to a SharePoint page. It also shows you how to display an Excel workbook programmatically in an Excel Web Access web part. The following project uses Microsoft Visual Studio. > [!NOTE] -> Depending on the Visual Studio version and the Visual Studio integrated development environment (IDE) settings that you are using, the process and steps to create a Visual Studio project could be slightly different from the procedures shown in this topic. - -> [!NOTE] -> It is assumed that you have already created a SharePoint document library and made it a trusted location. For more information, see [How to: Trust a Location](how-to-trust-a-location.md). - - - +> Depending on the Visual Studio version and the Visual Studio integrated development environment (IDE) settings that you are using, the process and steps to create a Visual Studio project could be slightly different from the procedures shown in this topic. +> [!NOTE] +> It is assumed that you have already created a SharePoint document library and made it a trusted location. For more information, see [How to: Trust a Location](how-to-trust-a-location.md). ## Adding a Reference The following steps show how to locate Microsoft.Office.Excel.WebUI.dll and how to add a reference to it. Repeat for Microsoft.Office.Excel.WebUI.Internal.dll and Microsoft.SharePoint.dll. - -> [!NOTE] -> It is assumed that you have already copied Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll from the global assembly cache to a folder of your choice. For more information about how to locate and copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll, see [How to: Locate and Copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll](how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md). - - - +> [!NOTE] +> It is assumed that you have already copied Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll from the global assembly cache to a folder of your choice. For more information about how to locate and copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll, see [How to: Locate and Copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll](how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md). ### To add a reference to Microsoft.Office.Excel.WebUI.dll - 1. On the **Project** menu, click **Add Reference**. - - -2. In the **Add Reference** dialog box, click **Browse**. - +1. In the **Add Reference** dialog box, click **Browse**. + > [!NOTE] - > You can also open the **Add Reference** dialog box in the **Solution Explorer** pane by right-clicking **References** and selecting **Add Reference**. - -3. Browse to the location of Microsoft.Office.Excel.WebUI.dll. - - -4. Select Microsoft.Office.Excel.WebUI.dll, and then click **OK**. - - -5. Click **Add Reference**. A reference to Microsoft.Office.Excel.WebUI.dll is added to your project. - - + > You can also open the **Add Reference** dialog box in the **Solution Explorer** pane by right-clicking **References** and selecting **Add Reference**. -## Instantiating a web part +1. Browse to the location of Microsoft.Office.Excel.WebUI.dll. +1. Select Microsoft.Office.Excel.WebUI.dll, and then click **OK**. +1. Click **Add Reference**. A reference to Microsoft.Office.Excel.WebUI.dll is added to your project. +## Instantiating a web part ### To instantiate the Excel Web Access web part +1. Add the **Microsoft.Office.Excel.WebUI** namespace as a directive to your code, so that when you use the types in this namespace, you do not need to fully qualify them: -1. Add the Microsoft.Office.Excel.WebUI namespace as a directive to your code, so that when you use the types in this namespace, you do not need to fully qualify them: - -```cs - -using Microsoft.Office.Excel.WebUI; -``` - - -```VB.net - Imports Microsoft.Office.Excel.WebUI -``` + ```csharp + using Microsoft.Office.Excel.WebUI; + ``` -2. Instantiate and initialize the Excel Web Access web part, as follows: - -```cs - - ExcelWebRenderer ewaWebPart = new ExcelWebRenderer(); -``` + ```vbnet + Imports Microsoft.Office.Excel.WebUI + ``` +1. Instantiate and initialize the Excel Web Access web part, as follows: -```VB.net - -Dim ewaWebPart As New ExcelWebRenderer() -``` + ```csharp + ExcelWebRenderer ewaWebPart = new ExcelWebRenderer(); + ``` + ```vbnet + Dim ewaWebPart As New ExcelWebRenderer() + ``` ### To display a workbook programmatically +1. In this example, the `AddWebPart()` method takes in the path to an Excel workbook location as an argument. The user provides the path by typing in a Windows Forms text box and clicking a button. -1. In this example, the **AddWebPart** method takes in the path to an Excel workbook location as an argument. The user provides the path by typing in a Windows Forms text box and clicking a button. - **Sample code provided by:** Daniel Mullowney, Microsoft Corporation - - -```cs - -public bool AddWebPart(string sitename, string book) -{ -... -} - private void AddEWAButton_Click(object sender, - EventArgs e) - { - siteurl = textBox1.Text; - bookuri = textBox2.Text; - succeeded = AddWebPart(siteurl, bookuri); - if (succeeded) + ```csharp + public bool AddWebPart(string sitename, string book) + { + ... + } + private void AddEWAButton_Click(object sender, + EventArgs e) { - MessageBox.Show( - success, - appname, - MessageBoxButtons.OK, - MessageBoxIcon.Information); - progressBar1.Value = 1; + siteurl = textBox1.Text; + bookuri = textBox2.Text; + succeeded = AddWebPart(siteurl, bookuri); + if (succeeded) + { + MessageBox.Show( + success, + appname, + MessageBoxButtons.OK, + MessageBoxIcon.Information); + progressBar1.Value = 1; + } } - } -``` - - - + ``` + + ```vbnet + Public Function AddWebPart(ByVal sitename As String, ByVal book As String) As Boolean + ... + End Function + Private Sub AddEWAButton_Click(ByVal sender As Object, ByVal e As EventArgs) + siteurl = textBox1.Text + bookuri = textBox2.Text + succeeded = AddWebPart(siteurl, bookuri) + If succeeded Then + MessageBox.Show(success, appname, MessageBoxButtons.OK, MessageBoxIcon.Information) + progressBar1.Value = 1 + End If + End Sub + ``` -```VB.net - -Public Function AddWebPart(ByVal sitename As String, ByVal book As String) As Boolean -... -End Function -Private Sub AddEWAButton_Click(ByVal sender As Object, ByVal e As EventArgs) - siteurl = textBox1.Text - bookuri = textBox2.Text - succeeded = AddWebPart(siteurl, bookuri) - If succeeded Then - MessageBox.Show(success, appname, MessageBoxButtons.OK, MessageBoxIcon.Information) - progressBar1.Value = 1 - End If -End Sub -``` + > [!IMPORTANT] + > Ensure that the location where the workbook is saved is a trusted location. +1. You can display an Excel workbook programmatically by using the following code. - > **Important:** - > Ensure that the location where the workbook is saved is a trusted location. -2. You can display an Excel workbook programmatically by using the following code. - **Sample code provided by:** Daniel Mullowney, Microsoft Corporation - - - -```cs - -... -// Instantiate Excel Web Access web part. -// Add an Excel Web Access web part in a shared view. -ExcelWebRenderer ewaWebPart = new ExcelWebRenderer(); -ewaWebPart.WorkbookUri = book; -progressBar1.PerformStep(); - -try -{ - webPartManager.AddWebPart(ewaWebPart, "Left", 0); -} -catch (Exception exc) -{ - MessageBox.Show( - addWebPartError + "\\n" + exc.Message, - appName, - MessageBoxButtons.OK, - MessageBoxIcon.Asterisk); - progressBar1.Value = 1; - return b; - -``` - - - - -```VB.net - -'Instantiate Excel Web Access web part. -'Add an Excel Web Access web part in a shared view. -Dim ewaWebPart As New ExcelWebRenderer() -ewaWebPart.WorkbookUri = book -progressBar1.PerformStep() -Try - webPartManager.AddWebPart(ewaWebPart, "Left", 0) -Catch exc As Exception - MessageBox.Show(addWebPartError & vbLf & exc.Message, appName, - MessageBoxButtons.OK, MessageBoxIcon.Asterisk) - progressBar1.Value = 1 - Return b -End Try -``` + ```csharp + ... + // Instantiate Excel Web Access web part. + // Add an Excel Web Access web part in a shared view. + ExcelWebRenderer ewaWebPart = new ExcelWebRenderer(); + ewaWebPart.WorkbookUri = book; + progressBar1.PerformStep(); + try + { + webPartManager.AddWebPart(ewaWebPart, "Left", 0); + } + catch (Exception exc) + { + MessageBox.Show( + addWebPartError + "\\n" + exc.Message, + appName, + MessageBoxButtons.OK, + MessageBoxIcon.Asterisk); + progressBar1.Value = 1; + return b; + ``` + + ```vbnet + 'Instantiate Excel Web Access web part. + 'Add an Excel Web Access web part in a shared view. + Dim ewaWebPart As New ExcelWebRenderer() + ewaWebPart.WorkbookUri = book + progressBar1.PerformStep() + + Try + webPartManager.AddWebPart(ewaWebPart, "Left", 0) + Catch exc As Exception + MessageBox.Show(addWebPartError & vbLf & exc.Message, appName, + MessageBoxButtons.OK, MessageBoxIcon.Asterisk) + progressBar1.Value = 1 + Return b + End Try + ``` ## Example The following example is a Windows Forms application that enables a user to enter information on a SharePoint site and display an Excel workbook saved in a trusted location programmatically. It programmatically creates an Excel Web Access web part on the default.aspx page of the specified site and displays the specified Excel workbook. - - - -The code sample is the code from the Form1.cs and Form1.vb example files described in the previous procedures. The code sample uses two text boxes, a progress bar, and a button. The code is only a portion of the Windows Forms project. For example, the code involving the layout of the form is not shown. - - - - **Sample code provided by:** Daniel Mullowney, Microsoft Corporation - - - +The code sample is the code from the Form1.cs and Form1.vb example files described in the previous procedures. The code sample uses two text boxes, a progress bar, and a button. The code is only a portion of the Windows Forms project. For example, the code involving the layout of the form is not shown. +**Sample code provided by:** Daniel Mullowney, Microsoft Corporation -```cs - +```csharp namespace AddEWATool { using System; @@ -374,14 +317,9 @@ namespace AddEWATool } } } - ``` - - - -```VB.net - +```vbnet Imports System Imports System.Windows.Forms Imports Microsoft.Office.Excel.WebUI @@ -497,37 +435,19 @@ Namespace AddEWATool End Sub End Class End Namespace - - - ``` - ## Robust programming The Excel workbook that you are using must be in a trusted location. - - - ## See also - #### Tasks +- [How to: Locate and Copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll](how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md) - - - - [How to: Locate and Copy Microsoft.Office.Excel.WebUI.dll and Microsoft.Office.Excel.WebUI.Internal.dll](how-to-locate-and-copy-microsoft-office-excel-webui-dll-and-microsoft-office-exc.md) #### Concepts - - - - - [Excel Services Alerts](excel-services-alerts.md) - - - - [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) +- [Excel Services Alerts](excel-services-alerts.md) +- [Excel Services Known Issues and Tips](excel-services-known-issues-and-tips.md) diff --git a/docs/general-development/how-to-refresh-data.md b/docs/general-development/how-to-refresh-data.md index d85dbbb32..1263043e9 100644 --- a/docs/general-development/how-to-refresh-data.md +++ b/docs/general-development/how-to-refresh-data.md @@ -1,12 +1,12 @@ --- title: Refresh data +description: This example shows how to retrieve updated data from external data sources for the open workbook by using the Refresh method. ms.date: 09/25/2017 keywords: how to,howdoi,howto f1_keywords: - how to,howdoi,howto -ms.prod: sharepoint ms.assetid: 6cfd89ff-846e-486b-8f73-a109016813ab -localization_priority: Normal +ms.localizationpriority: medium --- @@ -18,7 +18,7 @@ This example shows how to retrieve updated data from external data sources for t -```cs +```csharp public Status[] Refresh (string sessionId, string connectionName) ``` @@ -32,7 +32,7 @@ End Function If you link directly to Microsoft.Office.Excel.Server.WebServices.dll, the signature for the **Refresh** method is: -```cs +```csharp public void Refresh (string sessionId, string connectionName, out Status[] status) @@ -55,7 +55,7 @@ The following code sample shows how to call the **Refresh** method using Excel W -```cs +```csharp // Instantiate the Web service. ExcelService xlservice = new ExcelService(); diff --git a/docs/general-development/how-to-resolve-errors-and-warnings-when-previewing-a-page-in-sharepoint.md b/docs/general-development/how-to-resolve-errors-and-warnings-when-previewing-a-page-in-sharepoint.md index 9f4751336..82a2d4c73 100644 --- a/docs/general-development/how-to-resolve-errors-and-warnings-when-previewing-a-page-in-sharepoint.md +++ b/docs/general-development/how-to-resolve-errors-and-warnings-when-previewing-a-page-in-sharepoint.md @@ -1,62 +1,37 @@ --- title: Resolve errors and warnings when previewing a page in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: After you convert an HTML file into a SharePoint master page, or after you create a page layout, you can preview that page in the browser. But before you can preview a master page or page layout, you may have to resolve any issues that prevent the server-side preview from rendering your page. +ms.date: 06/13/2022 ms.assetid: 03f72f65-b22b-4304-be92-f44ce0619372 -localization_priority: Priority +ms.localizationpriority: high --- - - # Resolve errors and warnings when previewing a page in SharePoint After you convert an HTML file into a SharePoint master page, or after you create a page layout, you can preview that page in the browser. But before you can preview a master page or page layout, you may have to resolve any issues that prevent the server-side preview from rendering your page. ## Introduction to resolving preview errors - After you convert an HTML file into a SharePoint master page, or after you create a page layout, you can preview that page in the browser. As you edit and save your HTML master page or page layout, you can refresh the preview to see exactly how SharePoint renders your page. - - - + The preview in Design Manager is a live server-side preview, so any snippets or controls on your page, such as a navigation control or a search-driven web part, use live data. Also, when you preview a master page or page layout, you can choose a generic preview of just that file, or you can choose to preview how a specific page in your site renders with that master page or page layout. The server-side preview is a highly useful tool that complements the design-time preview in an HTML editor. For more information, see [How to: Change the preview page in SharePoint Design Manager](how-to-change-the-preview-page-in-sharepoint-design-manager.md). - - - + But before you can preview a master page or page layout, you may have to resolve any issues that prevent the server-side preview from rendering your page. If the server-side preview isn't working, this means that the master page or page layout also won't work after they're applied to your site. In Design Manager, after you convert a master page or create a page layout, you can click the file name or conversion status to preview that file. On the preview page, the notification area at the top of the page displays any errors or warnings. - - - + Here are the preview errors and warnings that you might encounter, and help for how to resolve them. - - - ## HTML file cannot contain \ tags - - ### Message **Your Master Page has one or more HTML \ tags. For your master page to work, remove the tags (but you can leave the content in them).** - - - ### Resolution -SharePoint pages are already wrapped in a **\** tag so that ASP.NET can do post-backs (specifically, a SharePoint.master page contains the **** tag that creates an actual **\** tag when an associated content page is rendered). So, including a **\** tag on your master page or page layout means that there would be nested **\** tags on the final rendering of the page, which is not valid in HTML. In your HTML editor, delete any **\** tags, save the page, and then refresh the preview. - - - -If you want an HTML **\** tag in the page layout, you should put the form within a content placeholder with the ID **PlaceHolderUtilityContent** by adding this code to your HTML page layout: - - - - +SharePoint pages are already wrapped in a **\** tag so that ASP.NET can do post-backs (specifically, a SharePoint.master page contains the **\** tag that creates an actual **\** tag when an associated content page is rendered). So, including a **\** tag on your master page or page layout means that there would be nested **\** tags on the final rendering of the page, which is not valid in HTML. In your HTML editor, delete any **\** tags, save the page, and then refresh the preview. +If you want an HTML **\** tag in the page layout, you should put the form within a content placeholder with the ID **PlaceHolderUtilityContent** by adding this code to your HTML page layout: ```HTML - @@ -65,119 +40,60 @@ If you want an HTML **\** tag in the page layout, you should put the form ``` You can also add the HTML Form web part or the InfoPath Form web part to your page from the Snippet Gallery. For more information, see [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md). - - - ## HTML file must be XML-compliant - - ### Message - **SharePoint requires HTML files to be XML-compliant. Your file isn't XML-compliant, likely because of tag properties without quotes, missing closing tags, or invalid properties in tags. {Type of error, location of error}. Occurred at: {Time}.** - - - +**SharePoint requires HTML files to be XML-compliant. Your file isn't XML-compliant, likely because of tag properties without quotes, missing closing tags, or invalid properties in tags. {Type of error, location of error}. Occurred at: {Time}.** ### Resolution For an HTML file to be converted into the corresponding ASP.NET file, the HTML file must be XML-compliant. This error identifies specific markup in your HTML file that is not XML-compliant. Run the HTML file through an XML validator, fix any issues in your HTML editor, save the file, and then refresh the preview. - -> [!NOTE] -> This requirement overrides some HTML 5 standards. For example, in HTML 5 you can specify the doctype in lowercase, but in XML the doctype must be uppercase. - - - - - - - +> [!NOTE] +> This requirement overrides some HTML 5 standards. For example, in HTML 5 you can specify the doctype in lowercase, but in XML the doctype must be uppercase. ## HTML file contains problematic markup - - ### Message - **SharePoint can't parse this file, most likely because of an incorrectly formatted SharePoint snippet. The markup at the following location is causing problems. Edit the markup manually to fix it, or replace it with a new snippet from the Snippet Gallery. {Type of error, location of error}. Occurred at: {Time}.** - - - +**SharePoint can't parse this file, most likely because of an incorrectly formatted SharePoint snippet. The markup at the following location is causing problems. Edit the markup manually to fix it, or replace it with a new snippet from the Snippet Gallery. {Type of error, location of error}. Occurred at: {Time}.** ### Resolution -You see this error when there is a problem with a SharePoint snippet in your HTML file. To fix this error, undo whatever change caused the error, or replace the problematic snippet with a new one, either from the Snippet Gallery or from a different master page or page layout file that has a working version of the snippet. In your HTML editor, after you fix or replace the snippet, save the page, and then refresh the preview. - - - - -## Master page for a page layout has changed - - +You see this error when there is a problem with a SharePoint snippet in your HTML file. To fix this error, undo whatever change caused the error, or replace the problematic snippet with a new one, either from the Snippet Gallery or from a different master page or page layout file that has a working version of the snippet. In your HTML editor, after you fix or replace the snippet, save the page, and then refresh the preview.## Master page for a page layout has changed ### Message **This page layout's master page has changed, which will cause inconsistencies across your site. Click here to update the sections of your page layout that represent master page regions.** - - - ### Resolution For a page layout to work with a given master page, the two must have the same set of content placeholders. If you create a page layout based on a particular master page, and then edit that HTML master page, you'll see this message. Even if you know that changes to the master page didn't add or remove content placeholders, you should update the content regions of your page layout anyway, so that you can preview any changes from the master page that might affect your page layout. - - - ## Reset the preview - - ### Message - **Your master page (page layout) doesn't have any warnings or errors. Reset the preview to its original state.** - - - +**Your master page (page layout) doesn't have any warnings or errors. Reset the preview to its original state.** ### Explanation This message simply confirms that the conversion process worked with no errors or issues. However, when you preview a page, you may navigate away from that specific page or change the preview in some other way. If this happens, you can always choose **Reset the preview** in the message area. Doing so refreshes the preview so that it uses the specific master page or page layout that you're working on, and whatever page you've selected in the **Change Preview Page** option in the upper-left corner. - - - ## Change the preview page - - ### Message - **You're currently previewing your master page (page layout) without any content. You can change the page you're previewing from the menu above.** - - - +**You're currently previewing your master page (page layout) without any content. You can change the page you're previewing from the menu above.** ### Explanation You see this message when you aren't using a live SharePoint page with which to preview your master page or page layout. For example, if you're previewing a page layout, you can choose **Change Preview Page** in the upper-left corner, and then select a specific content page to preview with your page layout. This way, you can preview the page layout with actual page content in the page fields. If you want the preview to show just the positions of **ContentPlaceHolderMain** or page fields, you can always use **Change Preview Page** to switch back to a generic preview. - - - ## See also - - - -- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) - - -- [How to: Change the preview page in SharePoint Design Manager](how-to-change-the-preview-page-in-sharepoint-design-manager.md) - - -- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) - - +- [Develop the site design in SharePoint](develop-the-site-design-in-sharepoint.md) +- [How to: Change the preview page in SharePoint Design Manager](how-to-change-the-preview-page-in-sharepoint-design-manager.md) +- [SharePoint Design Manager snippets](sharepoint-design-manager-snippets.md) \ No newline at end of file diff --git a/docs/general-development/how-to-restrict-udf-code-access-security-permissions.md b/docs/general-development/how-to-restrict-udf-code-access-security-permissions.md index c95b9c62c..ccadfd1ac 100644 --- a/docs/general-development/how-to-restrict-udf-code-access-security-permissions.md +++ b/docs/general-development/how-to-restrict-udf-code-access-security-permissions.md @@ -1,12 +1,12 @@ --- title: Restrict UDF code access security permissions +description: "If you do not want a particular user-defined function (UDF) assembly to run with full trust, you must explicitly restrict code access security permissions for it." ms.date: 09/25/2017 keywords: cas,how to,howdoi,howto,UDF list f1_keywords: - cas,how to,howdoi,howto,UDF list -ms.prod: sharepoint ms.assetid: 4f022e0d-1fe3-4fab-b41f-82a0d628f77c -localization_priority: Normal +ms.localizationpriority: medium --- @@ -134,5 +134,5 @@ For more information about configuring code groups, see the following articles o - [How to: Access an External Data Source from a UDF](how-to-access-an-external-data-source-from-a-udf.md) - [How to: Deploy UDFs Using SharePoint Foundation Solutions](how-to-deploy-udfs-using-sharepoint-foundation-solutions.md) - [Walkthrough: Developing a Managed-Code UDF](walkthrough-developing-a-managed-code-udf.md) -- [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.md) +- [Frequently Asked Questions About Excel Services UDFs](frequently-asked-questions-about-excel-services-udfs.yml) - [Understanding Excel Services UDFs](understanding-excel-services-udfs.md) diff --git a/docs/general-development/how-to-retrieve-the-url-of-a-pages-library.md b/docs/general-development/how-to-retrieve-the-url-of-a-pages-library.md index 2a0c8944d..f8baa97b7 100644 --- a/docs/general-development/how-to-retrieve-the-url-of-a-pages-library.md +++ b/docs/general-development/how-to-retrieve-the-url-of-a-pages-library.md @@ -1,9 +1,9 @@ --- title: Retrieve the URL of a Pages library +description: Learn how to retrieve the URL for the pages list for a publishing web in a site collection that differs from the current context. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: d9922e4b-4948-4c4a-a8ca-1623168143a3 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -61,7 +61,7 @@ The application queries the [SPPropertyBag](https://msdn.microsoft.com/library/ -```cs +```csharp using System; using System.Collections; diff --git a/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-javascript-object-model-in.md b/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-javascript-object-model-in.md index 5fb7e3210..9d31446f2 100644 --- a/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-javascript-object-model-in.md +++ b/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-javascript-object-model-in.md @@ -1,9 +1,9 @@ --- title: Retrieve user profile properties by using the JavaScript object model in SharePoint +description: Learn how to retrieve user properties and user profile properties programmatically by using the SharePoint JavaScript object model. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: c6e1ca38-134f-428a-8d21-b8b2615b161b -localization_priority: Priority +ms.localizationpriority: high --- diff --git a/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-net-client-object-model-in.md b/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-net-client-object-model-in.md index 8acafb9d8..8a5a5f069 100644 --- a/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-net-client-object-model-in.md +++ b/docs/general-development/how-to-retrieve-user-profile-properties-by-using-the-net-client-object-model-in.md @@ -1,9 +1,9 @@ --- title: Retrieve user profile properties by using the .NET client object model in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to retrieve user profile properties programmatically by using the SharePoint .NET client object model. +ms.date: 06/13/2022 ms.assetid: 236ebaf8-f92e-4192-9b51-0a9de0210885 -localization_priority: Priority +ms.localizationpriority: high --- @@ -90,7 +90,7 @@ To create a console application that uses the .NET client object model to retrie 6. In the **Main** method, define variables for the server URL and the target user name, as shown in the following code. -```cs +```csharp const string serverUrl = "http://serverName/"; const string targetUser = "domainName\\userName"; ``` @@ -99,13 +99,13 @@ const string targetUser = "domainName\\userName"; 7. Initialize the SharePoint client context, as shown in the following code. -```cs +```csharp ClientContext clientContext = new ClientContext(serverUrl); ``` 8. Get the target user's properties from the **PeopleManager** object, as shown in the following code. -```cs +```csharp PeopleManager peopleManager = new PeopleManager(clientContext); PersonProperties personProperties = peopleManager.GetPropertiesFor(targetUser); ``` @@ -115,7 +115,7 @@ PersonProperties personProperties = peopleManager.GetPropertiesFor(targetUser); 9. To initialize the **personProperties** object, register the request that you want to run, and then run the request on the server, as shown in the following code. -```cs +```csharp clientContext.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties); clientContext.ExecuteQuery(); ``` @@ -126,7 +126,7 @@ clientContext.ExecuteQuery(); 10. Iterate through the user profile properties and read the name and value of each property, as shown in the following code. -```cs +```csharp foreach (var property in personProperties.UserProfileProperties) { Console.WriteLine(string.Format("{0}: {1}", @@ -147,7 +147,7 @@ The following code example shows how to retrieve and iterate through all the use -```cs +```csharp using System; using System.Collections.Generic; @@ -203,7 +203,7 @@ The following code example shows how to get, in a SharePoint Add-in, the user pr -```cs +```csharp string contextTokenString = TokenHelper.GetContextTokenFromRequest(Request); @@ -241,7 +241,7 @@ The following code example shows how to retrieve a specific set of user profile -Unlike the previous code example that retrieves a [PersonProperties](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PersonProperties.aspx) object for the target user, this example calls the [PeopleManager.GetUserProfilePropertiesFor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PeopleManager.GetUserProfilePropertiesFor.aspx) method and passes in a [UserProfilePropertiesForUser](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.UserProfilePropertiesForUser.aspx) object that specifies the target user and the user profile properties to retrieve. [GetUserProfilePropertiesFor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PeopleManager.GetUserProfilePropertiesFor.aspx) returns an **IEnumerable** collection that contains the values of the properties that you specify. +Unlike the previous code example that retrieves a [PersonProperties](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PersonProperties.aspx) object for the target user, this example calls the [PeopleManager.GetUserProfilePropertiesFor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PeopleManager.GetUserProfilePropertiesFor.aspx) method and passes in a [UserProfilePropertiesForUser](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.UserProfilePropertiesForUser.aspx) object that specifies the target user and the user profile properties to retrieve. [GetUserProfilePropertiesFor](https://msdn.microsoft.com/library/Microsoft.SharePoint.Client.UserProfiles.PeopleManager.GetUserProfilePropertiesFor.aspx) returns an **IEnumerable\** collection that contains the values of the properties that you specify. > [!NOTE] > Replace the `http://serverName/` and `domainName\\\\userName` placeholder values before you run the code. @@ -252,7 +252,7 @@ Unlike the previous code example that retrieves a [PersonProperties](https://ms -```cs +```csharp using System; using System.Collections.Generic; diff --git a/docs/general-development/how-to-save-from-excel-client-to-the-server.md b/docs/general-development/how-to-save-from-excel-client-to-the-server.md index 29454489c..452851cce 100644 --- a/docs/general-development/how-to-save-from-excel-client-to-the-server.md +++ b/docs/general-development/how-to-save-from-excel-client-to-the-server.md @@ -1,12 +1,12 @@ --- title: Save from Excel client to the server -ms.date: 09/25/2017 +description: Describes how to create a workbook with editable ranges, save it to a trusted SharePoint document library, and change values in the workbook. +ms.date: 06/13/2022 keywords: how to,howdoi,howto f1_keywords: - how to,howdoi,howto -ms.prod: sharepoint ms.assetid: 28716ba5-0774-44df-833b-0034d2c63319 -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/how-to-save-to-the-server-to-prepare-for-programmatic-access.md b/docs/general-development/how-to-save-to-the-server-to-prepare-for-programmatic-access.md index 25c7028cb..482c58790 100644 --- a/docs/general-development/how-to-save-to-the-server-to-prepare-for-programmatic-access.md +++ b/docs/general-development/how-to-save-to-the-server-to-prepare-for-programmatic-access.md @@ -1,197 +1,133 @@ --- title: Save to the server to prepare for programmatic access -ms.date: 09/25/2017 +description: This example shows how to save an Excel workbook to the server to prepare it for programmatic access. +ms.date: 01/05/2020 keywords: how to,howdoi,howto f1_keywords: - how to,howdoi,howto -ms.prod: sharepoint ms.assetid: 80b34a29-3d40-4d11-9ba1-b4886ffcfd42 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Save to the server to prepare for programmatic access This example shows how to save an Excel workbook to the server to prepare it for programmatic access. The steps are: 1. Create a workbook with named ranges. - - -2. Save the workbook to a trusted SharePoint library location. - - > [!NOTE] - > It is assumed that you have already created a SharePoint document library and made it a trusted location. For more information, see [How to: Trust a Location](how-to-trust-a-location.md). +1. Save the workbook to a trusted SharePoint library location. -3. Programmatically specify values for the worksheet, named range, and cell value by using the Excel Web Services **SetCellA1** method. The values are passed in as arguments—that is, _args [1]_ and _args [2]_: - -```cs - -status = xlServices.SetCellA1(sessionId, String.Empty, args[1], args[2]); -``` + > [!NOTE] + > It is assumed that you have already created a SharePoint document library and made it a trusted location. For more information, see [How to: Trust a Location](how-to-trust-a-location.md). +1. Programmatically specify values for the worksheet, named range, and cell value by using the Excel Web Services **SetCellA1** method. The values are passed in as arguments—that is, _args [1]_ and _args [2]_: -```VB.net - status = xlServices.SetCellA1(sessionId, String.Empty, args(1), args(2)) -``` + ```csharp + status = xlServices.SetCellA1(sessionId, String.Empty, args[1], args[2]); + ``` + ```VB.net + status = xlServices.SetCellA1(sessionId, String.Empty, args(1), args(2)) + ``` You can specify the values of _args [1]_ and _args [2]_ by using a Web form or from the command line: - - - - - - -``` -GetSnapshot.exe http://MyServer002/MyTrustedDocumentLibrary/TestMyParam.xlsx MyParam28 > MySnapshot.xlsx +```console +GetSnapshot.exe http://MyServer002/MyTrustedDocumentLibrary/TestMyParam.xlsx MyParam28 > MySnapshot.xlsx ``` In this example, _args [1]_ is **MyParam**, **args [2]** is _28_ and _GetSnapshot.exe_ is the name of the application that you create. To find a sample program, see [How to: Get an Entire Workbook or a Snapshot](how-to-get-an-entire-workbook-or-a-snapshot.md). -### To create a named range +### To create a named range 1. Start Excel. - - -2. Rename **Sheet1** to beMyParamSheet. - - -3. In cell B2, type 20. - - -4. In cell B3, type =2+B2. - - -5. Make cell B3 bold. - - -6. Make cell B2 into a named range: - -1. On the ribbon, click the **Formulas** tab, and then click cell B2 to select it. - - -2. In the **Defined Names** group, click **Define Name**. - - -3. In the **New Name** dialog box, in the **Name** text box, typeMyParam. - - -7. Save the workbook to a location of your choice on the local drive. Name the workbook TestMyParam.xlsx. - - +1. Rename **Sheet1** to beMyParamSheet. +1. In cell B2, type 20. +1. In cell B3, type =2+B2. +1. Make cell B3 bold. +1. Make cell B2 into a named range: -### To save to a SharePoint library + 1. On the ribbon, click the **Formulas** tab, and then click cell B2 to select it. + 1. In the **Defined Names** group, click **Define Name**. + 1. In the **New Name** dialog box, in the **Name** text box, typeMyParam. +1. Save the workbook to a location of your choice on the local drive. Name the workbook TestMyParam.xlsx. -1. On the **File** menu, click **Save & Send**, and then click **Save to SharePoint**. - - -2. In the **Save to SharePoint** dialog box, click **Publish Options**. - - -3. In the **Publish Options** dialog box, on the **Show** tab, ensure that **Entire Workbook** is selected. - - -4. Click **Parameters**. - - -5. Click **Add**. - - -6. In the **Add Parameters** list, you should see **MyParam**. Select the **MyParam** check box. - - -7. Click **OK**. You should now see **MyParam** in the **Parameters** list. - - -8. Click **OK**. - - -9. In the **Save to SharePoint** dialog box, click **Save As**. - - -10. In the **Save As** dialog box, clear the **Open with Excel in the browser** check box. - - -11. In the **File name** box, type the path to the trusted SharePoint document library where you want to store this workbook. For example,http:// _MyServer002_/MyDocumentLibrary/TestParam.xlsx. - - -12. Click **Save**. - - +### To save to a SharePoint library -### To specify values programmatically +1. On the **File** menu, click **Save & Send**, and then click **Save to SharePoint**. +1. In the **Save to SharePoint** dialog box, click **Publish Options**. +1. In the **Publish Options** dialog box, on the **Show** tab, ensure that **Entire Workbook** is selected. +1. Click **Parameters**. +1. Click **Add**. +1. In the **Add Parameters** list, you should see **MyParam**. Select the **MyParam** check box. +1. Click **OK**. You should now see **MyParam** in the **Parameters** list. +1. Click **OK**. +1. In the **Save to SharePoint** dialog box, click **Save As**. +1. In the **Save As** dialog box, clear the **Open with Excel in the browser** check box. +1. In the **File name** box, type the path to the trusted SharePoint document library where you want to store this workbook. For example,http:// _MyServer002_/MyDocumentLibrary/TestParam.xlsx. +1. Click **Save**. +### To specify values programmatically 1. Following is the signature for the **SetCellA1** method in Excel Web Services: - -```cs - public void SetCellA1 ( -string sessionId, -string sheetName, -string rangeName, -Object cellValue, -Out Status[] status -) -``` - -```VB.net - -Public Sub SetCellA1(ByVal sessionId As String, - ByVal sheetName As String, - ByVal rangeName As String, - ByVal cellValue As Object, - Out ByVal status() As Status) -End Sub -``` + ```csharp + public void SetCellA1 ( + string sessionId, + string sheetName, + string rangeName, + Object cellValue, + Out Status[] status + ) + ``` + + ```vbnet + Public Sub SetCellA1(ByVal sessionId As String, + ByVal sheetName As String, + ByVal rangeName As String, + ByVal cellValue As Object, + Out ByVal status() As Status) + End Sub + ``` Set the values for the worksheet, named range, and cell value to the **SetCellA1** method as follows: - - -```cs - -// Set a value into a cell. -status = xlSrv.SetCellA1(sessionId, String.Empty, args[1], args[2]); - -``` - -2. In the preceding code: + ```csharp + // Set a value into a cell. + status = xlSrv.SetCellA1(sessionId, String.Empty, args[1], args[2]); + ``` +1. In the preceding code: + - _args [1]_ is the name of the named range. In this example, it is **MyParam**. - - - _args [2]_ is the value that you want to set in the cell. The cell where the value will be set is the named range in _args [1]_ called **MyParam**. - - + + 3. If you are using a command line, you can pass in the arguments as follows: - + `GetSnapshot.exe http://` _MyServer002_ `/` _MyTrustedDocumentLibrary_ `/TestMyParam.xlsx MyParam 28 > MySnapshot.xlsx` - - -4. If you generate a snapshot of the workbook, you see the following: - + + +4. If you generate a snapshot of the workbook, you see the following: + - Cell B2 (with the named range **MyParam**) now has a value that you fed through the program, which is **28**. - - + + - Cell B3 has a new calculated value of **30**. - - + + - Cell B3 does not show the original formula, which was "=2+B2". - - + + - Cell B3 retains its font format, which is bold. - - + + > [!NOTE] > For more information about snapshots, see [How to: Get an Entire Workbook or a Snapshot](how-to-get-an-entire-workbook-or-a-snapshot.md). For more information about the **SetCellA1** method, see the Excel Web Services reference documentation. The namespace of the Web service is [Microsoft.Office.Excel.Server.WebServices](https://msdn.microsoft.com/library/Microsoft.Office.Excel.Server.WebServices.aspx) . - - - + + + ## See also @@ -200,36 +136,36 @@ status = xlSrv.SetCellA1(sessionId, String.Empty, args[1], args[2]); #### Tasks - - - + + + [How to: Save from Excel Client to the Server](how-to-save-from-excel-client-to-the-server.md) #### Reference - - - + + + [Microsoft.Office.Excel.Server.WebServices](https://msdn.microsoft.com/library/Microsoft.Office.Excel.Server.WebServices.aspx) #### Concepts - - - + + + [Accessing the SOAP API](accessing-the-soap-api.md) - - - + + + [Loop-Back SOAP Calls and Direct Linking](loop-back-soap-calls-and-direct-linking.md) - - - + + + [Excel Services Alerts](excel-services-alerts.md) #### Other resources - - - + + + [Walkthrough: Developing a Custom Application Using Excel Web Services](walkthrough-developing-a-custom-application-using-excel-web-services.md) diff --git a/docs/general-development/how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md b/docs/general-development/how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md index aa298d401..19bc3f0c2 100644 --- a/docs/general-development/how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md +++ b/docs/general-development/how-to-set-the-bing-maps-key-at-the-web-and-farm-level-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Set the Bing Maps key at the web and farm level in SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn how to set the Bing Maps key programmatically at the web (SharePoint Server and SharePoint Online) and farm (SharePoint Server) level by using the SharePoint client object model and Windows PowerShell, to enable the Bing Maps functionality in SharePoint lists and location-based web and mobile apps. +ms.date: 01/06/2023 ms.assetid: 507ed9de-c349-44b5-b182-e838795dd862 -localization_priority: Normal +ms.localizationpriority: medium --- # Set the Bing Maps key at the web and farm level in SharePoint @@ -26,52 +26,54 @@ To follow the steps in this example, you should have the following: > [!IMPORTANT] > Please note that you are responsible for compliance with terms and conditions applicable to your use of the Bing Maps key, and any necessary disclosures to users of your application regarding data passed to the Bing Maps service. +[!INCLUDE [pnp-powershell](../../includes/snippets/open-source/pnp-powershell.md)] + ## Code example: Set the Bing Maps key at the farm or web level The Bing Maps key can be set at the farm or web level. To set the Bing Maps key at the farm level, you need administrator rights on the server; you can then add the key by using the SharePoint Management Shell. To set the Bing Maps key at the web level, write a console application that uses the SharePoint client object model or leverage SharePoint PnP PowerShell. - + > [!TIP] -> The Bing Maps key set at web level has higher precedence order than the Bing Maps key set at farm level. +> The Bing Maps key set at web level has higher precedence order than the Bing Maps key set at farm level. ### To set the Bing Maps key at the farm level using Windows PowerShell 1. Log on to the SharePoint server as an administrator, and open the SharePoint Management Shell. - - -2. Execute the following command: - + + +2. Execute the following command: + `Set-SPBingMapsKey -BingKey ""` - - The Bing Maps key is now set at the farm level in SharePoint. - + + The Bing Maps key is now set at the farm level in SharePoint. + > [!NOTE] -> When you use Windows PowerShell, the Bing Maps key can be set only at the farm level. If you want to set the Bing Maps key at the web level, you can set the key programmatically, as shown in the following section. +> When you use Windows PowerShell, the Bing Maps key can be set only at the farm level. If you want to set the Bing Maps key at the web level, you can set the key programmatically, as shown in the following section. ### To set the Bing Maps key at the web level with SharePoint PnP PowerShell 1. Open the SharePoint Online Management Shell 2. Connect to the site you want to add/update the Bing Maps key -```cs +```powershell Connect-PnPOnline -url "https://TENANT.sharepoint.com/sites/SITEURL" ``` 3. Add the Bing Maps Key to the Site Property Bag (Update "YOURKEYVALUE") -```cs +```powershell Set-PnPPropertyBagValue -Key "BING_MAPS_KEY" -Value "YOURKEYVALUE" ``` 4. If you receive an error regarding NoScript being enabled, you must disable it in the site. Then rerun step 3. -```cs -Set-SPOsite -DenyAddAndCustomizePages 0 +```powershell +Set-PnPSite -NoScriptSite $false ``` - + > [!NOTE] -> Ensure you understand the implications of changing a site's NoScript Policy - https://docs.microsoft.com/sharepoint/allow-or-prevent-custom-script?redirectSourcePath=%252fen-us%252farticle%252fTurn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f +> Ensure you understand the implications of changing a site's NoScript Policy - [Allow or prevent custom script](/sharepoint/allow-or-prevent-custom-script). ### To set the Bing Maps key at the farm or web level using the client object model with Visual Studio @@ -79,13 +81,13 @@ Set-SPOsite -DenyAddAndCustomizePages 0 1. Start Visual Studio. 2. On the menu bar, choose **File**, **New Project**. The **New Project** dialog box opens. - + 3. In the **New Project** dialog box, choose **C#** in the **Installed Templates** box, and then choose the **Console Application** template. 4. Give the project a name, and then choose the **OK** button. - + 5. Visual Studio creates the project. Add a reference to the following assemblies, and choose **OK**. - + - Microsoft.SharePoint.Client.dll - Microsoft.SharePoint.Client.Runtime.dll @@ -94,8 +96,8 @@ Set-SPOsite -DenyAddAndCustomizePages 0 7. Add the following code to the Main method in the .cs file. -```cs - +```csharp + class Program { static void Main(string[] args) @@ -111,19 +113,19 @@ class Program web.AllProperties["BING_MAPS_KEY"] = "" web.Update(); context.ExecuteQuery(); - } + } } ``` -8. Replace the and __ with valid values. +8. Replace the \; and _\_ with valid values. 9. Set the target framework in Project Properties as .NET Framework 4.0, and run the example. -10. The key should now be set at the web level. +10. The key should now be set at the web level. ## Next steps To learn more about working with location and map functionality in SharePoint, see the following: -- [How to: Add a Geolocation column to a list programmatically in SharePoint](how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md) -- [How to: Extend the Geolocation field type using client-side rendering](how-to-extend-the-geolocation-field-type-using-client-side-rendering.md) +- [How to: Add a Geolocation column to a list programmatically in SharePoint](how-to-add-a-geolocation-column-to-a-list-programmatically-in-sharepoint.md) +- [How to: Extend the Geolocation field type using client-side rendering](how-to-extend-the-geolocation-field-type-using-client-side-rendering.md) diff --git a/docs/general-development/how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md b/docs/general-development/how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md index 94fd15b8d..3895eb84c 100644 --- a/docs/general-development/how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md +++ b/docs/general-development/how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md @@ -1,9 +1,9 @@ --- title: Set up an environment for developing mobile apps for SharePoint -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Describes the system requirements and configuring a development environment for SharePoint mobility projects. +ms.date: 06/13/2022 ms.assetid: acaf556d-e20d-478d-8c59-2efd8efb9dcb -localization_priority: Normal +ms.localizationpriority: medium --- @@ -87,7 +87,7 @@ To develop SharePoint Add-ins for use on Windows Phone 7, you need to set up you -1. On a computer with a supported client operating system, install [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=27570). +1. On a computer with a supported client operating system, install [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=29233). > [!NOTE] > An earlier version of the Windows Phone SDK was named the Windows Phone Developer Tools. diff --git a/docs/general-development/how-to-set-values-of-ranges.md b/docs/general-development/how-to-set-values-of-ranges.md index 86c792077..808e527e8 100644 --- a/docs/general-development/how-to-set-values-of-ranges.md +++ b/docs/general-development/how-to-set-values-of-ranges.md @@ -1,12 +1,12 @@ --- title: Set values of ranges +description: "Excel Web Services exposes four methods for setting values into an Excel workbook: SetCell, SetCellA1, SetRange, and SetRangeA1." ms.date: 09/25/2017 keywords: how to,howdoi,howto,set range f1_keywords: - how to,howdoi,howto,set range -ms.prod: sharepoint ms.assetid: ccc7e204-f857-45a9-81ec-3a8484e6d454 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -29,7 +29,7 @@ Use the **SetCell** and **SetCellA1** methods to set values in a single cell. If Methods that have the A1 suffix ( **SetCellA1** and **SetRangeA1**) use a different coordinate system than those that do not ( **SetCell** and **SetRange**). If you want to use Excel-style references to cells, such as range references (for example, H8, A3:D5, Sheet2!A12:G18) or named ranges, you should use the methods with the A1 suffix. Those methods allow you to pass in the name of a sheet and range.If you want to access an Excel range by using a numeric coordinate system, you should use the methods that do not have the A1 suffix. It is easier to use range coordinates when you have code that iterates through a set of cells in a loop, or when the range coordinates are calculated dynamically as part of the algorithm.The row and column coordinates of a cell are 0-based. Therefore, "0,0" will return cell A1, as in this example: -```cs +```csharp // Call the SetCell method to set a value, 8, into a cell. // The cell is in the first row and first column; that is, cell A1. @@ -52,7 +52,7 @@ If you are getting values from multiple adjacent cells, you may want to consider 1. Use the **SetCell** method to set a value in a cell in the open workbook by using numeric range coordinates: -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); @@ -104,7 +104,7 @@ xlservice.SetCell(sessionId, sheetName, 8, 1, 28) 2. Use the **SetRange** method to set values in a range in the open workbook by using numeric range coordinates: -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); @@ -229,7 +229,7 @@ End Sub 1. Use the **SetCellA1** method to set a value in a cell in the open workbook, using the Excel "A1" range specification: -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); @@ -250,7 +250,7 @@ xlservice.SetCellA1(sessionId, String.Empty, "InterestRateParam", 8) 2. Use the **SetRangeA1** method to get a value from a range in the open workbook, using the Excel "A1" range specification: -```cs +```csharp // Instantiate the Web service and make a status array object. ExcelService xlservice = new ExcelService(); diff --git a/docs/general-development/how-to-set-various-credentials.md b/docs/general-development/how-to-set-various-credentials.md index 8b044c8cf..3682a32fe 100644 --- a/docs/general-development/how-to-set-various-credentials.md +++ b/docs/general-development/how-to-set-various-credentials.md @@ -1,9 +1,9 @@ --- title: Set various credentials +description: You must set credentials for your users before they can call Excel Web Services by using your custom application. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: eb819681-5a4f-49ae-b7f4-334366c51112 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -22,7 +22,7 @@ The following code uses the current user's logon credentials to make a request t -```cs +```csharp //Instantiate the Web service. ExcelService xlService = new ExcelService(); @@ -54,7 +54,7 @@ The following code uses the current user's logon credentials to make a request t -```cs +```csharp protected string farmURL, docLibPath, workbookPath, uiCulture, dataCulture, localTempFolder, authenticationType; protected Cookie authCookie; @@ -184,7 +184,7 @@ The following code uses the current user's logon credentials to make a request t -```cs +```csharp //Instantiate the Web service. ExcelService xlService = new ExcelService(); diff --git a/docs/general-development/how-to-specify-a-range-address-and-sheet-name.md b/docs/general-development/how-to-specify-a-range-address-and-sheet-name.md index 651853f86..12f840246 100644 --- a/docs/general-development/how-to-specify-a-range-address-and-sheet-name.md +++ b/docs/general-development/how-to-specify-a-range-address-and-sheet-name.md @@ -1,12 +1,12 @@ --- title: Specify a range address and sheet name +description: This example shows how to specify range addresses by using range coordinates, named ranges, rows, and columns. It also shows how to specify a sheet name and the relationship between a sheet name and a range address. ms.date: 09/25/2017 keywords: how to,howdoi,howto,set range f1_keywords: - how to,howdoi,howto,set range -ms.prod: sharepoint ms.assetid: 8bfefc48-1fbc-4b65-8156-1b7d0a8453ee -localization_priority: Normal +ms.localizationpriority: medium --- @@ -26,7 +26,7 @@ A range specification must contain a sheet name; Excel Web Services does not rec - As part of the range address—for example, "Sheet3!B12:D18"—in which case the sheet name argument can be empty: -```cs +```csharp object[] rangeResult1 = xlservice.GetRangeA1(sessionId, String.Empty, "Sheet2!A12:G18", true, out outStatus); ``` @@ -38,7 +38,7 @@ object[] rangeResult1 = xlservice.GetRangeA1(sessionId, String.Empty, "Sheet2!A1 - In a separate sheet name argument, in which case the range address argument does not have to include the sheet name: -```cs +```csharp xlservice.SetCell(sessionId, "Sheet3", 0, 11, 1000); ``` @@ -49,7 +49,7 @@ object[] rangeResult1 = xlservice.GetRangeA1(sessionId, String.Empty, "Sheet2!A1 - In both the sheet name and range address, in which case the name of the sheet must match: -```cs +```csharp object[] rangeResult = xlservice.GetCellA1(sessionId, "Sheet3", "Sheet3!G18", true, out outStatus); ``` @@ -61,7 +61,7 @@ object[] rangeResult1 = xlservice.GetRangeA1(sessionId, String.Empty, "Sheet2!A1 The only case that does not require a sheet name is a named range, because some named ranges have a workbook scope. For example, you can refer to named ranges without specifying the sheet name argument: -```cs +```csharp xlServices.SetCellA1(sessionId, String.Empty, "MyNamedRange", 8); ``` @@ -82,7 +82,7 @@ If you specify a sheet name, the ranges you reference must exist on the sheet yo -```cs +```csharp using System; using System.Text; using System.Web.Services.Protocols; diff --git a/docs/general-development/how-to-store-and-retrieve-sharepoint-list-items-on-a-windows-phone.md b/docs/general-development/how-to-store-and-retrieve-sharepoint-list-items-on-a-windows-phone.md index 78335bfe3..256b3804e 100644 --- a/docs/general-development/how-to-store-and-retrieve-sharepoint-list-items-on-a-windows-phone.md +++ b/docs/general-development/how-to-store-and-retrieve-sharepoint-list-items-on-a-windows-phone.md @@ -1,949 +1,740 @@ --- title: Store and retrieve SharePoint list items on a Windows Phone -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Learn about the Windows Phone application life cycle and storing network data locally. +ms.date: 06/13/2022 ms.assetid: 14ca37a2-5b45-430d-9004-ff3016f89834 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Store and retrieve SharePoint list items on a Windows Phone Learn about the Windows Phone application life cycle and storing network data locally. -One of the most important considerations in the development of Windows Phone apps is the management of state information, both for the overall application and for individual pages or data items within the application. If you're developing Windows Phone apps, you must take into account that users of your apps might lose connectivity to network resources (such as SharePoint lists). The development infrastructure for Windows Phone apps provides mechanisms for handling state information at various stages in the life cycle of an app. - - - - -> **Important:** -> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). - - - +One of the most important considerations in the development of Windows Phone apps is the management of state information, both for the overall application and for individual pages or data items within the application. If you're developing Windows Phone apps, you must take into account that users of your apps might lose connectivity to network resources (such as SharePoint lists). The development infrastructure for Windows Phone apps provides mechanisms for handling state information at various stages in the life cycle of an app. +> [!IMPORTANT] +> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). ## Store SharePoint list data locally on a Windows Phone - On a Windows Phone, only one app runs at a time, and when a user switches to another app on the phone (by pressing the **Start** button on the phone, for example), the app currently running is deactivated, or, in the terms of Windows Phone development,tombstoned. If the user switches back to the deactivated app (by pressing the **Back** button), the app can be reactivated, but unless you provide logic to handle application state information over the course of the app life cycle, that state information is not preserved by default in the transition from activation to deactivation and back again. (For more information about the application life cycle for Windows Phone apps, see [Execution Model Overview for Windows Phone](https://msdn.microsoft.com/library/ff817008%28v=VS.92%29.aspx).) - - - -For Windows Phone apps, the **PhoneApplicationService** class exposes standard life-cycle events that can be used to manage application state. In projects created from the Windows Phone SharePoint List Application template (as with projects created from all **Silverlight for Windows Phone** templates), these standard Windows Phone application life-cycle events are declared in the App.xaml file and associated with event handlers in the code-behind file, App.xaml.cs. The declarations in the App.xaml file for your SharePoint list apps should look like the following markup. - - - - +For Windows Phone apps, the **PhoneApplicationService** class exposes standard life-cycle events that can be used to manage application state. In projects created from the Windows Phone SharePoint List Application template (as with projects created from all **Silverlight for Windows Phone** templates), these standard Windows Phone application life-cycle events are declared in the App.xaml file and associated with event handlers in the code-behind file, App.xaml.cs. The declarations in the App.xaml file for your SharePoint list apps should look like the following markup. -``` - +```xml - ``` The **Application_Activated** and **Application_Deactivated** event handlers declared in the App.xaml file are implemented in the App.xaml.cs code-behind file with default logic that caches application state information for use in the phone app as long as the app is not terminated. The implementation of the handlers for these events uses the **State** property (which provides access to a **Dictionary** object) of the **PhoneApplicationService** class to store data. Data stored in this **State** property is transient. That is, it is preserved when the app is deactivated or tombstoned, but not when the app is terminated. It is important to keep in mind as you handle application life-cycle events in your projects that if a Windows app is deactivated when a user switches to another app, that deactivated app is subject to termination by the Windows Phone operating system, depending on circumstances. Any data on the phone that isn't saved to persistent storage is lost, even if that data was saved to transient storage by using the **State** property of the **PhoneApplicationService**. - - - + In a Windows Phone app that gets data from a SharePoint list, the data used on the phone from session to session can of course be retrieved from the server running SharePoint Server, if the server is available. But continuous connectivity to a SharePoint Server may not be available for a Windows Phone device, owing to variations in service coverage by location and other factors. To provide users of your app with access to data in the event of lost connectivity with the server running SharePoint Server, or simply to save data to persistent storage between sessions of the app regardless of server availability, you can take advantage of the **Closing** and **Launching** events of the **PhoneApplicationService** class. - - - + The **Application_Launching** and **Application_Closing** handlers for these events are declared in App.xaml and defined in the App.xaml.cs file, but they are not implemented. To handle storing and retrieving application state information in the context of app termination, you can provide an implementation for the **Application_Closing** event handler to store data in the isolated storage designated for the app so that the data persists between sessions of the app, and you can provide an implementation for the **Application_Launching** event handler to retrieve data from isolated storage when a new session of the app is started (when the app is launched), even if connectivity to the server running SharePoint Server that is the original source of the data is not available. - - - -> **Tip:** +> [!TIP] > Data should be encrypted before you save it to a local device. For more information about how to encrypt the data, see [How to: Encrypt Data in a Windows Phone Application](https://msdn.microsoft.com/library/hh487164%28v=vs.92%29.aspx) - - - - ### To implement event handlers for storing and retrieving application state - 1. Create a Windows Phone app by using the Windows Phone SharePoint List Application template in Visual Studio by following the steps in [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md). - - -2. In **Solution Explorer**, choose the App.xaml file. - - -3. Press F7 to open the code-behind file, App.xaml.cs, for editing. - - -4. Locate the (empty) implementation of the **Application_Launching** event handler and replace the event handler with the following code. - -```cs - -private void Application_Launching(object sender, LaunchingEventArgs e) -{ - if (IsolatedStorageSettings.ApplicationSettings.Contains(DataProvider.ListTitle)) - { - App.MainViewModel = (ListViewModel)IsolatedStorageSettings.ApplicationSettings - [DataProvider.ListTitle]; - App.MainViewModel.Initialize(); - } -} -``` +1. In **Solution Explorer**, choose the **App.xaml** file. +1. Press F7 to open the code-behind file, **App.xaml.cs**, for editing. +1. Locate the (empty) implementation of the **Application_Launching** event handler and replace the event handler with the following code. -5. Locate the (empty) implementation of the **Application_Closing** event handler and replace that event handler with the following code. - -```cs - -private void Application_Closing(object sender, ClosingEventArgs e) -{ - if (IsolatedStorageSettings.ApplicationSettings.Contains(DataProvider.ListTitle)) + ```csharp + private void Application_Launching(object sender, LaunchingEventArgs e) { - IsolatedStorageSettings.ApplicationSettings[DataProvider.ListTitle] = App.MainViewModel; + if (IsolatedStorageSettings.ApplicationSettings.Contains(DataProvider.ListTitle)) + { + App.MainViewModel = (ListViewModel)IsolatedStorageSettings.ApplicationSettings + [DataProvider.ListTitle]; + App.MainViewModel.Initialize(); + } } - else + ``` + +1. Locate the (empty) implementation of the **Application_Closing** event handler and replace that event handler with the following code. + + ```csharp + private void Application_Closing(object sender, ClosingEventArgs e) { - IsolatedStorageSettings.ApplicationSettings.Add(DataProvider.ListTitle, App.MainViewModel); + if (IsolatedStorageSettings.ApplicationSettings.Contains(DataProvider.ListTitle)) + { + IsolatedStorageSettings.ApplicationSettings[DataProvider.ListTitle] = App.MainViewModel; + } + else + { + IsolatedStorageSettings.ApplicationSettings.Add(DataProvider.ListTitle, App.MainViewModel); + } + IsolatedStorageSettings.ApplicationSettings.Save(); } - IsolatedStorageSettings.ApplicationSettings.Save(); -} -``` + ``` + +1. Save the file. -6. Save the file. - - With these implementations in place, run your app to initialize the main ViewModel in the app with data from the server running SharePoint Server. Exit the app on the phone (by pressing the **Back** button to navigate past the first page of the app) to trigger the **Application_Closing** event. If you then run your app without connectivity to the server, the ViewModel that was saved to the **IsolatedStorageSettings** **Dictionary** object (in the **Application_Closing** event) is retrieved and initialized. The SharePoint list items that were saved to isolated storage in a previous session of the app are displayed in the List form (List.xaml) of the app. - - - ## Implement a mechanism for editing list items offline - If you follow the procedure in the previous section to implement handlers for the **Closing** and **Launching** events in your app, SharePoint list data that was retrieved from the server when connectivity was available can be displayed in your app even if connectivity to the server is lost in a subsequent session of the app, because the list items are retrieved from local persistent storage on the phone. Based on the implementation in the previous section, however, the list items made available in this way for display while offline can't be edited and saved back to the server unless connectivity is restored. In the following procedure, you'll add a mechanism to your app to provide for storing edited versions of list items locally when connectivity is unavailable. When connectivity to the server is available again, you can retrieve these edited list items and save your changes back to the server. - - - + For the procedures in this section, we assume you're working in the context of a Windows Phone app project created from the Windows Phone SharePoint List Application template and that your app is based on a Product Orders list created from the Custom List template on the server and contains the columns and field types shown in Table 1. - - - **Table 1. Sample Product Orders list** - -|**Column**|**Type**|**Required**| -|:-----|:-----|:-----| -|Product (for example, Title)
    |Single line of text (Text)
    |Yes
    | -|Description
    |Single line of text (Text)
    |No
    | -|Quantity
    |Number
    |Yes
    | -|Order Date
    |Date and Time (DateTime)
    |No
    | -|Fulfillment Date
    |Date and Time (DateTime)
    |No
    | -|Contact Number
    |Single line of text (Text)
    |No
    | - +| Column | Type | Required | +| :--------------------------- | :------------------------- | :------- | +| Product (for example, Title) | Single line of text (Text) | Yes | +| Description | Single line of text (Text) | No | +| Quantity | Number | Yes | +| Order Date | Date and Time (DateTime) | No | +| Fulfillment Date | Date and Time (DateTime) | No | +| Contact Number | Single line of text (Text) | No | ### To implement a class to support editing items while offline - 1. Starting with a Visual Studio project that was created based on the Product Orders list represented by Table 1, in **Solution Explorer**, choose the node that represents the project (for example, SPListAppLocalStorage). - - -2. On the **Project** menu, choose **Add Class**. - +1. On the **Project** menu, choose **Add Class**. + The **Add New Item** dialog box appears with the C# **Class** template selected. - - -3. Name the class file DraftItemStore.cs, and then choose **Add**. - + +1. Name the class file DraftItemStore.cs, and then choose **Add**. + The class file is added to the project and opened for editing. - - -4. Replace the contents of the class file with the following code. - -```cs - -using System; -using System.Net; -using System.Windows; -using System.Collections.Generic; -using System.IO.IsolatedStorage; - -namespace SPListAppLocalStorage // Based on project name by default. -{ - public class DraftItemStore - { - const string DraftsKey = "Drafts"; - public static void AddDraftItem(string id, EditItemViewModel model) - { - Dictionary draftCollection = GetDraftItemCollection(); - draftCollection[id] = model; - SaveDrafts(draftCollection); - } +1. Replace the contents of the class file with the following code. - public static void RemoveDraftItem(string id) - { - Dictionary draftCollection = GetDraftItemCollection(); - draftCollection.Remove(id); - SaveDrafts(draftCollection); - } + ```csharp + using System; + using System.Net; + using System.Windows; + using System.Collections.Generic; + using System.IO.IsolatedStorage; - public static void SaveDrafts(Dictionary draft) + namespace SPListAppLocalStorage // Based on project name by default. + { + public class DraftItemStore { - if (IsolatedStorageSettings.ApplicationSettings.Contains(DraftsKey)) - { - IsolatedStorageSettings.ApplicationSettings[DraftsKey] = draft; - } - else + const string DraftsKey = "Drafts"; + + public static void AddDraftItem(string id, EditItemViewModel model) { - IsolatedStorageSettings.ApplicationSettings.Add(DraftsKey, draft); + Dictionary draftCollection = GetDraftItemCollection(); + draftCollection[id] = model; + SaveDrafts(draftCollection); } - } - public static List Drafts - { - get + public static void RemoveDraftItem(string id) { Dictionary draftCollection = GetDraftItemCollection(); + draftCollection.Remove(id); + SaveDrafts(draftCollection); + } - List modelCollection = new List(); - foreach (KeyValuePair entry in draftCollection) + public static void SaveDrafts(Dictionary draft) + { + if (IsolatedStorageSettings.ApplicationSettings.Contains(DraftsKey)) + { + IsolatedStorageSettings.ApplicationSettings[DraftsKey] = draft; + } + else { - modelCollection.Add(entry.Value); + IsolatedStorageSettings.ApplicationSettings.Add(DraftsKey, draft); } + } + + public static List Drafts + { + get + { + Dictionary draftCollection = GetDraftItemCollection(); - return modelCollection; + List modelCollection = new List(); + foreach (KeyValuePair entry in draftCollection) + { + modelCollection.Add(entry.Value); + } + + return modelCollection; + } } - } - public static Dictionary GetDraftItemCollection() - { - Dictionary draftCollection = null; - if (IsolatedStorageSettings.ApplicationSettings.Contains(DraftsKey)) - draftCollection = (Dictionary)IsolatedStorageSettings.ApplicationSettings[DraftsKey]; + public static Dictionary GetDraftItemCollection() + { + Dictionary draftCollection = null; + if (IsolatedStorageSettings.ApplicationSettings.Contains(DraftsKey)) + draftCollection = (Dictionary)IsolatedStorageSettings.ApplicationSettings[DraftsKey]; - if (draftCollection == null) - draftCollection = new Dictionary(); + if (draftCollection == null) + draftCollection = new Dictionary(); - return draftCollection; - } + return draftCollection; + } - public static EditItemViewModel GetDraftItemById(string id) - { - Dictionary draftCollection = GetDraftItemCollection(); - return !draftCollection.ContainsKey(id) ? null : draftCollection[id]; + public static EditItemViewModel GetDraftItemById(string id) + { + Dictionary draftCollection = GetDraftItemCollection(); + return !draftCollection.ContainsKey(id) ? null : draftCollection[id]; + } } } -} -``` - + ``` The namespace specified in this code is based on the name of the project (SPListAppLocalStorage in this case). You might want to specify a different namespace, based on the name of your project. - - -5. Save the file. - - -A specific instance of the **EditItemViewModel** class represents a SharePoint list item that is being edited on the phone. You can consider a list item that was edited as a "draft item" before changes to the item are saved to the server. In the code in this class, the **AddDraftItem** method adds a specific instance of the **EditItemViewModel** class (that is, a draft item) as a value to a **Dictionary** object, associating the **EditItemViewModel** in the **Dictionary** with a key based on the identifier for the given list item. (An identifier is assigned by SharePoint Server to each item in a list. In a project based on the Windows Phone SharePoint List Application template, that identifier is stored in the **ID** property of the given **ViewModel** class, such as **EditItemViewModel** or **DisplayItemViewModel**, which represents the list item.) The **RemoveDraftItem** method removes an **EditItemViewModel** from the **Dictionary** object based on a specified identifier. Both of these methods use the **GetDraftItemCollection** method to retrieve the **Dictionary** object containing the **EditItemViewModel** objects from isolated storage and both methods use the **SaveDrafts** method to save the modified **Dictionary** object (with a draft item either added to it or removed from it) back to isolated storage. The **GetDraftItemCollection** method first determines whether a "Drafts" **Dictionary** object has been saved to isolated storage. If so, the method returns that **Dictionary** object; otherwise, the method initializes and returns a new **Dictionary** object. The **Drafts** property of the class provides access to the **Dictionary** of draft items by returning a list (that is, an object based on the **List** generic) of draft items as **EditItemViewModel** objects. The **GetDraftItemById** method returns a given draft item from the **Dictionary** object based on a specified identifier value. - - - + +1. Save the file. + +A specific instance of the **EditItemViewModel** class represents a SharePoint list item that is being edited on the phone. You can consider a list item that was edited as a "draft item" before changes to the item are saved to the server. In the code in this class, the **AddDraftItem** method adds a specific instance of the **EditItemViewModel** class (that is, a draft item) as a value to a **Dictionary** object, associating the **EditItemViewModel** in the **Dictionary** with a key based on the identifier for the given list item. (An identifier is assigned by SharePoint Server to each item in a list. In a project based on the Windows Phone SharePoint List Application template, that identifier is stored in the **ID** property of the given **ViewModel** class, such as **EditItemViewModel** or **DisplayItemViewModel**, which represents the list item.) The **RemoveDraftItem** method removes an **EditItemViewModel** from the **Dictionary** object based on a specified identifier. Both of these methods use the **GetDraftItemCollection** method to retrieve the **Dictionary** object containing the **EditItemViewModel** objects from isolated storage and both methods use the **SaveDrafts** method to save the modified **Dictionary** object (with a draft item either added to it or removed from it) back to isolated storage. The **GetDraftItemCollection** method first determines whether a "Drafts" **Dictionary** object has been saved to isolated storage. If so, the method returns that **Dictionary** object; otherwise, the method initializes and returns a new **Dictionary** object. The **Drafts** property of the class provides access to the **Dictionary** of draft items by returning a list (that is, an object based on the **List\** generic) of draft items as **EditItemViewModel** objects. The **GetDraftItemById** method returns a given draft item from the **Dictionary** object based on a specified identifier value. + Now you can add elements to the user interface of the phone app and configure them to use the **DraftItemStore** class for editing list items offline. In the following procedures, you will: - - - - Add and configure a Windows Phone page to display all list items that were saved as draft items to isolated storage on the phone. - - - Add and configure another page, bound to an **EditItemViewModel**, for editing an individual draft item, analogous to the Edit form (EditForm.xaml) for list items. - - - Add a method, **SaveAsDraft**, to the **EditItemViewModel** class that executes the **AddDraftItem** method of the **DraftItemStore** class implemented in the previous procedure. - - - Add an **ApplicationBar** button to the EditForm.xaml file to call the **SaveAsDraft** method. - - - Add an **ApplicationBar** button to the List.xaml file to navigate to the page that displays all list items saved as drafts. - - ### To add a page for displaying all draft items saved on the phone - 1. In **Solution Explorer**, choose the **Views** folder. - - -2. On the **Project** menu, choose **Add New Item**. - +1. On the **Project** menu, choose **Add New Item**. + The **Add New Item** dialog box opens. - - -3. In the **Add New Item** dialog box, under the **Visual C#** node, choose the **Silverlight for Windows Phone** node. - - -4. In the **Templates** pane, choose the **Windows Phone Portrait Page** template. - - -5. Name the file Drafts.xaml, and then choose **Add**. - + +1. In the **Add New Item** dialog box, under the **Visual C#** node, choose the **Silverlight for Windows Phone** node. +1. In the **Templates** pane, choose the **Windows Phone Portrait Page** template. +1. Name the file Drafts.xaml, and then choose **Add**. + The file is added to the project under the **Views** node and opened for editing. - - -6. In the XAML pane of the designer, replace the contents of the file with the following XAML. - -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +1. In the XAML pane of the designer, replace the contents of the file with the following XAML. + + ```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - -``` + + + + + + + ``` The value of the namespace designation `` in this code ("SPListAppLocalStorage.Views.Drafts") will vary depending on the name of your project. - - -7. With the Drafts.xaml file selected in **Solution Explorer**, press F7 to open the associated code-behind file, Drafts.xaml.cs, for editing. - - -8. Replace the contents of the file with the following code. - -```cs - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using Microsoft.Phone.Controls; - -namespace SPListAppLocalStorage.Views -{ - public partial class Drafts : PhoneApplicationPage + +1. With the Drafts.xaml file selected in **Solution Explorer**, press F7 to open the associated code-behind file, Drafts.xaml.cs, for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Windows; + using System.Windows.Controls; + using System.Windows.Documents; + using System.Windows.Input; + using System.Windows.Media; + using System.Windows.Media.Animation; + using System.Windows.Shapes; + using Microsoft.Phone.Controls; + + namespace SPListAppLocalStorage.Views { - public Drafts() + public partial class Drafts : PhoneApplicationPage { - InitializeComponent(); - this.Loaded += new RoutedEventHandler(Drafts_Loaded); - } + public Drafts() + { + InitializeComponent(); + this.Loaded += new RoutedEventHandler(Drafts_Loaded); + } - private void lstBoxDraftItems_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - ListBox lstBox = sender as ListBox; - if (lstBox.SelectedIndex == -1) - return; + private void lstBoxDraftItems_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + ListBox lstBox = sender as ListBox; + if (lstBox.SelectedIndex == -1) + return; - EditItemViewModel selectedDraftItem = lstBox.SelectedItem as EditItemViewModel; - NavigationService.Navigate(new Uri(string.Format("/Views/DraftItemEditForm.xaml?ID={0}", - selectedDraftItem.ID), UriKind.Relative)); + EditItemViewModel selectedDraftItem = lstBox.SelectedItem as EditItemViewModel; + NavigationService.Navigate(new Uri(string.Format("/Views/DraftItemEditForm.xaml?ID={0}", + selectedDraftItem.ID), UriKind.Relative)); - lstBox.SelectedIndex = -1; - } + lstBox.SelectedIndex = -1; + } - void Drafts_Loaded(object sender, RoutedEventArgs e) - { - this.DataContext = DraftItemStore.Drafts; - } + void Drafts_Loaded(object sender, RoutedEventArgs e) + { + this.DataContext = DraftItemStore.Drafts; + } - private void OnCancelButtonClick(object sender, EventArgs e) - { - // Navigate back to initial List View form. - NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); + private void OnCancelButtonClick(object sender, EventArgs e) + { + // Navigate back to initial List View form. + NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); + } } } -} -``` + ``` -9. Save the files. - - +1. Save the files. ### To add a page for editing individual draft items - 1. In **Solution Explorer**, choose the **Views** folder. - - -2. On the **Project** menu, choose **Add New Item**. - +1. On the **Project** menu, choose **Add New Item**. + The **Add New Item** dialog box opens. - - -3. In the **Add New Item** dialog box, under the **Visual C#** node, choose the **Silverlight for Windows Phone** node. - - -4. In the **Templates** pane, choose the **Windows Phone Portrait Page** template. - - -5. Name the file DraftItemEditForm.xaml, and then choose **Add**. - - The file is added to the project under the **Views** node and opened for editing. - - -6. In the XAML pane of the designer, replace the contents of the file with the following XAML. - -``` - - - - - - - - - - - - Product* - - - - Description - - - - - Product Category - - - - - - - - - - Quantity* - - - - Order Date - - - - - Fulfillment Date - - - - - Rush - : - - - - Contact Number - - - - - - - - - - - - - +1. In the **Add New Item** dialog box, under the **Visual C#** node, choose the **Silverlight for Windows Phone** node. +1. In the **Templates** pane, choose the **Windows Phone Portrait Page** template. +1. Name the file DraftItemEditForm.xaml, and then choose **Add**. - -``` + The file is added to the project under the **Views** node and opened for editing. +1. In the XAML pane of the designer, replace the contents of the file with the following XAML. + + ```xml + + + + + + + + + + + Product* + + + + Description + + + + + Product Category + + + + + + + + + + Quantity* + + + + Order Date + + + + + Fulfillment Date + + + + + Rush + : + + + + Contact Number + + + + + + + - The XAML for defining this page is similar to that of the EditForm.xaml file. You can copy the EditForm.xaml file to use as a basis for DraftItemEditForm.xaml, making the modifications to the file as indicated in this markup. - - -7. With the DraftItemEditForm.xaml file chosen in **Solution Explorer**, press F7 to open the associated code-behind file, DraftItemEditForm.xaml.cs, for editing. - - -8. Replace the contents of the file with the following code. - -```cs - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using Microsoft.Phone.Controls; -using Microsoft.SharePoint.Client; -using Microsoft.Phone.Tasks; -using System.Device.Location; -using Microsoft.Phone.Shell; -using Microsoft.SharePoint.Phone.Application; - -namespace SPListAppLocalStorage -{ - public partial class DraftItemEditForm : PhoneApplicationPage + + + + + + + + + ``` + + + The XAML for defining this page is similar to that of the **EditForm.xaml** file. You can copy the **EditForm.xaml** file to use as a basis for **DraftItemEditForm.xaml**, making the modifications to the file as indicated in this markup. + +1. With the **DraftItemEditForm.xaml** file chosen in **Solution Explorer**, press F7 to open the associated code-behind file, **DraftItemEditForm.xaml**.cs, for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net; + using System.Windows; + using System.Windows.Controls; + using System.Windows.Documents; + using System.Windows.Input; + using System.Windows.Media; + using System.Windows.Media.Animation; + using System.Windows.Shapes; + using Microsoft.Phone.Controls; + using Microsoft.SharePoint.Client; + using Microsoft.Phone.Tasks; + using System.Device.Location; + using Microsoft.Phone.Shell; + using Microsoft.SharePoint.Phone.Application; + + namespace SPListAppLocalStorage { - EditItemViewModel viewModel; - - /// - /// Constructor for Draft Item Edit Form. - /// - public DraftItemEditForm() + public partial class DraftItemEditForm : PhoneApplicationPage { - InitializeComponent(); - } + EditItemViewModel viewModel; - protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) - { - // Include initialization of ViewModel here rather than in constructor to be able to use QueryString value. - if (viewModel == null) + /// + /// Constructor for Draft Item Edit Form. + /// + public DraftItemEditForm() { - viewModel = DraftItemStore.GetDraftItemById(NavigationContext.QueryString["ID"].ToString()); + InitializeComponent(); } - viewModel.Initialize(); - this.DataContext = viewModel; - - base.OnNavigatedTo(e); - viewModel.ItemUpdated += new EventHandler(OnItemUpdated); - } - - protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) - { - base.OnNavigatedFrom(e); - viewModel.ItemUpdated -= new EventHandler(OnItemUpdated); - } - - private void OnViewModelInitialization(object sender, InitializationCompletedEventArgs e) - { - this.Dispatcher.BeginInvoke(() => + protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { - // If initialization has failed show error message and return. - if (e.Error != null) + // Include initialization of ViewModel here rather than in constructor to be able to use QueryString value. + if (viewModel == null) { - MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK); - return; + viewModel = DraftItemStore.GetDraftItemById(NavigationContext.QueryString["ID"].ToString()); } - // Set Page's DataContext to current ViewModel instance. - this.DataContext = (sender as EditItemViewModel); - }); - } + viewModel.Initialize(); + this.DataContext = viewModel; - private void OnCancelButtonClick(object sender, EventArgs e) - { - NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); - } + base.OnNavigatedTo(e); + viewModel.ItemUpdated += new EventHandler(OnItemUpdated); + } - private void OnSubmitButtonClick(object sender, EventArgs e) - { - viewModel.UpdateItem(); - } + protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) + { + base.OnNavigatedFrom(e); + viewModel.ItemUpdated -= new EventHandler(OnItemUpdated); + } - private void OnItemUpdated(object sender, ItemUpdatedEventArgs e) - { - this.Dispatcher.BeginInvoke(() => + private void OnViewModelInitialization(object sender, InitializationCompletedEventArgs e) { - if (e.Error != null) + this.Dispatcher.BeginInvoke(() => { - MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK); - return; - } + // If initialization has failed show error message and return. + if (e.Error != null) + { + MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK); + return; + } + + // Set Page's DataContext to current ViewModel instance. + this.DataContext = (sender as EditItemViewModel); + }); + } - // Remove Draft Item from local storage if update to server succeeds. - DraftItemStore.RemoveDraftItem(viewModel.ID.ToString()); - this.NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); - }); - } + private void OnCancelButtonClick(object sender, EventArgs e) + { + NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); + } - private void OnBackButtonClick(object sender, EventArgs e) - { - NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); + private void OnSubmitButtonClick(object sender, EventArgs e) + { + viewModel.UpdateItem(); + } + + private void OnItemUpdated(object sender, ItemUpdatedEventArgs e) + { + this.Dispatcher.BeginInvoke(() => + { + if (e.Error != null) + { + MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK); + return; + } + + // Remove Draft Item from local storage if update to server succeeds. + DraftItemStore.RemoveDraftItem(viewModel.ID.ToString()); + this.NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); + }); + } + + private void OnBackButtonClick(object sender, EventArgs e) + { + NavigationService.Navigate(new Uri("/Views/List.xaml", UriKind.Relative)); + } } } -} -``` + ``` As you can see, the namespace used in this file is based on the name of the project (SPListAppLocalStorage). - - -9. Add the appbar.back.rest.png image to your project for the **ApplicationBar** button (btnBack) declared in the DraftItemEditForm.xaml file. In **Solution Explorer**, choose the **Images** folder node in the project. - - -10. On the **Project** menu, choose **Add Existing Item**. - - -11. In the browser that opens, navigate to the folder in which the standard Windows Phone icon images were installed by the Windows Phone SDK 7.1. - + +1. Add the **appbar.back.rest.png** image to your project for the **ApplicationBar** button (btnBack) declared in the **DraftItemEditForm.xaml** file. In **Solution Explorer**, choose the **Images** folder node in the project. + +11. On the **Project** menu, choose **Add Existing Item**. +1. In the browser that opens, navigate to the folder in which the standard Windows Phone icon images were installed by the Windows Phone SDK 7.1. + > [!NOTE] > The images with a light foreground and a dark background are in `%PROGRAMFILES%(x86)\\Microsoft SDKs\\Windows Phone\\v7.1\\Icons\\dark` in a standard installation of the SDK. -12. Choose the image file named appbar.back.rest.png, and choose **Add**. The image is added to the project under the **Images** node. - - -13. In **Solution Explorer**, choose the image file you just added, and in the **Properties Window** for the file, set the **Build Action** property for the image file to **Content**, and set the **Copy to Output Directory** property to **Copy if newer**. - - -14. Save the files. - - +1. Choose the image file named **appbar.back.rest.png**, and choose **Add**. The image is added to the project under the **Images** node. +1. In **Solution Explorer**, choose the image file you just added, and in the **Properties Window** for the file, set the **Build Action** property for the image file to **Content**, and set the **Copy to Output Directory** property to **Copy if newer**. +1. Save the files. ### To add an ApplicationBar button to the Edit Form for saving an item as a draft +1. In **Solution Explorer**, choose the **EditItemViewModel.cs** file under the **ViewModels** node in the project. Press F7 to open the file for editing. +1. Within the code block (demarcated by opening and closing braces) that implements the **EditItemViewModel** class, add the following public method to the file. -1. In **Solution Explorer**, choose the EditItemViewModel.cs file under the **ViewModels** node in the project. Press F7 to open the file for editing. - - -2. Within the code block (demarcated by opening and closing braces) that implements the **EditItemViewModel** class, add the following public method to the file. - -```cs - -public void SaveAsDraft() -{ - DraftItemStore.AddDraftItem(this.ID.ToString(), this); -} -``` + ```csharp + public void SaveAsDraft() + { + DraftItemStore.AddDraftItem(this.ID.ToString(), this); + } + ``` + +1. In **Solution Explorer**, under the **Views** node in the project, double-click the EditForm.xaml file. -3. In **Solution Explorer**, under the **Views** node in the project, double-click the EditForm.xaml file. - The file is opened for editing in the designer. - - -4. In the XAML pane of the designer, add another button to the `` tag (in addition to the existing **Submit** and **Cancel** buttons), as shown in the following XAML. - -``` - - - - - - - - -``` -5. With the EditForm.xaml file chosen in **Solution Explorer**, press F7 to open the associated code-behind file, EditForm.xaml.cs, for editing. - - -6. Within the code block (demarcated by opening and closing braces) that implements the **EditForm** partial class, add the following event handler to the file. - -```cs - -private void OnSaveDraftButtonClick(object sender, EventArgs e) -{ - viewModel.SaveAsDraft(); -} -``` +1. In the XAML pane of the designer, add another button to the `` tag (in addition to the existing **Submit** and **Cancel** buttons), as shown in the following XAML. -7. Save the files. - - + ```xml + + + + + + + + ``` -### To add an ApplicationBar button to the List View Form to display all draft items +1. With the EditForm.xaml file chosen in **Solution Explorer**, press F7 to open the associated code-behind file, **EditForm.xaml.cs**, for editing. +1. Within the code block (demarcated by opening and closing braces) that implements the **EditForm** partial class, add the following event handler to the file. + ```csharp + private void OnSaveDraftButtonClick(object sender, EventArgs e) + { + viewModel.SaveAsDraft(); + } + ``` + +1. Save the files. + +### To add an ApplicationBar button to the List View Form to display all draft items 1. In **Solution Explorer**, under the **Views** node, double-click the List.xaml file. - + The file is opened for editing in the designer. - - -2. In the XAML pane of the designer, add another button to the **** tag (in addition to the existing **New** and **Refresh** buttons), as shown in the following XAML markup. - -``` - - - - - - - - -``` -3. Add an icon image to your project for the **Drafts** button. In **Solution Explorer**, choose the **Images** folder node in the project. - - -4. On the **Project** menu, choose **Add Existing Item**. - - -5. In the browser that opens, navigate to the folder in which the standard Windows Phone icon images were installed by the Windows Phone SDK 7.1. - +1. In the XAML pane of the designer, add another button to the **\** tag (in addition to the existing **New** and **Refresh** buttons), as shown in the following XAML markup. + + ```xml + + + + + + + + ``` + +1. Add an icon image to your project for the **Drafts** button. In **Solution Explorer**, choose the **Images** folder node in the project. +1. On the **Project** menu, choose **Add Existing Item**. +1. In the browser that opens, navigate to the folder in which the standard Windows Phone icon images were installed by the Windows Phone SDK 7.1. + > [!NOTE] > The images with a light foreground and a dark background are in `%PROGRAMFILES%(x86)\\Microsoft SDKs\\Windows Phone\\v7.1\\Icons\\dark` in a standard installation of the SDK. -6. Choose the image file named appbar.folder.rest.png, and then choose **Add**. - +1. Choose the image file named appbar.folder.rest.png, and then choose **Add**. + The image is added is added to the project under the **Images** node. - - -7. In **Solution Explorer**, choose the image file you just added and in the **Properties Window**, set the **Build Action** property for the image file to **Content** and set the **Copy to Output Directory** property to **Copy if newer**. - - -8. In **Solution Explorer**, choose the List.xaml file under the **Views** node and press F7. The associated code-behind file, List.xaml.cs, is opened for editing. - - -9. Add the following event handler to the file, within the code block (demarcated by opening and closing braces) that implements the **ListForm** partial class. - -```cs - + +1. In **Solution Explorer**, choose the image file you just added and in the **Properties Window**, set the **Build Action** property for the image file to **Content** and set the **Copy to Output Directory** property to **Copy if newer**. +1. In **Solution Explorer**, choose the List.xaml file under the **Views** node and press F7. The associated code-behind file, **List.xaml.cs**, is opened for editing. +1. Add the following event handler to the file, within the code block (demarcated by opening and closing braces) that implements the **ListForm** partial class. + +```csharp + private void OnDraftsButtonClick(object sender, EventArgs e) { NavigationService.Navigate(new Uri("/Views/Drafts.xaml", UriKind.Relative)); } ``` -10. Save all the files in the solution and press F6 to compile the solution. - - +1. Save all the files in the solution and press F6 to compile the solution. + If you start the project and deploy it to a Windows Phone Emulator, you see a **View Drafts** button on the **ApplicationBar** of the List form (Figure 1), which brings up all list items stored as drafts. - - - **Figure 1. Modified List Form with View Drafts button** - - - - - - - ![Modified List Form with View Drafts button](../images/921bd9ab-d9a4-4cb6-b168-9ae53401d6d6.gif) - - - + At first, because no drafts are saved, the page to display drafts will be empty. Choose an item from the List form (to show the Display form (DisplayForm.xaml) for an item), and then choose the **Edit** button to display the Edit form. If you should lose connectivity with the SharePoint Server, you can then choose the **Save Draft** button on the Edit Form (Figure 2) to save any changes you've made to the list item to isolated storage. - - - **Figure 2. Modified Edit Form with Save Draft button** - - - - - - - ![Modified Edit Form with Save Draft button](../images/ce88b78d-5d41-406f-bf51-bee45ad2fe8f.gif) - - - + When the server becomes available again, you can choose the **View Drafts** button on the List form to display the Drafts page (Figure 3). - - - **Figure 3. Drafts page displaying items saved as drafts to isolated storage** - - - - - - - ![Drafts page displaying list items saved as drafts](../images/99ff6118-ed5d-4a21-9c11-3aabec8df1e5.gif) - - - + If you choose an item on the Drafts page, the Draft Item Edit form (DraftItemEditForm.xaml) is displayed (Figure 4) and you can make any additional changes, and then click the **Submit** button to save the edited item to the server. At that point, the item is removed from isolated storage because it's no longer treated as a draft item after it's saved with its changes to the server. - - - **Figure 4. Draft Item Edit Form** - - - - - - - ![The Draft Item Edit Form](../images/e3718687-682a-41a8-92b5-4eff9070348d.gif) - - - + Notice the similarity between the Draft Item Edit form (Figure 4) and the standard Edit form (Figure 2) in this app. The editing experience for items as draft items should be about the same as the editing experience for items in the context of the Edit form. - - - ## See also - - - -- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) - - -- [Local Data Storage for Windows Phone](https://msdn.microsoft.com/library/fdf7e973-5de5-4cfa-bf63-1e65c90744cc%28Office.15%29.aspx) - - -- [How to: Preserve and Restore Application State for Windows Phone](https://msdn.microsoft.com/library/342e97c1-ff92-4cb2-81fa-e46f87c3cfc2%28Office.15%29.aspx) - - -- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) - - -- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) - - -- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) - - -- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=27570) - - -- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) - - +- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) +- [Local Data Storage for Windows Phone](https://msdn.microsoft.com/library/fdf7e973-5de5-4cfa-bf63-1e65c90744cc%28Office.15%29.aspx) +- [How to: Preserve and Restore Application State for Windows Phone](https://msdn.microsoft.com/library/342e97c1-ff92-4cb2-81fa-e46f87c3cfc2%28Office.15%29.aspx) +- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) +- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) +- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) +- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=29233) +- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) diff --git a/docs/general-development/how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md b/docs/general-development/how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md index 3a920316f..98e127672 100644 --- a/docs/general-development/how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md +++ b/docs/general-development/how-to-support-and-convert-sharepoint-field-types-for-windows-phone-apps.md @@ -1,38 +1,24 @@ --- title: Support and convert SharePoint field types for Windows Phone apps -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Implement data-conversion logic to support SharePoint field types in Windows Phone apps. +ms.date: 06/09/2022 ms.assetid: 301e6e58-5153-4ca9-a419-8ae0535ebbed -localization_priority: Normal +ms.localizationpriority: medium --- - - # Support and convert SharePoint field types for Windows Phone apps Implement data-conversion logic to support SharePoint field types in Windows Phone apps. -In projects based on the Windows Phone SharePoint List Application template, the data of many SharePoint field types is processed and coordinated by default conversion logic to be suitable for display and manipulation in the Silverlight user interface of a Windows Phone, but developers can also implement their own custom data handling routines. - - - - -> **Important:** -> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). - - - +In projects based on the Windows Phone SharePoint List Application template, the data of many SharePoint field types is processed and coordinated by default conversion logic to be suitable for display and manipulation in the Silverlight user interface of a Windows Phone, but developers can also implement their own custom data handling routines. +> [!IMPORTANT] +> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). ## SharePoint field types in Windows Phone apps - SharePoint lists are constituted by fields of data (arranged in columns), and a given field is designated to contain data of a certain type (that is, data structured in a certain way). These types are called field types. (Such types may also be called column types, because when you add a column to a SharePoint list, you are adding a column of fields associated with a certain type of data.) These fields are defined by an XML schema. The schema for a field called "Order Date" with a **DateTime** data type (represented as a Date and Time field in the user interface of a Microsoft SharePoint Server) might look like the following. - - - ```XML - @@ -42,53 +28,39 @@ SharePoint lists are constituted by fields of data (arranged in columns), and a ``` Notice in particular the value of the **Type** attribute of the **Field** element in this schema, specified here as "DateTime". List fields created to contain data structured in other ways might be designated with a **Type** value of, say, "Choice" or "Text" or "Boolean". - - - + SharePoint field types cannot be bound directly to Silverlight controls in a Windows Phone app. The data as it is in the SharePoint list must be prepared or processed in a certain way (or, in the standard terminology of Silverlight data binding, converted) in order to be bound to the controls in the app and this preparation and coordination is handled by the ViewModels in projects created from the Windows Phone SharePoint List Application template. Projects based on this template are designed to include default conversion logic to support the binding and display of SharePoint data in a Windows Phone app for a number of standard SharePoint field types (or for custom fields created based on one of these standard types). The field types supported with default conversion logic are listed in Table 1. - - - **Table 1. Field types with provisions for default conversion** +| SharePoint field type | Silverlight data type | +| :---------------------------- | :-------------------------------------------------- | +| Attachments | File | +| Boolean | Boolean | +| Calculated (for display only) | String | +| Choice | String | +| Currency | Numeric | +| DateTime | Date (represented according to locale on the phone) | +| URL | Link | +| Integer | Numeric | +| Location | GeoCoordinate | +| Lookup | String | +| MultiChoice | String | +| Note | String | +| Number | Numeric | +| OutcomeChoice | String | +| Picture | Link | +| Text | String | +| User | String | + +Other SharePoint field types, such as **Guid** fields, can be used in Windows Phone apps, but developers need to provide custom conversion logic to support binding and displaying values for those field types for which no default conversion logic has been provided. (See [Custom conversion logic to provision unsupported field types](#custom-conversion-logic-to-provision-unsupported-field-types) in this article.) -|**SharePoint field type**|**Silverlight data type**| -|:-----|:-----| -|Attachments
    |File
    | -|Boolean
    |Boolean
    | -|Calculated (for display only)
    |String
    | -|Choice
    |String
    | -|Currency
    |Numeric
    | -|DateTime
    |Date (represented according to locale on the phone)
    | -|URL
    |Link
    | -|Integer
    |Numeric
    | -|Location
    |GeoCoordinate
    | -|Lookup
    |String
    | -|MultiChoice
    |String
    | -|Note
    |String
    | -|Number
    |Numeric
    | -|OutcomeChoice
    |String
    | -|Picture
    |Link
    | -|Text
    |String
    | -|User
    |String
    | - -Other SharePoint field types, such as **Guid** fields, can be used in Windows Phone apps, but developers need to provide custom conversion logic to support binding and displaying values for those field types for which no default conversion logic has been provided. (See [Custom conversion logic to provision unsupported field types](#BKMK_ConversionForUnsupportedFields) in this article.) - - - For the purpose of illustrating how the template provides default conversion and support for certain field types, assume a SharePoint list includes a column of fields named "Product Category" designated with a type of **Choice** and associated with several options, such as "Recreation" and "Culinary". The schema for such a field on the server might resemble the following markup. - - - - - ```XML - Recreation @@ -102,448 +74,354 @@ For the purpose of illustrating how the template provides default conversion and ``` This **Choice** field has to be processed in order to be suitable for display in the Windows Phone interface. In this case, the data in the field is represented as a string (for example, "Recreation") within a collection of string values (specifically, as one of the values of the **FieldValuesAsText** property of a **ListItem** object). The conversion logic for **Choice** fields extracts this string to display it in the phone's user interface. The string might be bound to and displayed in a **TextBlock** control in a form. If the value is presented for editing, the default conversion logic for **Choice** fields extracts the available options for the field ("Culinary", "Recreation", "Sartorial", etc.) from the XML schema that defines the field and represents those available options a collection (specifically, as a kind of collection based on the **ObservableCollection(T)** class) of objects that themselves include the specific option (for example, "Culinary") and whether that option has been selected. These operations are all handled in the ViewModel layer of the app. In the View (or Presentation) layer (that is, in the XAML file generated for the Edit form by the Windows Phone SharePoint List Application template), these options are rendered by default as Silverlight **RadioButton** controls within a **ListBox** control. - - - ## Custom conversion for SharePoint field types - In Visual Studio projects that are based on the Windows Phone SharePoint List Application template, the mechanism for handling the coordination and conversion of data between SharePoint and the Windows Phone Silverlight user interface has been designed to be flexible and extensible. - - - + Depending on the design intentions for your particular application, you may want to provide conversion logic to support binding and displaying SharePoint field types that are not provided with conversion logic by default, or you may want to display data for a supported field in a way that differs from the default implementation. - - - + Projects based on the Windows Phone SharePoint List Application template implement a static **Converter** class that includes routines for registering methods for handling data conversion operations specific to given data types. The project includes and registers data conversion routines for certain data types by default. The registration mechanism uses delegates to allow for extensibility. Developers can therefore write their own functions to provide the logic for data conversions and these custom functions can be called when the delegates are invoked instead of the default functions. In order to arrange for custom functions to be called for data conversion operations, register your functions with the **Converter** class using the registration methods of the class. The registration methods are specific to each ViewModel, to accommodate the possibility that you may want to implement and register different functions to process data differently depending on, for example, whether the data will presented for editing or for viewing only (without editing). - - - -> **Tip:** +> [!TIP] > The currency symbol shown in the display form is from SharePoint locale, even if the Windows Phone locale is different. Developers can customize this behavior by using **Converter** objects. - - - To register data conversion functions for the Display form (DisplayForm.xaml), use the **RegisterDisplayFieldValueConverter** method of the **Converter** class. To register functions for the Edit form (EditForm.xaml), use the **RegisterEditFieldValueConverter** method, and for the New form (NewForm.xaml), use the **RegisterNewFieldValueConverter** method. - - - -You can register conversion functions that process data as it comes from the list to be presented in the user interface (that is, functions that determine how to **get** data) and you can register functions that process data from the user interface as its saved to the list on the server (functions that determine how to **set** data). - - - -The **get** functions must match the signature of the following delegate declaration in the **Converter** class. - - - - +You can register conversion functions that process data as it comes from the list to be presented in the user interface (that is, functions that determine how to **get** data) and you can register functions that process data from the user interface as its saved to the list on the server (functions that determine how to **set** data). -```cs +The **get** functions must match the signature of the following delegate declaration in the **Converter** class. +```csharp public delegate object GetConvertedFieldValue(string fieldName, ListItem item, ConversionContext context); ``` The **set** functions must match the signature of the following delegate declaration. - - - - - - -```cs +```csharp public delegate void SetConvertedFieldValue(string fieldName, object fieldValue, ListItem item, ConversionContext context); ``` The **RegisterDisplayFieldValueConverter** method accepts a **get** function only, because the **DisplayItemViewModel** class, as designed, is intended to display but not edit data. The **RegisterEditFieldValueConverter** and the **RegisterNewFieldValueConverter** methods are overloaded to accept a **get** function, a **set** function, or both. - - - + In [How to: Implement business logic and data validation in a Windows Phone app for SharePoint](how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md), a validation routine was developed to verify the format or phone numbers provided by the user of a Windows Phone app. To demonstrate custom data conversion, in the following code sample, we'll implement **get** and **set** functions to handle phone number data in a particular way and register those functions to be used in the Edit and New forms with the **Converter** class. - - - + Assume for the purposes of the following code example that you have created a Windows Phone SharePoint list app based on a Product Orders list created using the Custom List template on the server. Assume that the list has a field named "Contact Number" and that this field is designated as a **Text** field in the list. In the default configuration of a list field designated as a **Text** type on a SharePoint Server, a user can enter any text characters (up to 255 characters). The template provides default conversion logic for displaying and editing data from **Text** fields in SharePoint, but a **Text** field (by default) is not structured to impose or display any specific formatting, such as might be conventionally applied to phone numbers. In your Windows Phone app, you may want phone numbers to be displayed to users in a consistent way and, when saved to the list on the server, formatted in a particular way, even though the underlying field type ( **Text**) is not associated with specific formatting rules. To apply your particular formatting rules, you can implement your own custom data conversion logic in place of the default logic for a supported field type. - - - ### To implement custom data conversion - 1. Assuming you have created a list on a SharePoint Server that includes a **Text** field named "Contact Number" (like the Product Orders sample list used in [How to: Implement business logic and data validation in a Windows Phone app for SharePoint](how-to-implement-business-logic-and-data-validation-in-a-windows-phone-app-for-s.md)), create a Windows Phone app using the Windows Phone SharePoint List Application template in Visual Studio by following the steps detailed in [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md). - - -2. In **Solution Explorer**, choose the node representing the project (named, for example, ContosoSPListApp). - - -3. On the **Project** menu in Visual Studio (or Visual Studio Express for Windows Phone), choose **Add Class**. The **Add New Item** dialog box opens with the C# **Class** template already chosen. - - -4. Specify a name for the class file (such as ContosoConverter.cs) and choose **Add**. The class file is added to the project and opened for editing. - - -5. Replace the contents of the file with the following code. - -```cs - -using System; -using Microsoft.SharePoint.Client; // Added for ListItem. -using Microsoft.SharePoint.Phone.Application; // Added for ConversionContext. -using System.Text.RegularExpressions; - -// Specify a namespace appropriate for your particular project. -namespace ContosoSPListApp -{ - public static class ContosoConverter +1. In **Solution Explorer**, choose the node representing the project (named, for example, ContosoSPListApp). +1. On the **Project** menu in Visual Studio (or Visual Studio Express for Windows Phone), choose **Add Class**. The **Add New Item** dialog box opens with the C# **Class** template already chosen. +1. Specify a name for the class file (such as ContosoConverter.cs) and choose **Add**. The class file is added to the project and opened for editing. +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using Microsoft.SharePoint.Client; // Added for ListItem. + using Microsoft.SharePoint.Phone.Application; // Added for ConversionContext. + using System.Text.RegularExpressions; + + // Specify a namespace appropriate for your particular project. + namespace ContosoSPListApp { - static Regex StandardNumberFormat = - new Regex(@"^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", RegexOptions.Compiled); - - public static object GetConvertedTextFieldValue(string fieldName, - ListItem item, ConversionContext context) + public static class ContosoConverter { - if (item == null) return null; + static Regex StandardNumberFormat = + new Regex(@"^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$", RegexOptions.Compiled); - if (fieldName == "Contact_x0020_Number") + public static object GetConvertedTextFieldValue(string fieldName, + ListItem item, ConversionContext context) { - string contactNumber = string.Empty; - try - { - contactNumber = item.FieldValuesAsText[fieldName]; - } - catch (PropertyOrFieldNotInitializedException) + if (item == null) return null; + + if (fieldName == "Contact_x0020_Number") { - object itemValue = item[fieldName]; - if (itemValue != null) + string contactNumber = string.Empty; + try { - contactNumber = itemValue.ToString(); + contactNumber = item.FieldValuesAsText[fieldName]; + } + catch (PropertyOrFieldNotInitializedException) + { + object itemValue = item[fieldName]; + if (itemValue != null) + { + contactNumber = itemValue.ToString(); + } } - } - // Regularize the formatting of phone number for display in UI. - if (StandardNumberFormat.IsMatch(contactNumber)) - { - // Phone number is in an acceptable format, but formatting it - // in a specific way for visual consistency in the UI. - string properlyFormattedNumber = - StandardNumberFormat.Replace(contactNumber, "($1) $2-$3"); - return properlyFormattedNumber; - } - else - { - // Return a representation of the data adorned in such a way - // as to designate its invalidity. - if (!contactNumber.Contains("Invalid Number")) + // Regularize the formatting of phone number for display in UI. + if (StandardNumberFormat.IsMatch(contactNumber)) { - return string.Format("Invalid Number: {0}", contactNumber); + // Phone number is in an acceptable format, but formatting it + // in a specific way for visual consistency in the UI. + string properlyFormattedNumber = + StandardNumberFormat.Replace(contactNumber, "($1) $2-$3"); + return properlyFormattedNumber; } else { - // Assume data is already adorned with an invalidity designation. - return contactNumber; + // Return a representation of the data adorned in such a way + // as to designate its invalidity. + if (!contactNumber.Contains("Invalid Number")) + { + return string.Format("Invalid Number: {0}", contactNumber); + } + else + { + // Assume data is already adorned with an invalidity designation. + return contactNumber; + } } } + else + { + return item[fieldName]; + } } - else - { - return item[fieldName]; - } - } - public static void SetConvertedTextFieldValue(string fieldName, - object fieldValue, ListItem item, ConversionContext context) - { - if (fieldValue == null) return; - - if (fieldName == "Contact_x0020_Number") + public static void SetConvertedTextFieldValue(string fieldName, + object fieldValue, ListItem item, ConversionContext context) { - // Conventional formats (e.g., 555-555-5555) are acceptable, - // but formatting phone numbers consistently here for storage in list on Server. - string contactNumber = (string)fieldValue; + if (fieldValue == null) return; - if (StandardNumberFormat.IsMatch(contactNumber)) + if (fieldName == "Contact_x0020_Number") { - string properlyFormattedNumber = StandardNumberFormat.Replace - (contactNumber, "($1) $2-$3"); - item[fieldName] = properlyFormattedNumber; - } - else - { - if (!contactNumber.Contains("Invalid Number")) + // Conventional formats (e.g., 555-555-5555) are acceptable, + // but formatting phone numbers consistently here for storage in list on Server. + string contactNumber = (string)fieldValue; + + if (StandardNumberFormat.IsMatch(contactNumber)) { - item[fieldName] = string.Format("Invalid Number: {0}", contactNumber); + string properlyFormattedNumber = StandardNumberFormat.Replace + (contactNumber, "($1) $2-$3"); + item[fieldName] = properlyFormattedNumber; } else { - // Assume data is already adorned with an invalidity designation. - item[fieldName] = contactNumber; - } + if (!contactNumber.Contains("Invalid Number")) + { + item[fieldName] = string.Format("Invalid Number: {0}", contactNumber); + } + else + { + // Assume data is already adorned with an invalidity designation. + item[fieldName] = contactNumber; + } + } + } + else + { + // Allow values for other Text fields to be passed on to list without modification. + item[fieldName] = fieldValue; } - } - else - { - // Allow values for other Text fields to be passed on to list without modification. - item[fieldName] = fieldValue; } } } -} -``` + ``` + +1. Save the file. -6. Save the file. - - The **GetConvertedTextFieldValue** function here determines whether string data from a field intended to contain a phone number (named "Contact Number" in this example) is formatted according to standard conventions for phone numbers (in North America) and, if so, converts the number into a specific format for display, "(XXX) XXX-XXXX". If the data is not formatted as a standard phone number, it is prefixed with a designator. This function doesn't actually change the data in the list. The **SetConvertedTextFieldValue** function, on the other hand, proceeds in the opposite direction. It checks the value of data supplied for a field by a user to determine whether the supplied data matches the pattern for standard phone numbers or not. If so, the supplied value is converted into a specific format to be saved to the list on the server. If the supplied value is not in a standard format, the value is prefixed with a designator and that prefixed value is then saved to the server. - - - + It remains now to register these data-conversion functions with the **Converter** class for use on the Edit and New forms. You can register the converters in several places. In the following procedure, the converters are registered in the **OnNavigatedTo** event of the List form (List.xaml). The List form is created and navigated to before the Edit and New forms are instantiated in the app, so the converters registered in this event in the List form will take effect for text fields in all the forms. - - - ### To register the data-conversion functions - 1. In **Solution Explorer** for the same project in which you created the class in the previous procedure, choose the List.xaml file under the **Views** node. - - -2. Press F7 to open the associated code-behind file, List.xaml.cs, for editing. - - -3. Add the following private variable declaration to the top of the code block that implements the **ListForm** partial class, after the opening brace in the code block and before the `ListForm()` constructor. - -```cs - -private bool _isConversionRegistered; -``` +1. Press F7 to open the associated code-behind file, List.xaml.cs, for editing. +1. Add the following private variable declaration to the top of the code block that implements the **ListForm** partial class, after the opening brace in the code block and before the `ListForm()` constructor. -4. Add the following method, **RegisterTextFieldValueConverters**, to the file, within the code block (demarcated by opening and closing braces) that implements the **ListForm** partial class. - -```cs - private void RegisterTextFieldValueConverters() -{ - Converter.RegisterEditFieldValueConverter(FieldType.Text, - ContosoConverter.GetConvertedTextFieldValue, - ContosoConverter.SetConvertedTextFieldValue); - - Converter.RegisterNewFieldValueConverter(FieldType.Text, - ContosoConverter.GetConvertedTextFieldValue, - ContosoConverter.SetConvertedTextFieldValue); -} -``` + ```csharp + private bool _isConversionRegistered; + ``` +1. Add the following method, **RegisterTextFieldValueConverters**, to the file, within the code block (demarcated by opening and closing braces) that implements the **ListForm** partial class. + + ```csharp + private void RegisterTextFieldValueConverters() + { + Converter.RegisterEditFieldValueConverter(FieldType.Text, + ContosoConverter.GetConvertedTextFieldValue, + ContosoConverter.SetConvertedTextFieldValue); + + Converter.RegisterNewFieldValueConverter(FieldType.Text, + ContosoConverter.GetConvertedTextFieldValue, + ContosoConverter.SetConvertedTextFieldValue); + } + ``` This method simply calls the appropriate registration methods of the **Converter** class. It is assumed for this code that the custom class containing the **get** and **set** functions created in the preceding procedure is named "ContosoConverter". If you specified a different name for your class, change the code here accordingly. - - -5. Modify the implementation of the **OnNavigatedTo** event handler in the file by adding a check for the value of the **_isConversionRegistered** flag and a call to the **RegisterTextFieldValueConverters** function added in the previous step. The modified handler should be as follows. - -```cs - -protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) -{ - base.OnNavigatedTo(e); - - App.MainViewModel.ViewDataLoaded += - new EventHandler(OnViewDataLoaded); - App.MainViewModel.InitializationCompleted += - new EventHandler(OnViewModelInitialization); - - // The OnNavigatedTo event can fire more than once, but the converters only need - // to be registered once, so checking the conversion flag first. - if (_isConversionRegistered == false) + +1. Modify the implementation of the **OnNavigatedTo** event handler in the file by adding a check for the value of the **_isConversionRegistered** flag and a call to the **RegisterTextFieldValueConverters** function added in the previous step. The modified handler should be as follows. + + ```csharp + protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { - // Register converters. - RegisterTextFieldValueConverters(); - _isConversionRegistered = true; + base.OnNavigatedTo(e); + + App.MainViewModel.ViewDataLoaded += + new EventHandler(OnViewDataLoaded); + App.MainViewModel.InitializationCompleted += + new EventHandler(OnViewModelInitialization); + + // The OnNavigatedTo event can fire more than once, but the converters only need + // to be registered once, so checking the conversion flag first. + if (_isConversionRegistered == false) + { + // Register converters. + RegisterTextFieldValueConverters(); + _isConversionRegistered = true; + } } -} -``` + ``` + +1. Save the file. -6. Save the file. - - Note that the data conversion functions are registered for all fields associated with a **Text** data type in the Edit and New forms. It is for this reason that the **get** and **set** functions implemented for the **ContosoConverter** class created in the preceding procedure include conditional checks to process the data for a particular field only (named, in this case, "Contact_x0020_Number"), allowing the data to "pass through" for other **Text** fields. - - - ## Custom conversion logic to provision unsupported field types - Even if you don't provide conversion logic in your app for **Text** fields, such fields can still be displayed and edited. Providing your own conversion logic for fields that are already provided with default conversion logic gives you a greater degree of control over the format or the structure of the data in those fields if the default logic is not suited to your design intentions. For fields with certain other data types, like **Guid** fields, conversion logic is not provided by default, but if you understand the mechanism (described in the preceding section) by which conversion logic is provided for fields, it may be fairly simple to provide your own conversion logic to support field types in your app that are not supported with default logic by the Windows Phone SharePoint List Application template. - - - + Assume you are creating a Windows Phone app based on a SharePoint list named Product Identifiers, which includes a field with a **Guid** data type. For the purpose of the following code sample, assume the list has a Product (or Title) field (of type **Text**) and an Identifier field (of type **Guid**). - + > [!NOTE] > SharePoint lists with **Guid** fields must be created programmatically or from a list template that includes **Guid** fields. - - - In a Windows Phone app created using the template and based on this simple list, the data in **Guid** fields is not displayed by default. (In place of that data, a message like the following will be displayed: "No Converter for field type 'Guid' is registered.") In the following procedure, you will include conversion logic to support **Guid** fields for a Windows Phone app. You add a class that contains methods to register field value converters to display GUIDs and to generate new GUID values for added list items. - - - ### To provide conversion logic for an unsupported field type - 1. In a project (named, for instance, SPListAppGuidConversion) created from the Windows Phone SharePoint List Application and based on the Product Identifiers list mentioned above, choose the node representing the project in **Solution Explorer**. - - -2. On the **Project** menu, choose **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. - - -3. Specify GuidConversion.cs as the name of the file and choose **Add**. The class file is added to the solution and opened for editing - - -4. Replace the contents of the file with the following code. - -```cs - -using System; -using Microsoft.SharePoint.Phone.Application; -using Microsoft.SharePoint.Client; - -namespace SPListAppGuidConversion -{ - public class GuidConversion +1. On the **Project** menu, choose **Add Class**. The **Add New Item** dialog box appears with the C# **Class** template already selected. +1. Specify GuidConversion.cs as the name of the file and choose **Add**. The class file is added to the solution and opened for editing +1. Replace the contents of the file with the following code. + + ```csharp + using System; + using Microsoft.SharePoint.Phone.Application; + using Microsoft.SharePoint.Client; + + namespace SPListAppGuidConversion { - /// - /// Registers a GET converter to prepare GUID values for display. - /// - static public void RegisterDisplayFieldGuidConverter() + public class GuidConversion { - // Register GET converter to display GUID values. - Converter.RegisterDisplayFieldValueConverter(FieldType.Guid, - getConvertedFieldValue: (string fieldName, ListItem item, ConversionContext context) => + /// + /// Registers a GET converter to prepare GUID values for display. + /// + static public void RegisterDisplayFieldGuidConverter() { - string guidValue = string.Empty; - - try - { - guidValue = item.FieldValuesAsText[fieldName]; - } - catch (PropertyOrFieldNotInitializedException) - { - object itemValue = item[fieldName]; - if (itemValue != null) - { - guidValue = itemValue.ToString(); - } - } - - if (string.IsNullOrWhiteSpace(guidValue)) + // Register GET converter to display GUID values. + Converter.RegisterDisplayFieldValueConverter(FieldType.Guid, + getConvertedFieldValue: (string fieldName, ListItem item, ConversionContext context) => { - return string.Format("{{{0}}}", Guid.Empty); - } - else - { - Guid g = new Guid(); + string guidValue = string.Empty; - if (Guid.TryParse(guidValue, out g)) + try { - guidValue = string.Format("{{{0}}}", g.ToString().ToUpper()); - return guidValue; + guidValue = item.FieldValuesAsText[fieldName]; } - else + catch (PropertyOrFieldNotInitializedException) { - return "Invalid Identifier (GUID)"; + object itemValue = item[fieldName]; + if (itemValue != null) + { + guidValue = itemValue.ToString(); + } } - } - }); - } - /// - /// Registers GET and SET converters for GUID value of new (i.e., added) list items. - /// - public static void RegisterNewFieldGuidConverter() - { - Converter.RegisterNewFieldValueConverter(FieldType.Guid, - getConvertedFieldValue: (string fieldName, ListItem item, - ConversionContext context) => Guid.NewGuid().ToString(), - setConvertedFieldValue: (string fieldName, object fieldValue, - ListItem item, ConversionContext context) => - { - if (fieldValue == null) + if (string.IsNullOrWhiteSpace(guidValue)) { - item[fieldName] = Guid.Empty.ToString(); + return string.Format("{{{0}}}", Guid.Empty); } else { - item[fieldName] = fieldValue; + Guid g = new Guid(); + + if (Guid.TryParse(guidValue, out g)) + { + guidValue = string.Format("{{{0}}}", g.ToString().ToUpper()); + return guidValue; + } + else + { + return "Invalid Identifier (GUID)"; + } } }); + } + + /// + /// Registers GET and SET converters for GUID value of new (i.e., added) list items. + /// + public static void RegisterNewFieldGuidConverter() + { + Converter.RegisterNewFieldValueConverter(FieldType.Guid, + getConvertedFieldValue: (string fieldName, ListItem item, + ConversionContext context) => Guid.NewGuid().ToString(), + setConvertedFieldValue: (string fieldName, object fieldValue, + ListItem item, ConversionContext context) => + { + if (fieldValue == null) + { + item[fieldName] = Guid.Empty.ToString(); + } + else + { + item[fieldName] = fieldValue; + } + }); + } } } -} -``` - + ``` In this custom class, the **RegisterDisplayFieldValueConverter** and the **RegisterNewFieldValueConverter** methods of the **Converter** class are called using anonymous functions (defined by a statement lambda) to implement the **get** and **set** routines for the delegates required by the registration methods. The optional argument labels here (for example, "getConvertedFieldValue:") are included in this code only to clarify which delegates are defined.) - - This approach, involving lambda expressions, is an alternative to passing named functions as parameters to the converter registration functions, which was demonstrated in an earlier procedure described in this topic (in the section [To register the data conversion functions](#BKMK_RegisterFunctions)). - - -5. Save the file. - - -6. In **Solution Explorer**, choose the App.xaml file. - - -7. Press F7 to open the associated code-behind file, App.xaml.cs, for editing. - - -8. Locate the implementation of the **Application_Launching** event handler (which is empty in a new project created from the Windows Phone SharePoint List Application template) and replace it with the following code. - -```cs - -private void Application_Launching(object sender, LaunchingEventArgs e) -{ - // Register converters for GUID fields. Converters can be - // registered just once for the app. - GuidConversion.RegisterDisplayFieldGuidConverter(); - GuidConversion.RegisterNewFieldGuidConverter(); -} -``` -9. For the converter logic to work for new list items (that is, to generate GUID values when items are added to the list), you need to ensure that the Identifier field of the **NewItemViewModel** is bound to the New form. One way of doing this is by adding a hidden **TextBlock** control to NewForm.xaml with a **Binding** declaration for its **Text** property set to the Identifier field. You can add the **TextBlock** control to the **StackPanel** container control that includes the **TextBox** control for the Title field, as in the following section of the markup in the NewForm.xaml file. - -``` - -... - - + Visibility="{Binding ShowIfBusy}" /> - + Title* - @@ -552,75 +430,36 @@ private void Application_Launching(object sender, LaunchingEventArgs e) -... -``` - + ``` Save the file. - - + If you start the project and deploy the app to the Windows Phone Emulator to run it, data in the Identifier field is displayed in the List form (List.xaml) if the corresponding field in the SharePoint list contains a GUID value. (See Figure 1.) - - - **Figure 1. Displaying Guid fields** - - - - - - - ![Displaying Guid fields](../images/eb20da0e-793f-43af-aa5e-67f85cdfa2df.gif) - - - -In projects based on the Windows Phone SharePoint List Application template, Silverlight controls may not be added to forms and bound to field types that are not supported with default conversion logic in the template. For the Identifiers field of the Product Identifiers list used in the preceding procedure, you could add markup to the DisplayForm.xaml file to define additional controls to display GUID values, such as a **TextBlock** control and a **TextBox** control in a **StackPanel** control, which is itself contained within the **Grid** control of the user interface. The markup for the added **StackPanel** control could resemble the following. - - - - +In projects based on the Windows Phone SharePoint List Application template, Silverlight controls may not be added to forms and bound to field types that are not supported with default conversion logic in the template. For the Identifiers field of the Product Identifiers list used in the preceding procedure, you could add markup to the DisplayForm.xaml file to define additional controls to display GUID values, such as a **TextBlock** control and a **TextBox** control in a **StackPanel** control, which is itself contained within the **Grid** control of the user interface. The markup for the added **StackPanel** control could resemble the following. -``` - +```xml - Identifier: - ``` Now the Identifier field is shown on the Display form as well as on the List form. - - - ## See also - - - -- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) - - -- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) - - -- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) - - -- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) - - -- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=27570) - - -- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) - - +- [Build Windows Phone apps that access SharePoint](build-windows-phone-apps-that-access-sharepoint.md) +- [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md) +- [Windows Phone SDK 8.0](https://www.microsoft.com/download/details.aspx?id=35471) +- [Microsoft SharePoint SDK for Windows Phone 8](https://www.microsoft.com/download/details.aspx?id=36818) +- [Windows Phone SDK 7.1](https://www.microsoft.com/download/details.aspx?id=29233) +- [Microsoft SharePoint SDK for Windows Phone 7.1](https://www.microsoft.com/download/details.aspx?id=30476) diff --git a/docs/general-development/how-to-trust-a-location.md b/docs/general-development/how-to-trust-a-location.md index d9d4ed81b..fe7a5a2bc 100644 --- a/docs/general-development/how-to-trust-a-location.md +++ b/docs/general-development/how-to-trust-a-location.md @@ -1,12 +1,12 @@ --- title: Trust a location -ms.date: 09/25/2017 +description: Describes trusted locations, provides steps on how to trust a location, and provides links to related articles. +ms.date: 06/13/2022 keywords: how to,howdoi,howto,trusted location f1_keywords: - how to,howdoi,howto,trusted location -ms.prod: sharepoint ms.assetid: 0f396c0b-f578-4d1a-9e6b-a75f352265ab -localization_priority: Normal +ms.localizationpriority: medium --- diff --git a/docs/general-development/how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md b/docs/general-development/how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md index a25c61bf2..1ac94d865 100644 --- a/docs/general-development/how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md +++ b/docs/general-development/how-to-use-a-custom-security-trimmer-for-sharepoint-server-search-results.md @@ -1,466 +1,332 @@ --- title: Use a custom security trimmer for SharePoint Server search results -ms.date: 09/25/2017 -ms.prod: sharepoint +description: This how-to guides you through the steps to implement—create, deploy, and register—a custom security trimmer for Search in SharePoint by using Microsoft Visual Studio 2010. +ms.date: 12/29/2020 ms.assetid: e1a8664e-fb43-45c2-83aa-9635fe1efc99 -localization_priority: Normal +ms.localizationpriority: medium --- - - # Use a custom security trimmer for SharePoint Server search results This how-to guides you through the steps to implement—create, deploy, and register—a custom security trimmer for Search in SharePoint by using Microsoft Visual Studio 2010. Search in SharePoint performs query-time security trimming of search results. However, there may be scenarios in which you want to perform custom security trimming. Search in SharePoint provides support for these scenarios through the [Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) , [Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) , and [ISecurityTrimmer2](https://msdn.microsoft.com/library/office/microsoft.office.server.search.query.isecuritytrimmer2.aspx) (deprecated) interfaces in the [Microsoft.Office.Server.Search.Query](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.aspx) namespace. - - - There are two kinds of custom security trimming: Pre-trimming and post-trimming. Pre-trimming refers to pre-query evaluation where the query is rewritten to add security information before the query is matched to the search index. Post-trimming refers to post-query evaluation where the search results are pruned before they are returned to the user. We recommend the use of pre-trimming for performance and general correctness; post-trimming prevents information leakage for refiner data and hit count instances. - - - The security trimmer registration process enables you to specify configuration properties for the custom security trimmer. + ## Overview Custom Security Trimming in Search in SharePoint consists of two interfaces that can be used to carry out pre-trimming or post-trimming of your search results. This how-to focuses on both interfaces, describing the steps necessary to create and register your own security trimmers. - - - ## Prerequisites - To complete this how-to, you must have the following installed in your development environment: - - - - Search in Microsoft SharePoint - - - Microsoft Visual Studio 2010 or similar Microsoft .NET Framework-compatible development tool - - ## Set up a custom security trimmer project - In this step, you will create the custom security trimmer project, and then add the required references to the project. - - - ### To create the project for a custom security trimmer - 1. Open Visual Studio and choose **File**, **New**, **Project**. - - -2. In **Project types**, under **C#**, choose **SharePoint**. - - -3. Under **Templates**, choose **Empty SharePoint Project**. In the **Name** field, type **CustomSecurityTrimmerSample**, and then choose the **OK** button. - - -4. In the **SharePoint Customization Wizard**, choose **Deploy as a farm solution**, and then choose **Finish**. - - +1. In **Project types**, under **C#**, choose **SharePoint**. +1. Under **Templates**, choose **Empty SharePoint Project**. In the **Name** field, type **CustomSecurityTrimmerSample**, and then choose the **OK** button. +1. In the **SharePoint Customization Wizard**, choose **Deploy as a farm solution**, and then choose **Finish**. ### To add references to the custom security trimmer project - 1. On the **Project** menu, choose **Add Reference**. - - -2. On the **.NET** tab, choose the references with the following component names, and then choose the **OK** button: - - - **Microsoft Search component** - +1. On the **.NET** tab, choose the references with the following component names, and then choose the **OK** button: + + - **Microsoft Search component** + You should see two entries on the **.NET** tab with the component name **Microsoft Search component**. Select the entry where the Path column is \\ISAPI\\Microsoft.Office.Server.Search.dll. If this entry is missing from the **.NET** tab in the **Add References** dialog box, you must add the reference from the **Browse** tab by using the path to the Microsoft.Office.Server.Search.dll. - - - - **Microsoft.IdentityModel** - + + - **Microsoft.IdentityModel** + If **Microsoft.IdentityModel** is not listed on the **.NET** tab, you must add the reference to the Microsoft.IdentityModel.dll from the **Browse** tab, by using the following path: - - `%ProgramFiles%\\Reference Assemblies\\Microsoft\\Windows Identity Foundation\\v4.0.` - - -## Create a custom security pre-trimmer - + `%ProgramFiles%\\Reference Assemblies\\Microsoft\\Windows Identity Foundation\\v4.0.` +## Create a custom security pre-trimmer ### To create the class file for the security pre-trimmer - 1. On the **Project** menu, choose **Add New Item**. - - -2. Under **Visual C# Items** in **Installed Templates**, choose **Code**, and then choose **Class**. - - -3. Type **CustomSecurityPreTrimmer.cs**, and then choose **Add**. - - +1. Under **Visual C# Items** in **Installed Templates**, choose **Code**, and then choose **Class**. +1. Type **CustomSecurityPreTrimmer.cs**, and then choose **Add**. ### Writing the custom security pre-trimmer code Your custom security trimmer must implement the **ISecurityTrimmerPre** interface. The following code example is a basic implementation of this interface. - - - ### To modify the default code in CustomSecurityPreTrimmer - 1. Add the following **using** directives at the beginning of the class. - -```cs - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Security.Principal; -using Microsoft.IdentityModel.Claims; -using Microsoft.Office.Server.Search.Query; -using Microsoft.Office.Server.Search.Administration; -``` + ```csharp + using System; + using System.Collections; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Security.Principal; + using Microsoft.IdentityModel.Claims; + using Microsoft.Office.Server.Search.Query; + using Microsoft.Office.Server.Search.Administration; + ``` + +1. Specify that the **CustomSecurityPreTrimmer** class implements the [ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) interface in the class declaration, as shown in the following code. -2. Specify that the **CustomSecurityPreTrimmer** class implements the [ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) interface in the class declaration, as shown in the following code. - -```cs - +```csharp public class CustomSecurityPreTrimmer : ISecurityTrimmerPre ``` - ### To implement the ISecurityTrimmerPre interface methods - 1. Add the following code for the [Initialize()](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.Initialize.aspx) method declaration. - -```cs - public void Initialize(NameValueCollection staticProperties, SearchServiceApplication searchApplication) -{ - -} -``` + ```csharp + public void Initialize(NameValueCollection staticProperties, SearchServiceApplication searchApplication) + { + } + ``` The basic version of this sample does not include any code in the **Initialize** method. - - -2. Add the following code for the [AddAccess()](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.AddAccess.aspx) method declaration. - -```cs - -public IEnumerable> AddAccess( - IDictionary sessionProperties, IIdentity passedUserIdentity) -{ -//AddAccess method implementation, see steps 3-5. -} -``` - -3. For the first part of the **AddAccess** method implementation, we find out who the user is by looking at the _passedUserIdentity_. - -```cs - -if (passedUserIdentity == null) -{ - throw new ArgumentException("AddAccess method is called with invalid user identity - parameter", "passedUserIdentity"); -} - - String strUser = null; - var claimsIdentity = (IClaimsIdentity)passedUserIdentity; - if (claimsIdentity != null) - { - foreach (var claim in claimsIdentity.Claims) - { - if (claim == null) - { - continue; - } - - // strUser is "domain\\\\user" format when web app is in Claims Windows Mode - if (SPClaimTypes.Equals(claim.ClaimType, SPClaimTypes.UserLogonName)) - { - strUser = claim.Value; - break; - } - - // strUser2 is "S-1-5-21-2127521184-1604012920-1887927527-66602" when web app is - in Legacy Windows Mode - // In this case we need to convert it into NT user format. - if (SPClaimTypes.Equals(claim.ClaimType, ClaimTypes.PrimarySid)) - { - strUser = claim.Value; - SecurityIdentifier sid = new SecurityIdentifier(strUser); - strUser = sid.Translate(typeof(NTAccount)).Value; - break; - } - } -} - -``` - -4. Create a list, populate the list with claims and return the list, as shown in the following code. - -```cs - -var claims = new LinkedList>(); -if (!string.IsNullOrEmpty(strUser)) - { - var groupMembership = GetMembership(strUser); - if (!string.IsNullOrEmpty(groupMembership)) - { - var groups = groupMembership.Split(new[] {';'}, - StringSplitOptions.RemoveEmptyEntries); - foreach (var group in groups) - { - claims.AddLast(new Tuple( - new Claim("http://schemas.happy.bdc.microsoft.com/claims/acl", group), false)); - } - } - } - return claims; -} - -``` +1. Add the following code for the [AddAccess()](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.AddAccess.aspx) method declaration. + + ```csharp + public IEnumerable> AddAccess( + IDictionary sessionProperties, IIdentity passedUserIdentity) + { + //AddAccess method implementation, see steps 3-5. + } + ``` + +1. For the first part of the **AddAccess** method implementation, we find out who the user is by looking at the _passedUserIdentity_. + + ```csharp + if (passedUserIdentity == null) + { + throw new ArgumentException("AddAccess method is called with invalid user identity + parameter", "passedUserIdentity"); + } + + String strUser = null; + var claimsIdentity = (IClaimsIdentity)passedUserIdentity; + if (claimsIdentity != null) + { + foreach (var claim in claimsIdentity.Claims) + { + if (claim == null) + { + continue; + } + + // strUser is "domain\\\\user" format when web app is in Claims Windows Mode + if (SPClaimTypes.Equals(claim.ClaimType, SPClaimTypes.UserLogonName)) + { + strUser = claim.Value; + break; + } + + // strUser2 is "S-1-5-21-2127521184-1604012920-1887927527-66602" when web app is + in Legacy Windows Mode + // In this case we need to convert it into NT user format. + if (SPClaimTypes.Equals(claim.ClaimType, ClaimTypes.PrimarySid)) + { + strUser = claim.Value; + SecurityIdentifier sid = new SecurityIdentifier(strUser); + strUser = sid.Translate(typeof(NTAccount)).Value; + break; + } + } + } + ``` + +1. Create a list, populate the list with claims and return the list, as shown in the following code. + + ```csharp + var claims = new LinkedList>(); + if (!string.IsNullOrEmpty(strUser)) + { + var groupMembership = GetMembership(strUser); + if (!string.IsNullOrEmpty(groupMembership)) + { + var groups = groupMembership.Split(new[] {';'}, + StringSplitOptions.RemoveEmptyEntries); + foreach (var group in groups) + { + claims.AddLast(new Tuple( + new Claim("http://schemas.happy.bdc.microsoft.com/claims/acl", group), false)); + } + } + } + return claims; + } + ``` The **GetMembership** method contains the custom logic of your trimmer. - - ## Create a custom security post-trimmer - - ### To create the class file for the security post-trimmer - 1. On the **Project** menu, choose **Add New Item**. - - -2. Under **Visual C# Items** in **Installed Templates**, choose **Code**, and then choose **Class**.. - - -3. Type CustomSecurityPostTrimmer.cs, and then choose **Add**. - - +1. Under **Visual C# Items** in **Installed Templates**, choose **Code**, and then choose **Class**.. +1. Type CustomSecurityPostTrimmer.cs, and then choose **Add**. ### Writing the custom security post-trimmer code Your custom security trimmer must implement the **ISecurityTrimmerPost** interface. The code example in this section is a basic implementation of this interface. - - - ### To modify the default code in CustomSecurityPostTrimmer - 1. Add the following **using** directives at the beginning of the class: - -```cs - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Security.Principal; -using Microsoft.IdentityModel.Claims; -using Microsoft.Office.Server.Search.Query; -using Microsoft.Office.Server.Search.Administration; -``` + ```csharp + using System; + using System.Collections; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Security.Principal; + using Microsoft.IdentityModel.Claims; + using Microsoft.Office.Server.Search.Query; + using Microsoft.Office.Server.Search.Administration; + ``` -2. Specify that the **CustomSecurityPostTrimmer** class implements the [ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) interface in the class declaration, as follows: - -```cs - -public class CustomSecurityPostTrimmer : ISecurityTrimmerPost -``` +1. Specify that the **CustomSecurityPostTrimmer** class implements the [ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) interface in the class declaration, as follows: + ```csharp + public class CustomSecurityPostTrimmer : ISecurityTrimmerPost + ``` ### To implement the ISecurityTrimmerPost interface methods - 1. Add the following code for the [Initialize()](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.Initialize.aspx) method declaration. - -```cs - public void Initialize(NameValueCollection staticProperties, SearchServiceApplication searchApplication) -{ -} -``` + ```csharp + public void Initialize(NameValueCollection staticProperties, SearchServiceApplication searchApplication) + { + } + ``` The basic version of this sample does not include any code in the Initialize method. - - -2. Add the following code for the [CheckAccess()](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.CheckAccess.aspx) method declaration. - -```cs - -public BitArray CheckAccess(IList documentCrawlUrls, IList documentAcls, IDictionary sessionProperties, IIdentity passedUserIdentity) -{ -//CheckAccess method implementation, see steps 3-5. -} -``` - -3. For the first part of the **CheckAccess** method implementation, declare and initialize a **BitArray** variable to store the results of the access check for each URL in the **documentCrawlUrls** collection, and retrieve the user who submitted the query, as shown in the following code. - -```cs - -if (documentCrawlUrls == null) -{ - throw new ArgumentException("CheckAccess method is called with invalid URL list", - "documentCrawlUrls"); -} -if (documentAcls == null) -{ - throw new ArgumentException("CheckAccess method is called with invalid documentAcls - list", "documentAcls"); -} -if (passedUserIdentity == null) -{ - throw new ArgumentException("CheckAccess method is called with invalid user identity - parameter", "passedUserIdentity"); -} - -``` - -4. Loop through each crawl URL in the collection, and perform the access check to determine if the user who submitted the query can access the crawl URL's associated content item, as shown in the following code. - -```cs - -// Initialize the bit array with TRUE value which means all results are visible by default. -var urlStatusArray = new BitArray(documentCrawlUrls.Count, true); -var claimsIdentity = (IClaimsIdentity)passedUserIdentity; -if (claimsIdentity != null) -{ - var userGroups = GetGroupList(claimsIdentity.Claims); - var numberDocs = documentCrawlUrls.Count; - for (var i = 0; i < numberDocs; ++i) - { - if (!string.IsNullOrEmpty(documentAcls[i])) - { - urlStatusArray[i] = VerifyAccess(documentAcls[i], userGroups); - } - } -} -``` +1. Add the following code for the [CheckAccess()](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.CheckAccess.aspx) method declaration. + + ```csharp + public BitArray CheckAccess(IList documentCrawlUrls, IList documentAcls, IDictionary sessionProperties, IIdentity passedUserIdentity) + { + //CheckAccess method implementation, see steps 3-5. + } + ``` + +1. For the first part of the **CheckAccess** method implementation, declare and initialize a **BitArray** variable to store the results of the access check for each URL in the **documentCrawlUrls** collection, and retrieve the user who submitted the query, as shown in the following code. + + ```csharp + if (documentCrawlUrls == null) + { + throw new ArgumentException("CheckAccess method is called with invalid URL list", + "documentCrawlUrls"); + } + if (documentAcls == null) + { + throw new ArgumentException("CheckAccess method is called with invalid documentAcls + list", "documentAcls"); + } + if (passedUserIdentity == null) + { + throw new ArgumentException("CheckAccess method is called with invalid user identity + parameter", "passedUserIdentity"); + } + ``` + +1. Loop through each crawl URL in the collection, and perform the access check to determine if the user who submitted the query can access the crawl URL's associated content item, as shown in the following code. + + ```csharp + // Initialize the bit array with TRUE value which means all results are visible by default. + var urlStatusArray = new BitArray(documentCrawlUrls.Count, true); + var claimsIdentity = (IClaimsIdentity)passedUserIdentity; + if (claimsIdentity != null) + { + var userGroups = GetGroupList(claimsIdentity.Claims); + var numberDocs = documentCrawlUrls.Count; + for (var i = 0; i < numberDocs; ++i) + { + if (!string.IsNullOrEmpty(documentAcls[i])) + { + urlStatusArray[i] = VerifyAccess(documentAcls[i], userGroups); + } + } + } + ``` If the user has access to the content item, set the value of the **BitArray** item at that index, **urlStatusArray[i]**, to **true**; otherwise, set it to **false**. - - -5. Set the return value of the **CheckAccess** method to **urlStatusArray**, as shown in the following code. - -```cs - -return urlStatusArray; -``` +1. Set the return value of the **CheckAccess** method to **urlStatusArray**, as shown in the following code. + + ```csharp + return urlStatusArray; + ``` ## Register the custom security trimmer - This step describes how to configure the custom security trimmer, and includes the following tasks: - - - - Registering the custom security trimmer for the Search service application by using the Windows PowerShell cmdlets. - - - Restarting the SharePoint search host controller (SPSearchHostController). - - ### Register the custom security trimmer You use the SharePoint Management Shell to register a custom security trimmer with _ClassName_. In our case, _ClassName_ could be either **CustomSecurityPreTrimmer** or **CustomSecurityPostTrimmer**. The following procedure shows how to register a custom security trimmer, with the ID set to 1 for the Search service application. - - - ### To register the custom security trimmer - 1. In Windows Explorer, locate CustomSecurityTrimmerSample.dll in the path __:\\WINDOWS\\assembly. - - -2. Open the shortcut menu for the file, and then choose Properties. - - -3. On the **General** tab in the **Properties** dialog box, select the token and copy it. - - -4. Open the SharePoint Management Shell. For information about using this tool, see [Administering Service Applications Using the SharePoint 2010 Management Shell](https://msdn.microsoft.com/library/aff64855-7377-4e4a-b3a9-b620c9047076%28Office.15%29.aspx) - - -5. At the command prompt, type the following command. - -``` - New-SPEnterpriseSearchSecurityTrimmer -SearchApplication "Search Service Application" --typeName "CustomSecurityTrimmerSample.ClassName, CustomSecurityTrimmerSample, -Version=1.0.0.0, Culture=neutral, PublicKeyToken=token" -RulePath "xmldoc://*" -``` +1. Open the shortcut menu for the file, and then choose Properties. +1. On the **General** tab in the **Properties** dialog box, select the token and copy it. +1. Open the SharePoint Management Shell. For information about using this tool, see [Administering Service Applications Using the SharePoint 2010 Management Shell](https://msdn.microsoft.com/library/aff64855-7377-4e4a-b3a9-b620c9047076%28Office.15%29.aspx) +1. At the command prompt, type the following command. + ```powershell + New-SPEnterpriseSearchSecurityTrimmer -SearchApplication "Search Service Application" + -typeName "CustomSecurityTrimmerSample.ClassName, CustomSecurityTrimmerSample, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=token" -RulePath "xmldoc://*" + ``` In the command, replace _ClassName_ either with **CustomSecurityPreTrimmer** or **CustomSecurityPostTrimmer** and _token_ with the Public Key Token for the CustomSecurityTrimmerSample.dll file. You must associate all post-trimmers with a crawl rule, _"xmldoc://*"_; but this is optional for pre-trimmers. - + > [!NOTE] - > If you have multiple front-end web servers, you must deploy your security trimmer to the global assembly cache on all the front-end web servers in the farm. + > If you have multiple front-end web servers, you must deploy your security trimmer to the global assembly cache on all the front-end web servers in the farm. -6. Verify that your security trimmer is registered with the following PowerShell cmdlets. - -``` - -$searchApp = Get-SPEnterpriseSearchServiceApplication -$searchApp | Get-SPEnterpriseSearchSecurityTrimmer -``` +1. Verify that your security trimmer is registered with the following PowerShell cmdlets. + ```powershell + $searchApp = Get-SPEnterpriseSearchServiceApplication + $searchApp | Get-SPEnterpriseSearchSecurityTrimmer + ``` Your security trimmer must be visible in the results. - - ### To restart the SharePoint search host controller - - You can restart the Search Service by typing the following PowerShell cmdlet. - -``` - -net restart sphostcontrollerservice - -``` + ```console + net restart sphostcontrollerservice + ``` ## See also - - - -- [Custom security trimming for Search in SharePoint](custom-security-trimming-for-search-in-sharepoint-server.md) - - -- [Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) - - -- [Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) - - -- [Microsoft.Office.Server.Search.Query.PluggableAccessCheckException](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.PluggableAccessCheckException.aspx) - - +- [Custom security trimming for Search in SharePoint](custom-security-trimming-for-search-in-sharepoint-server.md) +- [Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPre.aspx) +- [Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.ISecurityTrimmerPost.aspx) +- [Microsoft.Office.Server.Search.Query.PluggableAccessCheckException](https://msdn.microsoft.com/library/Microsoft.Office.Server.Search.Query.PluggableAccessCheckException.aspx) diff --git a/docs/general-development/how-to-use-code-to-pin-terms-to-navigation-term-sets-in-sharepoint.md b/docs/general-development/how-to-use-code-to-pin-terms-to-navigation-term-sets-in-sharepoint.md index e3459953d..2490fc272 100644 --- a/docs/general-development/how-to-use-code-to-pin-terms-to-navigation-term-sets-in-sharepoint.md +++ b/docs/general-development/how-to-use-code-to-pin-terms-to-navigation-term-sets-in-sharepoint.md @@ -1,9 +1,9 @@ --- title: Use code to pin terms to navigation term sets in SharePoint +description: Learn how to use code to pin terms to navigation term sets. ms.date: 09/25/2017 -ms.prod: sharepoint ms.assetid: 4a2811dc-25fd-4eb2-b0ab-1edded64c556 -localization_priority: Normal +ms.localizationpriority: medium --- @@ -49,7 +49,7 @@ You can use custom code from the .NET server, .NET client (CSOM), Silverlight, o -```cs +```csharp public void TermPinningTest() { diff --git a/docs/general-development/how-to-use-multiple-sharepoint-lists-in-a-windows-phone-app.md b/docs/general-development/how-to-use-multiple-sharepoint-lists-in-a-windows-phone-app.md index 6498e8454..955351d14 100644 --- a/docs/general-development/how-to-use-multiple-sharepoint-lists-in-a-windows-phone-app.md +++ b/docs/general-development/how-to-use-multiple-sharepoint-lists-in-a-windows-phone-app.md @@ -1,47 +1,28 @@ --- title: Use multiple SharePoint lists in a Windows Phone app -ms.date: 09/25/2017 -ms.prod: sharepoint +description: Create Windows Phone apps that use data from multiple SharePoint lists. +ms.date: 06/09/2022 ms.assetid: 5251d35a-d659-49b3-8e0d-dfd4a7faee6b -localization_priority: Normal +ms.localizationpriority: medium --- - - # Use multiple SharePoint lists in a Windows Phone app -Create Windows Phone apps that use data from multiple SharePoint lists. -You can use multiple SharePoint lists in your app in several ways. When you create a Windows Phone app based on the Windows Phone SharePoint List Application template, you specify a single target SharePoint list, but the architecture of the resulting project is extensible enough to accommodate the integration of multiple lists. - - - +Create Windows Phone apps that use data from multiple SharePoint lists. -> **Important:** -> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). - - - +You can use multiple SharePoint lists in your app in several ways. When you create a Windows Phone app based on the Windows Phone SharePoint List Application template, you specify a single target SharePoint list, but the architecture of the resulting project is extensible enough to accommodate the integration of multiple lists. +> [!IMPORTANT] +> If you are developing an app for Windows Phone 8, you must use Visual Studio Express 2012 instead of Visual Studio 2010 Express. Except for the development environment, all information in this article applies to creating apps for both Windows Phone 8 and Windows Phone 7. > For more information, see [How to: Set up an environment for developing mobile apps for SharePoint](how-to-set-up-an-environment-for-developing-mobile-apps-for-sharepoint.md). ## Create a solution involving SharePoint lists based on the same schema - If you have two SharePoint lists based on the same schema, you can take advantage of the classes implemented by the Windows Phone SharePoint List Application template and create objects of those classes specific to each list. - - - -Suppose you have two SharePoint lists based on the Contacts list template. One list, named, for instance, Marketing Team, contains members of a marketing team at your organization, and the other list, Engineering Team, contains members of an engineering team. If you create a project using the Windows Phone SharePoint List Application template and specify the Marketing Team list as the target list on which to base the project, an instance of the **ListDataProvider** class is created (named **DataProvider** by default) in the implementation of the **App** class in the App.xaml.cs file in the project. This object represents the list (that is, the Marketing Team) list as a data source for the app, providing operations to access and manipulate items in the list. An instance of the **ListViewModel** class is also created for the list on which the app is based. This object has a property member (which also happens to be named **DataProvider**) that can be set to a given instance of the **ListDataProvider** class, establishing the data source for the **ListViewModel** class instance. - - - -You can create an additional instance of the **ListDataProvider** class in the project to serve as the data source for the second list (Engineering Team) in the App.xaml.cs file. The object is called **SecondaryDataProvider** in the following code. - - - - +Suppose you have two SharePoint lists based on the Contacts list template. One list, named, for instance, Marketing Team, contains members of a marketing team at your organization, and the other list, Engineering Team, contains members of an engineering team. If you create a project using the Windows Phone SharePoint List Application template and specify the Marketing Team list as the target list on which to base the project, an instance of the **ListDataProvider** class is created (named **DataProvider** by default) in the implementation of the **App** class in the **App.xaml.cs** file in the project. This object represents the list (that is, the Marketing Team) list as a data source for the app, providing operations to access and manipulate items in the list. An instance of the **ListViewModel** class is also created for the list on which the app is based. This object has a property member (which also happens to be named **DataProvider**) that can be set to a given instance of the **ListDataProvider** class, establishing the data source for the **ListViewModel** class instance. -```cs +You can create an additional instance of the **ListDataProvider** class in the project to serve as the data source for the second list (Engineering Team) in the **App.xaml.cs** file. The object is called **SecondaryDataProvider** in the following code. +```csharp private static ListDataProvider m_SecondaryDataProvider; public static ListDataProvider SecondaryDataProvider @@ -61,14 +42,8 @@ public static ListDataProvider SecondaryDataProvider ``` Then you can instantiate another object of the **ListViewModel** class (named, for instance, **SecondaryViewModel**) and assign the **SecondaryDataProvider** object to its **DataProvider** property, as in the following code. - - - - - - -```cs +```csharp private static ListViewModel m_SecondaryViewModel; public static ListViewModel SecondaryViewModel @@ -87,19 +62,11 @@ public static ListViewModel SecondaryViewModel } ``` -If the same fields and views for the two lists are suitable for your purposes (and, again, if the two lists have the same columns and fields), you don't need to make any changes in the implementation of the **ListDataProvider** class (in the ListDataProvider.cs file). - - - -To display or modify the data from the second list in your project, however, you need to add view forms to your project that are bound to and configured for this **SecondaryViewModel**. For example, you could add a folder to your project named "SecondaryViews" and add a SecondaryList.xaml file to that folder with markup similar to that of the default List.xaml file generated by the template for the primary list in the project. Note that you should distinguish your secondary List form from the primary List form in the app by specifying a distinguishing value for the **x:Class** attribute of the **PhoneApplicationPage** element in the SecondaryList.xaml file. - - - +If the same fields and views for the two lists are suitable for your purposes (and, again, if the two lists have the same columns and fields), you don't need to make any changes in the implementation of the **ListDataProvider** class (in the **ListDataProvider.cs** file). +To display or modify the data from the second list in your project, however, you need to add view forms to your project that are bound to and configured for this **SecondaryViewModel**. For example, you could add a folder to your project named "SecondaryViews" and add a **SecondaryList.xaml** file to that folder with markup similar to that of the default **List.xaml** file generated by the template for the primary list in the project. Note that you should distinguish your secondary List form from the primary List form in the app by specifying a distinguishing value for the `x:Class` attribute of the `PhoneApplicationPage` element in the **SecondaryList.xaml** file. - -``` - +```xml ``` -In the associated code-behind file, SecondaryList.xaml.cs, replace all references to "App.MainViewModel" with references to "App.SecondaryViewModel". For example, the constructor in the file should be as follows. - - - - - - -```cs +In the associated code-behind file, **SecondaryList.xaml.cs**, replace all references to `App.MainViewModel` with references to `App.SecondaryViewModel`. For example, the constructor in the file should be as follows. +```csharp public ListForm() - { - InitializeComponent(); - this.DataContext = App.SecondaryViewModel; - } +{ + InitializeComponent(); + this.DataContext = App.SecondaryViewModel; +} ``` -Also replace all references in the code-behind file to "App.DataProvider" with references to "App.SecondaryDataProvider" and update any navigation paths to point to the appropriate secondary XAML pages. If you also add a secondary New form to your project (named, for example, SecondaryNewForm.xaml in the SecondaryViews folder of your project), the handler in the SecondaryList.xaml.cs file for the **OnNewButtonClick** event would resemble the following code. - - - - - - -```cs +Also replace all references in the code-behind file to `App.DataProvider` with references to `App.SecondaryDataProvider` and update any navigation paths to point to the appropriate secondary XAML pages. If you also add a secondary New form to your project (named, for example, **SecondaryNewForm.xaml** in the SecondaryViews folder of your project), the handler in the **SecondaryList.xaml.cs** file for the **OnNewButtonClick** event would resemble the following code. +```csharp private void OnNewButtonClick(object sender, EventArgs e) - { - // Instantiate a new instance of NewItemViewModel and go to NewForm. - App.SecondaryViewModel.CreateItemViewModelInstance = new NewItemViewModel { DataProvider = App.SecondaryDataProvider }; - NavigationService.Navigate(new Uri("/SecondaryViews/SecondaryNewForm.xaml", UriKind.Relative)); - } +{ + // Instantiate a new instance of NewItemViewModel and go to NewForm. + App.SecondaryViewModel.CreateItemViewModelInstance = new NewItemViewModel { DataProvider = App.SecondaryDataProvider }; + NavigationService.Navigate(new Uri("/SecondaryViews/SecondaryNewForm.xaml", UriKind.Relative)); +} ``` -Finally, you can add a button to the **ApplicationBar** in the List.xaml file to display the SecondaryList.xaml page. - - - - +Finally, you can add a button to the **ApplicationBar** in the **List.xaml** file to display the **SecondaryList.xaml** page. - -``` - -... - - - - - - - - -... +```xml + + + + + + + + ``` In the associated code-behind file, List.xaml.cs, add a handler for the **OnSecondaryListButtonClick** event declared in the List.xaml file. - - - - - - -```cs +```csharp private void OnSecondaryListButtonClick(object sender, EventArgs e) { NavigationService.Navigate(new Uri("/SecondaryViews/SecondaryList.xaml", UriKind.Relative)); } ``` -Users of your app can then navigate between the Marketing Team list and the Engineering Team list. Because the underlying list schemas are the same, the default **DataProvider** and **MainViewModel** objects generated by the template and the added **SecondaryDataProvider** and **SecondaryViewModel** objects handle all the data transactions without requiring any modifications to the ListDataProvider.cs file. - - - +Users of your app can then navigate between the Marketing Team list and the Engineering Team list. Because the underlying list schemas are the same, the default **DataProvider** and **MainViewModel** objects generated by the template and the added **SecondaryDataProvider** and **SecondaryViewModel** objects handle all the data transactions without requiring any modifications to the **ListDataProvider.cs** file. ## Create a solution involving SharePoint lists based on different schemas - The approach in the preceding section works as far as it goes (that is, for SharePoint lists based on the same schema) but the **ListDataProvider** class in the Windows Phone SharePoint List Application template is available to developers for customization to handle multiple SharePoint lists that may not be based on the same schema or may not include the same columns and fields. - - - + Suppose, as in the preceding section, that you have a SharePoint list, Marketing Team (based on the Contacts list template), containing members of a marketing team. Suppose also that you have a second list, named Orders (based on the Custom list template), containing the columns and field types shown in Table 1. - - - - -**Table 1. Columns and fields for Orders list** - - -|**Column**|**Field Type**|**Required**| -|:-----|:-----|:-----| -|Product (i.e., Title)
    |Single line of text (Text)
    |Yes
    | -|Unit Price
    |Currency
    |Yes
    | -|Quantity
    |Number
    |No (defaults to zero)
    | -|Order Value
    |Calculated (Unit Price * Quantity)
    |No
    | -|Order Date
    |Date and Time (Datetime)
    |No
    | -|Order Status
    |Choice
    |No
    | -|Customer
    |Single line of text (Text)
    |No
    | - -As in the example in the preceding section, you can instantiate a separate **ListDataProvider** object and another **ListViewModel** object to manage the Orders list. Assume that the instantiated **ListDataProvider** object is named **OrdersListDataProvider**, as in the following code. - - - +### Table 1. Columns and fields for Orders list +| Column | Field Type | Required | +| :-------------------- | :--------------------------------- | :-------------------- | +| Product (i.e., Title) | Single line of text (Text) | Yes | +| Unit Price | Currency | Yes | +| Quantity | Number | No (defaults to zero) | +| Order Value | Calculated (Unit Price * Quantity) | No | +| Order Date | Date and Time (Datetime) | No | +| Order Status | Choice | No | +| Customer | Single line of text (Text) | No | -```cs +As in the example in the preceding section, you can instantiate a separate **ListDataProvider** object and another **ListViewModel** object to manage the Orders list. Assume that the instantiated **ListDataProvider** object is named **OrdersListDataProvider**, as in the following code. +```csharp private static ListDataProvider m_OrdersListDataProvider; public static ListDataProvider OrdersListDataProvider @@ -245,14 +170,8 @@ public static ListDataProvider OrdersListDataProvider ``` And assume that the instantiated **ListViewModel** object for the Orders list is named **OrdersListViewModel**, as in the following code. - - - - - - -```cs +```csharp private static ListViewModel m_OrdersListViewModel; public static ListViewModel OrdersListViewModel @@ -271,20 +190,14 @@ public static ListViewModel OrdersListViewModel } ``` -The schema for the Orders list differs from that of the Marketing Team list. You can accommodate the differences by adding code to the ListDataProvider.cs file, specifically to the **CamlQueryBuilder** class. - - - - - - -```cs +The schema for the Orders list differs from that of the Marketing Team list. You can accommodate the differences by adding code to the **ListDataProvider.cs** file, specifically to the **CamlQueryBuilder** class. +```csharp public static class CamlQueryBuilder { static Dictionary ViewXmls = new Dictionary() - { - {"View1", @" + { + {"View1", @" 30{0}"}, {"View2", @"30 {0}"} @@ -316,22 +229,13 @@ public static class CamlQueryBuilder ``` Here, a second entry with a key value of "View2" is added to the **ViewXmls** **Dictionary** object for the Orders list. (Keep in mind that the key values for entries added to the **ViewXmls** **Dictionary** in the **CamlQueryBuilder** class must be unique (in the solution) for the caching logic in the template to operate properly.) String variables ( **View1Fields** and **View2Fields**) are used to store the list of fields for each view. Then, depending on the value of the **viewName** parameter passed to the **GetCamlQuery** method, the appropriate CAML query XML string is created. - - - -Then, as in the preceding section, you can create view forms for the list, bound this time to the **OrdersListViewModel** and **OrdersListDataProvider** objects. As an example, the XAML for a List form specific to the Orders list, named OrdersList.xaml, would be similar to the markup in the List.xaml file generated by the template for the primary list in the app, except that you would name the **PivotItem** control that renders the list "View2" (rather than the default, "View1") and set the **Binding** declaration for the **ItemsSource** attribute of the **ListBox** control in which list items are rendered to "View2" as in the following markup (which shows only the markup for the root grid of the page). - - - +Then, as in the preceding section, you can create view forms for the list, bound this time to the **OrdersListViewModel** and **OrdersListDataProvider** objects. As an example, the XAML for a List form specific to the Orders list, named OrdersList.xaml, would be similar to the markup in the List.xaml file generated by the template for the primary list in the app, except that you would name the **PivotItem** control that renders the list "View2" (rather than the default, "View1") and set the **Binding** declaration for the **ItemsSource** attribute of the **ListBox** control in which list items are rendered to "View2" as in the following markup (which shows only the markup for the root grid of the page). - -``` - -... +```xml - @@ -342,9 +246,9 @@ Then, as in the preceding section, you can create view forms for the list, bound - - @@ -356,458 +260,379 @@ Then, as in the preceding section, you can create view forms for the list, bound -... ``` A convenient way to create suitable XAML markup is to use the Windows Phone SharePoint List Application template to generate a separate project based on the Orders list and then copy the generated XAML from that project to the project with multiple lists, taking care to change the name of the **PivotItem** control (which defaults to "View1") to "View2" and to change the **Binding** declaration of the **ListBox** control as shown here. You would also need to change all references in the associated code-behind file for the form to specify the appropriate **ListViewModel** and **DataProvider** objects (as, for example, **OrdersListViewModel** and **OrdersListDataProvider**). - - - + This approach works because in the associated code-behind file (named, in this case, OrdersList.xaml.cs), the various event handlers that call methods of the **ListDataProvider** object (here, **OrdersListDataProvider**) to access list data use the name of the **PivotItem** control as a way to specify the appropriate view to use. For example, the **OnPivotItemLoaded** event handler calls the **LoadData** method of the **OrdersListViewModel** object instantiated from the **ListViewModel** class (and this method in turn calls the **LoadData** method of the **OrdersListDataProvider** object), passing the name of the **PivotItem** control (here, "View2") as the value of the **ViewName** parameter to the method. This same value is ultimately passed (as the value of the **viewName** parameter) to the **GetCamlQuery** method shown above in the modified implementation of the **CamlQueryBuilder** class. - - - ## An alternative approach for a solution involving SharePoint lists based on different schemas - As an alternative to the approach in the preceding section, you can use the Windows Phone SharePoint List Application template to create a Windows Phone app project in a Microsoft Visual Studio 2010 solution based on a given SharePoint list and then add projects built based on other lists to that same solution. This approach allows you to take advantage of the template for generating forms specific to each SharePoint list. You can then customize the solution according to your needs to control how users interact with the lists. The procedures in this section demonstrate that approach. - - - + Assume for the following procedures that you have a SharePoint list named Orders (based on the Custom list template), with the columns and field types as shown in Table 1 in the preceding section. In addition, assume you have another SharePoint list (again, based on the Custom list template), named Customers, with the columns and field types shown in Table 2. - - - -**Table 2. Columns and fields for Customers list** +### Table 2. Columns and fields for Customers list +| Column | Field Type | Required | +| :-------------------------- | :------------------------- | :------- | +| Customer Name (i.e., Title) | Single line of text (Text) | Yes | +| Contact Number | Single line of text (Text) | No | +| E-mail Address | Single line of text (Text) | No | +| Company | Single line of text (Text) | No | -|**Column**|**Field Type**|**Required**| -|:-----|:-----|:-----| -|Customer Name (i.e., Title)
    |Single line of text (Text)
    |Yes
    | -|Contact Number
    |Single line of text (Text)
    |No
    | -|E-mail Address
    |Single line of text (Text)
    |No
    | -|Company
    |Single line of text (Text)
    |No
    | - In the following procedures, you create a Windows Phone app that uses both of these lists. The primary list in the app is the Customers list. When you display the details for a given customer in the Display form, a button is included on the form that allows users to display all the orders (from the Orders list) associated with that customer. - - - ### To create the component projects for the solution +1. Create a Windows Phone app by using the Windows Phone SharePoint List Application template, specifying a SharePoint list defined based on the columns and field types shown in Table 2. In the procedures in this section, it is assumed that the name of the list in the project is "Customers" and the name of the project is "CustomersSPListApp". (See [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) for information about creating an app based on the Windows Phone SharePoint List Application template.) +1. In Visual Studio, choose **File**, **Add**, **New Project**. -1. Create a Windows Phone app by using the Windows Phone SharePoint List Application template, specifying a SharePoint list defined based on the columns and field types shown in Table 2. In the procedures in this section, it is assumed that the name of the list in the project is "Customers" and the name of the project is "CustomersSPListApp". (See [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) for information about creating an app based on the Windows Phone SharePoint List Application template..md) - - -2. In Visual Studio, choose **File**, **Add**, **New Project**. - The **Add New Project** dialog box appears. - - -3. In the **Add New Project** dialog box, under the **Visual C#** node, choose the **Silverlight for Windows Phone** node. - - -4. In the **Templates** pane, choose the Windows Phone SharePoint List Application template. - - -5. Name the app, for example, OrdersSPListApp, and then choose **OK**. - - -6. Follow the procedure described in [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) to create another Windows Phone app project, specifying a SharePoint list defined based on the columns and field types show in Table 1 as the target list for the project. You should now have two projects in your solution, named "CustomersSPListApp" and "OrdersSPListApp" (if you are following the naming conventions in this procedure). - - -7. In **Solution Explorer**, choose the CustomerSPListApp project node. - - -8. On the **Project** menu, choose **Add Reference**. - + +1. In the **Add New Project** dialog box, under the **Visual C#** node, choose the **Silverlight for Windows Phone** node. +1. In the **Templates** pane, choose the Windows Phone SharePoint List Application template. +1. Name the app, for example, OrdersSPListApp, and then choose **OK**. +1. Follow the procedure described in [How to: Create a Windows Phone SharePoint list app](how-to-create-a-windows-phone-sharepoint-list-app.md) to create another Windows Phone app project, specifying a SharePoint list defined based on the columns and field types show in Table 1 as the target list for the project. You should now have two projects in your solution, named "CustomersSPListApp" and "OrdersSPListApp" (if you are following the naming conventions in this procedure). +1. In **Solution Explorer**, choose the CustomerSPListApp project node. +1. On the **Project** menu, choose **Add Reference**. + The **Add Reference** dialog box appears. - - -9. On the **Projects** tab, choose the OrdersSPListApp project in the solution, and then choose the **OK** button. The project is added under the **References** node of the CustomersSPListApp project. - - + +1. On the **Projects** tab, choose the OrdersSPListApp project in the solution, and then choose the **OK** button. The project is added under the **References** node of the CustomersSPListApp project. + Next, configure the two projects in the solution. You essentially configure the OrdersSPListApp project (based on the Orders list) to operate as a "look-up" project for the CustomerSPListApp project (based on the Customers List). - - - ### To configure the OrdersSPListApp project +1. Change the navigation paths in the view forms of the OrdersSPListApp project to include the primary namespace of the project ("OrdersSPListApp") and the "component" designation. For example, in the handler for the OnNewButtonClick event in the **List.xaml.cs** file of the OrdersSPListApp project, change the call to the Navigate method of the NavigationService object from this: + + ```csharp + NavigationService.Navigate(new Uri("/Views/NewForm.xaml", UriKind.Relative)); + ``` -1. Change the navigation paths in the view forms of the OrdersSPListApp project to include the primary namespace of the project ("OrdersSPListApp") and the "component" designation. For example, in the handler for the OnNewButtonClick event in the List.xaml.cs file of the OrdersSPListApp project, change the call to the Navigate method of the NavigationService object from this: - - `NavigationService.Navigate(new Uri("/Views/NewForm.xaml", UriKind.Relative));` - To this: - - `NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml", UriKind.Relative));` - + + ```csharp + NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml", UriKind.Relative)); + ``` + The easiest way to make these changes is to use the **Quick Replace** command in the OrdersSPListApp project. - + 1. In **Solution Explorer**, choose the OrdersSPListApp project node. - - -2. Press Ctrl+H to display the **Quick Replace** dialog box. - - -3. In the **Find what** text box, specify the following text exactly as it is appears here: - +1. Press Ctrl+H to display the **Quick Replace** dialog box. +1. In the **Find what** text box, specify the following text exactly as it is appears here: + + ```csharp Uri("/Views/ - - -4. In the **Replace with** text box, specify the following text exactly as it appears here: - + ``` + +1. In the **Replace with** text box, specify the following text exactly as it appears here: + + ```csharp Uri("/OrdersSPListApp;component/Views/ - - -5. Ensure that **Current Project** is selected in the **Look in** drop-down list. - - -6. Choose **Replace All**. - - -7. Save all changed files in the project. - - -2. Add a member property to the App.xaml.cs file of the OrdersSPListApp project. In **Solution Explorer**, under the OrdersSPListApp project node, choose the App.xaml file. - - -3. Press F7 to open its associated code-behind file, App.xaml.cs, for editing. - - -4. Within the code block (demarcated by opening and closing braces) that implements the **App** partial class, add the following code. - -```cs - -public static string CustomerName { get; set; } -``` + ``` -5. In **Solution Explorer**, under the OrdersSPListApp project node, choose the List.xaml file. - - -6. Press F7 to open its associated code-behind file, List.xaml.cs, for editing. - - -7. Modify the **OnNavigatedTo** event handler in the file to parse the **QueryString** property of the **NavigationContext** object to set the value of the **CustomerName** variable declared in step 4. You can also set the **Header** property of the **PivotItem** control on the List form to match the customer name, for the convenience of your users. The modified handler should be as follows. - -```cs - protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) -{ - base.OnNavigatedTo(e); +1. Ensure that **Current Project** is selected in the **Look in** drop-down list. +1. Choose **Replace All**. +1. Save all changed files in the project. +1. Add a member property to the **App.xaml.cs** file of the OrdersSPListApp project. In **Solution Explorer**, under the OrdersSPListApp project node, choose the **App.xaml** file. +1. Press F7 to open its associated code-behind file, **App.xaml.cs**, for editing. +1. Within the code block (demarcated by opening and closing braces) that implements the **App** partial class, add the following code. - if (this.NavigationContext.QueryString.ContainsKey("CustomerName")) - { - App.CustomerName = NavigationContext.QueryString["CustomerName"]; - } + ```csharp + public static string CustomerName { get; set; } + ``` - // Also set the value of the Header property for the PivotItem to match the customer name. - if (!string.IsNullOrWhiteSpace(App.CustomerName)) +1. In **Solution Explorer**, under the OrdersSPListApp project node, choose the **List.xaml** file. +1. Press F7 to open its associated code-behind file, **List.xaml.cs**, for editing. +1. Modify the **OnNavigatedTo** event handler in the file to parse the **QueryString** property of the **NavigationContext** object to set the value of the **CustomerName** variable declared in step 4. You can also set the **Header** property of the **PivotItem** control on the List form to match the customer name, for the convenience of your users. The modified handler should be as follows. + + ```csharp + protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { - this.View1.Header = App.CustomerName; - } + base.OnNavigatedTo(e); - App.MainViewModel.ViewDataLoaded += new EventHandler(OnViewDataLoaded); - App.MainViewModel.InitializationCompleted += new EventHandler(OnViewModelInitialization); -} -``` + if (this.NavigationContext.QueryString.ContainsKey("CustomerName")) + { + App.CustomerName = NavigationContext.QueryString["CustomerName"]; + } -8. Add the **CustomerName** variable as an argument in the call to the **LoadData** method in the **OnPivotItemLoaded** event handler in the List.xaml.cs file. The implementation of the **OnPivotItemLoaded** event handler should be as follows. - -```cs - -private void OnPivotItemLoaded(object sender, PivotItemEventArgs e) -{ - if (!App.MainViewModel.IsInitialized) - { - //Initialize ViewModel and Load Data for PivotItem upon initialization. - App.MainViewModel.Initialize(); - } - else - { - //Load Data for the currently loaded PivotItem. - App.MainViewModel.LoadData(e.Item.Name, App.CustomerName); + // Also set the value of the Header property for the PivotItem to match the customer name. + if (!string.IsNullOrWhiteSpace(App.CustomerName)) + { + this.View1.Header = App.CustomerName; + } + + App.MainViewModel.ViewDataLoaded += new EventHandler(OnViewDataLoaded); + App.MainViewModel.InitializationCompleted += new EventHandler(OnViewModelInitialization); } -} -``` + ``` +1. Add the **CustomerName** variable as an argument in the call to the **LoadData** method in the **OnPivotItemLoaded** event handler in the **List.xaml.cs** file. The implementation of the **OnPivotItemLoaded** event handler should be as follows. - The **LoadData** method of the **ListViewModel** class in the template is defined such as to be able to accept optional parameters. - - -9. Also add the **CustomerName** variable as an argument in the call to the **LoadData** method in the **OnViewModelInitialization** event handler. The implementation of the **OnViewModelInitialization** event handler should be as follows. - -```cs - -private void OnViewModelInitialization(object sender, InitializationCompletedEventArgs e) -{ - this.Dispatcher.BeginInvoke(() => + ```csharp + private void OnPivotItemLoaded(object sender, PivotItemEventArgs e) { - //If initialization has failed, show error message and return. - if (e.Error != null) + if (!App.MainViewModel.IsInitialized) { - MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK); - return; + //Initialize ViewModel and Load Data for PivotItem upon initialization. + App.MainViewModel.Initialize(); } - App.MainViewModel.LoadData(((PivotItem)Views.SelectedItem).Name, App.CustomerName); - this.DataContext = (sender as ListViewModel); - }); -} -``` + else + { + //Load Data for the currently loaded PivotItem. + App.MainViewModel.LoadData(e.Item.Name, App.CustomerName); + } + } + ``` -10. Add the **CustomerName** variable as an argument in the call to the **RefreshData** method in the **OnRefreshButtonClick** event handler in the List.xaml.cs file. The implementation of the **OnRefreshButtonClick** event handler should be as follows. - -```cs - -private void OnRefreshButtonClick(object sender, EventArgs e) -{ - if (Views.SelectedItem == null) - return; - if (!App.MainViewModel.IsInitialized) - { - //Initialize ViewModel and Load Data for PivotItem upon completion. - App.MainViewModel.Initialize(); - } - else - { //Refresh Data for the currently loaded PivotItem. - App.MainViewModel.RefreshData(((PivotItem)Views.SelectedItem).Name, App.CustomerName); - } -} -``` + The **LoadData** method of the **ListViewModel** class in the template is defined such as to be able to accept optional parameters. +1. Also add the **CustomerName** variable as an argument in the call to the **LoadData** method in the **OnViewModelInitialization** event handler. The implementation of the **OnViewModelInitialization** event handler should be as follows. - As for the **LoadData** method, the **RefreshData** method is also defined to be able to accept optional parameters. Notice that in the preceding three steps, the only change to the event handlers as generated by the template is the addition of the **CustomerName** variable as an argument in the call to the **LoadData** or **RefreshData** methods. - - -11. When users choose the **New** button on the List form for the Orders list in your app, the Customer field in the New form should already contain the name of the customer, because the list of orders displayed to the user has been filtered based on the customer name. New orders added from that filtered list should be associated with the customer name on which the list is filtered. To pass the value of the **CustomerName** variable to the New form, modify the **OnNewButtonClick** event to include the value as a query string in the navigation path to the New form, as shown in the following code. - -```cs - -private void OnNewButtonClick(object sender, EventArgs e) -{ - //Instantiate a new instance of NewItemViewModel and go to NewForm. - App.MainViewModel.CreateItemViewModelInstance = new NewItemViewModel { DataProvider = App.DataProvider }; - - if (!string.IsNullOrWhiteSpace(App.CustomerName)) - { - NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml?CustomerName=" + - App.CustomerName, UriKind.Relative)); - } - else + ```csharp + private void OnViewModelInitialization(object sender, InitializationCompletedEventArgs e) { - NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml", UriKind.Relative)); + this.Dispatcher.BeginInvoke(() => + { + //If initialization has failed, show error message and return. + if (e.Error != null) + { + MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK); + return; + } + App.MainViewModel.LoadData(((PivotItem)Views.SelectedItem).Name, App.CustomerName); + this.DataContext = (sender as ListViewModel); + }); } -} -``` + ``` -12. In the **OnNavigatedTo** event handler for the New form, check the query string for a customer name and, if it's available, assign it to the Customer field of the ViewModel for the form. In **Solution Explorer**, under the OrdersSPListApp project, choose the NewForm.xaml file and press F7 to open its associated code-behind file, NewForm.xaml.cs, for editing. - - -13. Modify the **OnNavigatedTo** event handler in the file to match the following code. - -```cs - -protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) -{ - base.OnNavigatedTo(e); +1. Add the **CustomerName** variable as an argument in the call to the **RefreshData** method in the **OnRefreshButtonClick** event handler in the **List.xaml.cs** file. The implementation of the **OnRefreshButtonClick** event handler should be as follows. - if (this.NavigationContext.QueryString.ContainsKey("CustomerName")) + ```csharp + private void OnRefreshButtonClick(object sender, EventArgs e) { - this.viewModel["Customer"] = NavigationContext.QueryString["CustomerName"]; - } + if (Views.SelectedItem == null) + return; - viewModel.ItemCreated += new EventHandler(OnItemCreated); -} -``` + if (!App.MainViewModel.IsInitialized) + { + //Initialize ViewModel and Load Data for PivotItem upon completion. + App.MainViewModel.Initialize(); + } + else + { //Refresh Data for the currently loaded PivotItem. + App.MainViewModel.RefreshData(((PivotItem)Views.SelectedItem).Name, App.CustomerName); + } + } + ``` -14. In the **CamlQueryBuilder** class in the ListDataProvider.cs file in the OrdersSPListApp project, add a **WHERE** clause to the Customer field in the CAML query used to get items from the Orders list to filter the list based on a given customer name (from the **CustomerName** variable). Add a parameter to the **GetCamlQuery** method in the class for passing the customer name. The modified **CamlQueryBuilder** class should be as follows. - -```cs - -public static class CamlQueryBuilder -{ - static Dictionary ViewXmls = new Dictionary() - { - {"View1", @"{0}30{1}"} - }; + As for the **LoadData** method, the **RefreshData** method is also defined to be able to accept optional parameters. Notice that in the preceding three steps, the only change to the event handlers as generated by the template is the addition of the **CustomerName** variable as an argument in the call to the **LoadData** or **RefreshData** methods. - static string ViewFields = @""; +1. When users choose the **New** button on the List form for the Orders list in your app, the Customer field in the New form should already contain the name of the customer, because the list of orders displayed to the user has been filtered based on the customer name. New orders added from that filtered list should be associated with the customer name on which the list is filtered. To pass the value of the **CustomerName** variable to the New form, modify the **OnNewButtonClick** event to include the value as a query string in the navigation path to the New form, as shown in the following code. - public static CamlQuery GetCamlQuery(string viewName, string customerName) + ```csharp + private void OnNewButtonClick(object sender, EventArgs e) { - string queryClause = string.Empty; + //Instantiate a new instance of NewItemViewModel and go to NewForm. + App.MainViewModel.CreateItemViewModelInstance = new NewItemViewModel { DataProvider = App.DataProvider }; - // Create appropriate Query Clause, depending on customerName parameter. - if (string.IsNullOrWhiteSpace(customerName)) + if (!string.IsNullOrWhiteSpace(App.CustomerName)) { - queryClause = ""; + NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml?CustomerName=" + + App.CustomerName, UriKind.Relative)); } else { - queryClause = string.Format("{0}", customerName); + NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml", UriKind.Relative)); } - - // Add Query Clause and ViewFields to ViewXml. - string viewXml = ViewXmls[viewName]; - viewXml = string.Format(viewXml, queryClause, ViewFields); - - return new CamlQuery { ViewXml = viewXml }; } -} -``` + ``` -15. Modify the **LoadDataFromServer** method in the ListDataProvider.cs file to check for the **CustomerName** argument and pass the argument to the **GetCamlQuery** method. The modified method should be as follows. - -```cs - -private void LoadDataFromServer(string ViewName, Action - loadItemCompletedCallback, params object[] filterParameters) -{ - string customerName = string.Empty; - string cacheKey = ViewName; +1. In the **OnNavigatedTo** event handler for the New form, check the query string for a customer name and, if it's available, assign it to the Customer field of the ViewModel for the form. In **Solution Explorer**, under the OrdersSPListApp project, choose the NewForm.xaml file and press F7 to open its associated code-behind file, **NewForm.xaml.cs**, for editing. +1. Modify the **OnNavigatedTo** event handler in the file to match the following code. - // Parse the optional parameters: - if (filterParameters.Length > 0) + ```csharp + protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { - customerName = filterParameters[0].ToString(); - cacheKey += "-" + customerName; + base.OnNavigatedTo(e); + + if (this.NavigationContext.QueryString.ContainsKey("CustomerName")) + { + this.viewModel["Customer"] = NavigationContext.QueryString["CustomerName"]; + } + + viewModel.ItemCreated += new EventHandler(OnItemCreated); } + ``` - CamlQuery query = CamlQueryBuilder.GetCamlQuery(ViewName, customerName); - ListItemCollection items = Context.Web.Lists.GetByTitle(ListTitle).GetItems(query); - Context.Load(items); - Context.Load(items, listItems => listItems.Include(item => item.FieldValuesAsText)); +1. In the **CamlQueryBuilder** class in the **ListDataProvider.cs** file in the OrdersSPListApp project, add a **WHERE** clause to the Customer field in the CAML query used to get items from the Orders list to filter the list based on a given customer name (from the **CustomerName** variable). Add a parameter to the **GetCamlQuery** method in the class for passing the customer name. The modified **CamlQueryBuilder** class should be as follows. - Context.ExecuteQueryAsync( - delegate(object sender, ClientRequestSucceededEventArgs args) + ```csharp + public static class CamlQueryBuilder + { + static Dictionary ViewXmls = new Dictionary() { - base.CacheView(cacheKey, items); - loadItemCompletedCallback(new LoadViewCompletedEventArgs { ViewName = ViewName, Items = base.GetCachedView(cacheKey) }); - }, - delegate(object sender, ClientRequestFailedEventArgs args) + {"View1", @"{0}30{1}"} + }; + + static string ViewFields = @""; + + public static CamlQuery GetCamlQuery(string viewName, string customerName) { - loadItemCompletedCallback(new LoadViewCompletedEventArgs { Error = args.Exception }); - }); -} -``` + string queryClause = string.Empty; + + // Create appropriate Query Clause, depending on customerName parameter. + if (string.IsNullOrWhiteSpace(customerName)) + { + queryClause = ""; + } + else + { + queryClause = string.Format("{0}", customerName); + } + + // Add Query Clause and ViewFields to ViewXml. + string viewXml = ViewXmls[viewName]; + viewXml = string.Format(viewXml, queryClause, ViewFields); + + return new CamlQuery { ViewXml = viewXml }; + } + } + ``` -16. Likewise, modify the **LoadData** method in the ListDataProvider.cs file to process the **CustomerName** parameter. - -```cs - -public override void LoadData(string ViewName, Action - loadViewCompletedCallback, params object[] filterParameters) -{ - string customerName = string.Empty; - string cacheKey = ViewName; +1. Modify the **LoadDataFromServer** method in the **ListDataProvider.cs** file to check for the **CustomerName** argument and pass the argument to the **GetCamlQuery** method. The modified method should be as follows. - // Parse the optional parameters: - if (filterParameters.Length > 0) + ```csharp + private void LoadDataFromServer(string ViewName, Action + loadItemCompletedCallback, params object[] filterParameters) { - customerName = filterParameters[0].ToString(); - cacheKey += "-" + customerName; + string customerName = string.Empty; + string cacheKey = ViewName; + + // Parse the optional parameters: + if (filterParameters.Length > 0) + { + customerName = filterParameters[0].ToString(); + cacheKey += "-" + customerName; + } + + CamlQuery query = CamlQueryBuilder.GetCamlQuery(ViewName, customerName); + ListItemCollection items = Context.Web.Lists.GetByTitle(ListTitle).GetItems(query); + Context.Load(items); + Context.Load(items, listItems => listItems.Include(item => item.FieldValuesAsText)); + + Context.ExecuteQueryAsync( + delegate(object sender, ClientRequestSucceededEventArgs args) + { + base.CacheView(cacheKey, items); + loadItemCompletedCallback(new LoadViewCompletedEventArgs { ViewName = ViewName, Items = base.GetCachedView(cacheKey) }); + }, + delegate(object sender, ClientRequestFailedEventArgs args) + { + loadItemCompletedCallback(new LoadViewCompletedEventArgs { Error = args.Exception }); + }); } + ``` + +1. Likewise, modify the **LoadData** method in the **ListDataProvider.cs** file to process the **CustomerName** parameter. - List CachedItems = GetCachedView(cacheKey); - if (CachedItems != null) + ```csharp + public override void LoadData(string ViewName, Action + loadViewCompletedCallback, params object[] filterParameters) { - loadViewCompletedCallback(new LoadViewCompletedEventArgs { ViewName = ViewName, Items = CachedItems }); - return; + string customerName = string.Empty; + string cacheKey = ViewName; + + // Parse the optional parameters: + if (filterParameters.Length > 0) + { + customerName = filterParameters[0].ToString(); + cacheKey += "-" + customerName; + } + + List CachedItems = GetCachedView(cacheKey); + if (CachedItems != null) + { + loadViewCompletedCallback(new LoadViewCompletedEventArgs { ViewName = ViewName, Items = CachedItems }); + return; + } + + LoadDataFromServer(ViewName, loadViewCompletedCallback, filterParameters); } + ``` - LoadDataFromServer(ViewName, loadViewCompletedCallback, filterParameters); -} -``` +1. Add a **Cancel** button to the **ApplicationBar** element in the List.xaml file in the OrdersSPListApp project. In **Solution Explorer**, under the OrdersSPListApp node, choose the List.xaml file, and then press SHIFT+F7 to open the file for editing in the designer. +1. Add XAML to declare a **Cancel** button within the `` tag, as shown in the following markup. -17. Add a **Cancel** button to the **ApplicationBar** element in the List.xaml file in the OrdersSPListApp project. In **Solution Explorer**, under the OrdersSPListApp node, choose the List.xaml file, and then press SHIFT+F7 to open the file for editing in the designer. - - -18. Add XAML to declare a **Cancel** button within the `` tag, as shown in the following markup. - -``` - - - - - - - - -``` + ```xml + + + + + + + + ``` -19. With the List.xaml file selected in **Solution Explorer**, press F7 to open the associated code-behind file, List.xaml.cs, for editing. - - -20. Within the code block (demarcated by opening and closing braces) that implements the **ListForm** partial class, add the following handler for the **OnCancelButtonClick** event. - -```cs - -private void OnCancelButtonClick(object sender, EventArgs e) -{ - NavigationService.Navigate(new Uri("/CustomersSPListApp;component/Views/DisplayForm.xaml", UriKind.Relative)); -} -``` +1. With the List.xaml file selected in **Solution Explorer**, press F7 to open the associated code-behind file, List.xaml.cs, for editing. +1. Within the code block (demarcated by opening and closing braces) that implements the **ListForm** partial class, add the following handler for the **OnCancelButtonClick** event. + + ```csharp + private void OnCancelButtonClick(object sender, EventArgs e) + { + NavigationService.Navigate(new Uri("/CustomersSPListApp;component/Views/DisplayForm.xaml", UriKind.Relative)); + } + ``` + +1. Save the files in the project. -21. Save the files in the project. - - Now, it remains to add a button to the Display form in the CustomersSPListApp project to show the orders associated with a given customer. - - - ### To configure the CustomersSPListApp project - 1. In **Solution Explorer**, under the node for the CustomersSPListApp project, choose the DisplayForm.xaml file. - - -2. Press Shift + F7 (or double-click the file) to open the file for editing in the designer. - - -3. Add XAML declarations for a **Button** control within a containing **StackPanel** control after the final **StackPanel** control container for the last field of the list item, as in the following markup. - -``` - -... +1. Press Shift + F7 (or double-click the file) to open the file for editing in the designer. +1. Add XAML declarations for a **Button** control within a containing **StackPanel** control after the final **StackPanel** control container for the last field of the list item, as in the following markup. + + ```xml - + - Title : + Title : - + - Contact Number : + Contact Number : + Text="{Binding [Contact_x0020_Number]}" TextWrapping="Wrap" + Style="{StaticResource PhoneTextSubtleStyle}" /> - E-mail Address : - + E-mail Address : + - Company : - + Company : +