1. App Web & Host Web

The special website to which the app is deployed is called an App Web.

The website to which the app is installed is called the Host Web.

例子:

Suppose, you are developing a SharePoint 2013 app for your organization. In that, you would require the App to access and to use the SharePoint components such as the lists, content types, workflows, and pages. In this Case, all your SharePoint components should be deployed in a separate SharePoint site, called as the App Web.
 
The Host Web is nothing but the SharePoint site where the App is actually installed. So, to conclude, all the resources accessed by a SharePoint web has to be deployed in a different site, named as the App web. And, the actual site where the app is deployed (from VS) is called the Host Web.
 
2. Client Authentication with Office 365
使用SharePointOnlineCredentials对象
ClientContext context = new ClientContext(url);
System.Security.SecureString passWord = new System.Security.SecureString();
foreach (char c in password.ToCharArray())
{
passWord.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials(userName, passWord);

3. App中的Client Web Part是否加入到Feature或者package中不影响App中的内容,App文件会将项目中的所有信息加入进去;

4. App的链接中已默认包含了这个参数:SPHostUrl, SPLanguage, SPClientTag, SPProductNumber, 和SPAppWebUrl。

5. 动态创建Tile的方法:

在页面上定义一个container:

<!-- Tiles will be rendered here -->
<div id="tileArea" style="width:600px;"></div>

定义CSS:

/* Custom styles for the tiles */
.tile{
width:150px;
height:150px;
color:#FFFFFF;
margin-top:5px;
margin-left:0px;
margin-right:10px;
margin-bottom:10px;
cursor:pointer;
padding:5px;
float:left;
text-align:right;
font-family:Segoe UI, sans-serif;
font-size:14px;
background-image:url(../images/MetroPlay.png);
background-repeat: no-repeat;
background-position:bottom right;
background-color:#FFAAAA;
}
.tileNumber{
text-align:center;
font-family:Segoe UI Light, sans-serif;
font-size:72px;
margin-top:10px;
margin-bottom:10px;
}
a, a:hover, a:visited {text-decoration:none; outline:none;color:#FFFFFF}
a:active, a:focus {outline:}

使用JavaScript,根据列表数目动态生成tile:

// Variables used to hold objects for use in callback functions
var context;
var lists;
//var list;
var listItems;
var tileArea;
// This code runs when the DOM is ready and creates a context object which is needed
// to use the SharePoint object model
$(document).ready(function () { context = SP.ClientContext.get_current();
var web = context.get_web();
lists = web.get_lists();
context.load(lists);
context.executeQueryAsync(Function.createDelegate(this, renderListTiles), Function.createDelegate(this, errorLoadingLists));
}); function errorLoadingLists(sender, args) {
tileArea = document.getElementById("tileArea"); // Remove all nodes from the chart <DIV> so we have a clean space to write to
while (tileArea.hasChildNodes()) {
tileArea.removeChild(tileArea.lastChild);
} // Write a message to let the user know the operation has failed
var errMessage = document.createElement("div");
errMessage.appendChild(document.createTextNode("Lists could not be retrieved."+args.get_message()));
} function renderListTiles(sender, args) {
var listEnumerator = lists.getEnumerator(); while (listEnumerator.moveNext()) {
var list = listEnumerator.get_current();
var listTitle = list.get_title();
if ((listTitle == "Employees") || (listTitle == "MarketSize") || (listTitle == "Sales")) {
var itemCount = list.get_itemCount();
var tile = document.createElement("a");
tile.setAttribute("class", "tile");
tile.setAttribute("href", "../Lists/" + listTitle);
tile.appendChild(document.createTextNode(listTitle)); $("#tileArea").appendChild(tile);
var tileBody = document.createElement("div");
tileBody.setAttribute("class", "tileNumber");
tileBody.appendChild(document.createTextNode(itemCount.toString()));
tile.appendChild(tileBody);
}
}
}

效果:

6. 向SharePoint Log中添加记录时,需要用到SP.Analytics命名空间(SP.js);

 var eventGuid = new SP.Guid("101c16a5-3abd-4020-921f-cc40090c6ff7");

    // When you have entered a valid GUID, you can then call the logAnalyticsAppEvent
// as follows:
SP.Analytics.AnalyticsUsageEntry.logAnalyticsAppEvent(context, eventGuid, "Test App Page");
context.executeQueryAsync( // This is the success callback:
function () {
status.innerText = "Success! The event for 'Test App Page' has been logged.";
}, // This is the failure callback:
function (sender, e) {
status.innerText = "Failed to log event for 'Test App Page': " + e.get_message();
});

7. sp.userprofiles.js中包含了获取user profle信息的方法和对象(但除了accountName属性,其它属性可能为null)

// This code runs when the DOM is ready and creates a context object
// which is needed to use the SharePoint object model. We also wire
// up the click event handler of the listProfiles button in default.aspx.
$(document).ready(function () {
context = SP.ClientContext.get_current();
$('#listProfiles').click(function () { listProfilesClick();});
}); // This function handles the click event of the listProfiles button in default.aspx
function listProfilesClick() { // Our way into the current user's profile is through the PeopleManager class
// so we'll instantiate a new object and pass in the current context,
peopleMgr = new SP.UserProfiles.PeopleManager(context); // We'll then load the object...
context.load(peopleMgr); // ... and we'll get the user profile properties and load them as well.
profileProperties = peopleMgr.getMyProperties();
context.load(profileProperties); // Next we ask SharePoint to run all of our previously batched commands...
context.executeQueryAsync( // ... and if we're successful, the following success callback will run
function () { if (peopleMgr.get_isMyPeopleListPublic()) {
publicDiv.appendChild(document.createTextNode("Your followers and those you follow are publicly visible"));
}
else {
publicDiv.appendChild(document.createTextNode("Your followers and those you follow are not publicly visible"));
}
$('#profileList').append(publicDiv); // Then we'll add a few simple properties from the profile.
// The first one is the account name
var accountName = profileProperties.get_accountName(); // The second one is the display name.
// Note that we'll check for null in case this property hasn't been set.
var displayName = profileProperties.get_displayName(); // The third thing to show the user is their profile picture.
// Note that we'll check for null in case this property hasn't been set.
// If it's not null, we'll render the actual picture.
var myPicture = profileProperties.get_pictureUrl(); // Finally, we'll add three links:
// One for editing the profile...
var myProfileLink = peopleMgr.get_editProfileLink(); // One for going to the user's personal site...
var myPersonalSite = profileProperties.get_personalUrl(); // And one that shows the user what their page looks like when
// viewed by other users.
var myPublicPersona = profileProperties.get_userUrl(); }, // If we haven't been successful, the following failure callback
// will run, so we'll clear the profile list div, and then use it
// to tell the user what went wrong
function (sender, e) {
$('#profileList').children().remove();
$('#profileList').append(docume.createTextNode(e.get_message()));
});
}

8. SP.RequestExecutor.js文件就是cross-domain library,SP.RequestExecutor对象用于执行与其它数据源交互的操作,比如host-web,app-web;但需要注意的是,如果在APP中使用SP.RequestExecutor对象与Host Web的数据进行交互,由于在App中,默认的context site是app web, 所以我们还需要使用SP.AppContextSite()来设置当前的context site为 host web,然后还要再AppManifest.xml中设置app在host web中的权限(在使用SP.AppContextSite时必须使用SP.AppContextSite(@target) 和?@target='<host web url>'的格式,不能直接将host web地址写在参数括号中);

var hostweburl;
var appWebUrl; // Load the required SharePoint libraries
$(document).ready(function () {
//Get the URI decoded URLs.
hostweburl =
decodeURIComponent(
getQueryStringParameter("SPHostUrl")
); appWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl")); // Load the js file and continue to the
// success event handler
$.getScript(hostweburl+"/_layouts/15/SP.RequestExecutor.js", execCrossDomainRequest);
}); // Function to prepare and issue the request to get
// SharePoint data
function execCrossDomainRequest() {
var executor; // Initialize the RequestExecutor with the app web URL.
executor = new SP.RequestExecutor("/"); // Issue the call against the host web.
// To get the title using REST we can hit the endpoint:
// app_web_url/_api/SP.AppContextSite(@target)/web/title?@target='siteUrl'
// The response formats the data in the JSON format.
// The functions successHandler and errorHandler attend the
// success and error events respectively.
executor.executeAsync(
{
url:
appWebUrl+"/_api/SP.AppContextSite(@target)/web/title?@target='" +
hostweburl + "'",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: successHandler,
error: errorHandler
}
);
} // Function to handle the success event.
// Prints the host web's title to the page.
function successHandler(data) {
var jsonObject = JSON.parse(data.body); document.getElementById("HostwebTitle").innerHTML =
"<b>" + jsonObject.d.Title + "</b>";
} // Function to handle the error event.
// Prints the error message to the page.
function errorHandler(data, errorCode, errorMessage) {
document.getElementById("HostwebTitle").innerText =
"Could not complete cross-domain call: " + errorMessage;
}

9.  在app中搜索host web内容时,需要在AppManifest.xml文件的Permissions中为app添加Search权限,搜索时使用的url路径就是app web的路径,但依然可以搜索到host web的内容;

function executeQuery() {
alert(_spPageContextInfo.webAbsoluteUrl);
$.ajax(
{
url: _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='" + $("#queryTerms").val() + "'",
method: "GET",
headers: {
"Accept": "application/json;odata=verbose"
},
success: onSuccess,
error: onError
}
);
} function onSuccess(data) {
var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
alert(JSON.stringify(data.d.query)); //display json as string
var html = "<table>"; for (var i = 0; i < results.length; i++) {
html += "<tr><td>";
html += results[i].Cells.results[3].Value;
html += "</td><td>"
html += results[i].Cells.results[6].Value;
html += "</td><tr>";
} html += "</table>"; $("#resultsDiv").append($(html));
} function onError(err) {
alert(JSON.stringify(err));
}

10. _spPageContextInfo.webAbsoluteUrl可以直接在app中获取到当前站点的web绝对路径;

11.

SharePoint 2013 - Add-ins的更多相关文章

  1. SharePoint 2013 create workflow by SharePoint Designer 2013

    这篇文章主要基于上一篇http://www.cnblogs.com/qindy/p/6242714.html的基础上,create a sample workflow by SharePoint De ...

  2. SharePoint 2013 configure and publish infopth

    This article will simply descript how to configure and publish a InfoPath step by step. Note: To con ...

  3. Integrating SharePoint 2013 with ADFS and Shibboleth

    Time again to attempt to implement that exciting technology, Federation Services (Web Single Sign On ...

  4. office 365 Sharepoint 2013

    平台环境: office 365 Sharepoint  2013 操作文件和文件夹 访问文档库的最佳方式是借助在 /_api/web 处可用的 GetFolderByServerRelativeUr ...

  5. SharePoint 2013 版本功能对比

    前言:在SharePoint使用中,经常纠结于版本问题,SharePoint 2013主要有免费的Foundation和收费的标准版.企业版三个版本,他们之间的功能上是不一样的,找了一些资料才发现下面 ...

  6. SharePoint 2013 Search REST API 使用示例

    前言:在SharePoint2013中,提供Search REST service搜索服务,你可以在自己的客户端搜索方法或者移动应用程序中使用,该服务支持REST web request.你可以使用K ...

  7. SharePoint 2013 文档库中PPT转换PDF

    通过使用 PowerPoint Automation Services,可以从 PowerPoint 二进制文件格式 (.ppt) 和 PowerPoint Open XML 文件格式 (.pptx) ...

  8. SharePoint 2013 Word 转换PDF服务介绍及示例

    前言:在SharePoint使用过程中,经常会发现将文档进行格式转换的需求,之前,看到SharePoint 2013有将PPT转换PDF文档的服务,后来,才发现SharePoint 2010开始,就有 ...

  9. SharePoint 2013 状态机工作流之UpdateItemActivity

    没什么可说的,一个Activity的使用介绍,其他类似的Activity也可以参考这个使用. 1.添加ApplyActivation和UpdateItemActivity,在onWorkflowAct ...

  10. SharePoint 2013 状态机工作流之日常报销示例

    简单介绍下状态机工作流,状态机工作流提供了一系列的状态.工作流从初始状态开始,到终止状态结束.两个状态之间定义行为进行过渡.通常情况下,状态机工作流对事件作出反应,事件的发生将会使状态发生改变. 1. ...

随机推荐

  1. 5、Numpy处理数据

    转载自:http://old.sebug.net/paper/books/scipydoc/numpy_intro.html#id9 2 NumPy-快速处理数据 标准安装的Python中用列表(li ...

  2. linux 下PATH环境变量

    环境变量简介 什么是环境变量呢?简要的说,就是指定一个目录,运行软件的时候,相关的程序将会按照该目录寻找相关文件. 在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现&quo ...

  3. flex布局浅谈

    flex布局浅谈和实例 阿基米德曾说给我一个支点我可以撬动地球,而拥有flex基本可以撬动所有的布局. 1.flex布局基本介绍及效果展示 工欲善其事必先利其器,来来来,一起看下基础知识先(呵~,老掉 ...

  4. P4174 [NOI2006]最大获利

    传送门 把用户群和中转站都看成点 用户群权值为正,中转站权值为负 为了获得用户群的权值,我们不得不一起获得中转站负的权值 发现就是裸的最大权闭合子图 那么从用户群连边向中转站,边值INF 从 S 连向 ...

  5. HOW TO MAKE IT FLOW ?

      FLEXnet Licensing is a member of the FLEXnet Publisher family of products. It is the most popular ...

  6. SQL注入(过滤空格和--+等注释符)

    1.地址:http://ctf5.shiyanbar.com/web/index_2.php(过滤了空格和--+等注释符) 思路:确定注入参数值类型,直接输入单引号,根据报错信息确定参数值类型为字符型 ...

  7. API 接口设计工具 --Swagger

      swagger-editor,无法启动GUI软件,在线版的FQ也打不开   null

  8. Docker:网络模式详解

    Docker作为目前最火的轻量级容器技术,牛逼的功能,如Docker的镜像管理,不足的地方网络方面. Docker自身的4种网络工作方式,和一些自定义网络模式 安装Docker时,它会自动创建三个网络 ...

  9. (转)DB2 db2diag.log 日志分析

    DB2 db2diag.log 日志分析 原文:http://blog.csdn.net/lyjiau/article/details/52129997 db2diag.log是用来记录DB2数据库运 ...

  10. [转]实例化SqlParameter时,如果是字符型,一定要指定size属性

    转自:http://bbs.csdn.net/topics/380155255 以前在实例化SqlParameter时,通常都是用下面的语句,没有设置size属性: new SqlParameter( ...