2012年9月17日,星期一

SharePoint应用程序:使用应用程序网站以及为什么要这样做

免责声明:仅因为我’我在写有关应用的文章,没有’并不意味着我认为SP2013中的所有内容都应作为应用程序开发!一世’我专注于应用程序仅仅是因为它’这是一个有很多东西要学的地方。

  1. SharePoint 2013应用–架构,功能和UX注意事项
  2. 入门–在SharePoint应用程序中创建列表,内容类型,字段等(配置)
  3. 在应用程序网络中使用数据以及为什么要这样做 [本文]
  4. 从SharePoint 2013应用访问最终用户数据(在宿主网站中)
  5. 将SharePoint 2013应用推广到企业-租户范围和PowerShell安装
  6. Azure是新的SharePoint‘_layouts’ directory
  7. “Host web apps” –将文件(例如母版页)设置到主机网站
  8. ““Host web apps” –设置字段和内容类型
  9. 将SP2013提供程序托管的应用程序/远程事件接收器部署到Azure网站(用于Office 365应用程序)
  10. 在SharePoint应用程序中使用Web部件

该应用网站是默认网站

您可能已经想到将托管SharePoint组件(例如列表,内容类型等)的SharePoint 2013应用程序放置到称为应用程序网络的隔离区域中的想法。如果没有,我的上一篇文章 在SharePoint应用程序中创建列表,内容类型和字段(配置) 提供一些详细信息,包括下图的一些解释,其中概述了我的应用程序’m building:

TimeTrackingApp

关于应用网络的主要考虑因素是 这是默认值 –如果您编写一些客户端对象模型(CSOM)代码(请记住,应用程序中禁止使用SharePoint服务器端代码),也许是为了查找列表并检索项目,在标准应用程序安排中,这是 应用程式网页 您正在与。这是因为默认情况下,’将会在应用程序网络的一个页面中– meaning your 语境 是应用程式网路,’反映在 ClientContext 反对你’将在您的代码中使用。发生的是,当您浏览一个应用程序时’s “front door”在“网站内容”区域中,您将被重定向到应用程序网络中的页面– and the ClientContext CSOM中的对象只是在做其始终要做的事情,即根据浏览器地址栏中的URL获取当前网站。

Consequently, there 是 nothing special needed to ‘get a reference’ to 应用网站 in your code. As a separate topic, the same cannot be said of the “host web” (the “real” SharePoint site where the app was installed) – in a best practice configuration which has the app domain on a completely separate URL domain to team sites/My Sites etc. (e.g. “http://myCorp-apps.com” vs. “http://myCorp.com” ), you’ll need to 采用 the SP.RequestExecutor Microsoft提供的用于访问主机网站的跨域库。有关此的更多信息"在主机网络中处理数据”本系列后面的文章。

获取应用程序网站和托管网站的网址(在应用程序内)

在应用程序中,开发人员需要知道应用程序网站和安装该应用程序的主机网站的URL。 传递了应用网站和宿主网站的相关URL 作为URL中的querystring参数 当用户从“网站内容”区域中的应用程序入口点到达应用程序的首页加载时,该操作将一直执行。实际上,只要用户访问应用程序的首页(例如,通过单击应用程序本身内的面包屑链接),您就可以’将在浏览器地址栏中看到它们。所以’只需阅读这些URL  parameters –在JavaScript中有很多方法可以做到这一点,我使用以下jQuery插件,但任何类似的方法都可以;只需确保’在您的应用页面引用的JavaScript文件中:

// jQuery plugin for fetching querystring parameters..
jQuery.extend({
    getUrlVars: function () {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    },
    getUrlVar: function (name) {
        return jQuery.getUrlVars()[name];
    }
});

然后,要获取应用程序的Web /主机Web URL,您可以执行以下操作:

// retrieve passed 应用程式网页/host web URLs..
hostweburl = decodeURIComponent($.getUrlVar("SPHostUrl"));
appweburl = decodeURIComponent($.getUrlVar("SPAppWebUrl"));

注意:SharePoint 2013 Preview中主机Web URL周围的错误

我在当前版本(预览)中注意到的一件事是,主机Web URL仅在主机Web首次加载页面(应用程序条目)时通过。当用户在您在应用程序网络中创建的任何页面上浏览时,如果他们单击面包屑链接以转到该应用程序 ’在默认页面中,URL参数存在但值不正确。现在有URL  of 应用网站,而不是托管网站。因此,如果你’重新尝试在主机网络中查找内容时,此代码将在此时失败。一世’m假设这必须是一个错误,并将很快将其提交给Connect(它没有’我检查时已经记录过)。

作为一种临时解决方法,我’m在第一次输入时将值保留在cookie中,然后根据需要从那里获取。这很好,我’d如果对任何人都有用,很乐意分享我的代码(请在下面给我留言),但是’不是特别复杂,我’确保您可以想象它的作用。

应用程序网络的常见任务

所以如果’只是标准的客户端对象模型代码,不需要任何特殊的操作‘get a reference’到应用程序网络,然后就可以使用标准的JavaScript CSOM代码示例。因此,我的上一篇文章提供了一些基本的JavaScript CSOM示例,当我可以’记住语法和其他内容:

其他好的来源是:

请记住,客户端对象模型的JavaScript版本(我’我在这里讨论)就是你’d在网页中使用,但是如果您使用某种服务器端代码(Windows桌面应用程序/ Windows Phone应用程序,WCF服务,PowerShell脚本,控制台应用程序等),则可以使用.NET托管客户端对象模型和例如C#中的代码。

使用应用网站与托管网站

因此,使用应用程序网络非常简单。在安全性方面,应用程序主体(应用程序的身份–这是一个完整的安全身份),具有应用程序网站的“完全控制”权限,因此您可以完成所需的任何操作,只要可以使用客户端代码即可完成。但是,正如我上次指出的,默认情况下,应用程序网络非常稀疏– there’由于没有真正的导航,因此无法使用许多SharePoint系统页面(例如,“网站内容”页面,/ _ layouts / viewlsts.aspx),并且显然在那里’应用程序与最终用户之间的分隔’的协作内容(列表和库)位于主机网络中。显然,您可以进行大量的自定义,甚至可以进入类似于团队协作的网站,但这将需要大量工作– it’实际不允许 采用 应用网站的模板,例如团队网站(STS#0)。这里’提醒您默认的用户体验是什么样的:

AppDefaultPage 

如果此应用程序隔离没有’如果无法真正满足要求,则可以由应用提供替代安排’s列表/页面/等。进入主机网络。要明确的是,这实际上不是’在许多情况下可能有两个主要原因:

  • 安全–该应用程序无法与主机网络打交道;默认情况下,它仅具有非常有限的读取权限。当然,这是隔离的重点,也是那些必须计划,维护和升级SharePoint部署的应用程序的主要好处。
  • 供应模型–如果将功能添加到Visual Studio项目中以创建(例如)列表–然后在应用程序网络中创建此列表。根本不可能在应用程序中对主机Web使用传统的配置方法

但是,在多种情况下 可能:

  • 该应用程序附带对主机Web的“完全控制”权限请求(必须由安装该应用程序的用户授予才能安装该应用程序)
  • 通过客户端对象模型(CSOM)实施供应

这些限制意味着不一定总是可以使用此方法。例如,Microsoft不太可能批准需要完全控制宿主网站才能在Office 365 / SharePoint Online中使用的应用程序。同样,SharePoint管理员决定将公开可用的应用添加到组织中是否安全’App Catalog最有可能采取相同的观点。但是,满足特定的客户要求可能很有意义–如果客户需要某种功能集并希望将其实现为应用程序,则可能是这样。

Doug Ware,他是SharePoint MVP的同伴,“developer’s 开发商”,在这方面做了大量的思想领导。 本文底部的链接是他的帖子,如果您认为此方法与您相关,我认为需要阅读这些链接。要构建这种类型的应用程序,很明显,需要CSOM调配方法(例如createField(),createContentType(),createList(),addListItem(),addFile()等库),而Doug是开始有关该主题的博客系列。

但是,我不’相信这种方法是应对应用程序模型挑战的灵丹妙药。这里’s why…

…在主机网络中实现应用可能不是一个好主意

所以我们’我已经涵盖了可能意味着它的限制’首先是不可能的(主机网络中需要完全控制权限)。我也认为:

  • 宿主Web方法部分地破坏了应用程序的目的(一种非常特定的功能,该功能与SharePoint环境隔离运行,因此’不会对平台稳定性,任何将来的升级和用户数据产生负面影响) 
    • 如果应用 是 just for one client, I feel like the benefits of apps are eroded so much you may as well build a farm solution. It will be 道路 无论您使用JavaScript和CSOM有多么出色,都可以更快。
  • 对于许多需求,将工件放入应用程序网络实际上应该可以正常工作。如果您需要存储一些列表/库数据并为前端提供一些页面,则该事实与最终用户有所不同’s core data doesn’t really matter.
    • 例如,在我做的有些人为的时间跟踪应用中’楼,只要用户界面能够快速,轻松地查看当前用户本周记录了多少小时,以及他/她的目标是什么-我不会’t think he/she would 关心 数据是否来自应用程序或主机网络中的列表。
  • I’我深信微软唐’希望您在托管网络中构建应用。一世’m主要基于以下观察结果:
    • 供应模型遍布应用程序网络
    • It’无法设置应用’s 首页 成为主机网络中的页面。值得注意的是,可以在起始页URL的开头使用的所有URL令牌都是针对应用程序网络(如果是外部托管的应用程序,则为远程应用程序网络)。请参阅MSDN页面 SharePoint应用程序中的URL字符串和令牌 并注意“此令牌不能在应用清单的StartPage元素中使用…”每个令牌旁边的声明,这些令牌引用一个宿主Web项目
    • 没有SDK示例使用此方法
    • 没有MSDN文档对此进行讨论(至少在撰写本文时)
    • 他们在应用程序Web上的许多设计目标都无法实现(安全性,针对定制环境的升级复杂性降低等)

实际上,我几乎看到了一个应用程序请求“完全控制”权限,然后在那里配置为LOOPHOLE的想法。

概要

那么这是否意味着我们永远不应该使用这种方法(而Doug是错误的)?我是否认为我们必须完全按照Microsoft的设想构建解决方案? 一定不行! 首先,微软表示每个自定义项都应在SharePoint 2013中作为应用程序构建,正如我在这些文章开头的免责声明中所述,我个人不’t agree with that. 

但是我认为你应该 认真思考 使用之前“exploitable loophole”主机网络中构建的过程。太多的开发人员无法看到其解决方案的全部总拥有成本-涉及可维护性(以及所需的技能/经验/能力),长期稳定性,性能,升级期间所需的返工等,因为’ve 从此移至下一个项目/客户。一世’曾经看到过非常出色的解决方案(由才华横溢的开发人员创建)从几个月以来受到绝对爱戴,逐渐成为组织的头疼事。当然,最初的开发者是’t看到这个–如果是的话,他可能可以管理自己的看法,将问题降到最低,并可能吸取了教训-但他不是’t. It’很难接受,但是我的一些解决方案也可能朝这个方向发展。现在我’我不暗示道格对此感到内gui– I’确保具有这种才能的人能够照顾他的SharePoint客户端’最好的利益很好– but there 是 a 实施者应考虑的有关SharePoint开发工作的长期影响。而且我认为,如果首先使用应用程序模型,则可以在主机网络(而不是应用程序网络)中实现应用程序 可能是问题的一部分,而不是解决方案的一部分。

这一切都不是’t to say it 决不 虽然有意义–就像我之前说的,在某些情况下,SharePoint确实无法解决 坐在最终用户拥有的其他列表/库/页面旁边将是示例。我认为道格在谈论时实际上在说很多 使用App模型构建传统的SharePoint协作解决方案 – it’只是我可能会更乐观地认为,与他相比,孤立的模型可以在更多的场景下工作。时间会证明一切。

进一步阅读:

17条评论:

哈雷尔 said...

克里斯,你好
感谢提供这篇好文章。

请一个简单的问题。

创建应用网站时,它是否与宿主网站完全相同?我的意思是,如果我知道主机网络包含一些"Projects"列表中包含一些数据,然后我可以通过ClientContext(应用程序网络本身)获取此列表的数据,还是我需要进行另一个客户端对象或跨域调用来托管网站以获取此列表/数据?

韦斯说过...

另一篇很棒的文章,我想道格的一件事'的方法可能适用于搜索。从目前的理解搜索可以'看不到应用程序网络内部。因此,在应用包含文档库和数据的情况下,这对于搜索是隐藏的。如果您的系列文章也讨论了在应用数据中进行搜索的方法以及类似的注意事项,那将是很好的。

克里斯·奥'Brien说过...

@Wes,

确实如此。至少就我的测试而言,搜索至少看不到应用程序网络内部。

如果应用'的数据需要显示在某人的搜索结果中(主要搜索结果或某些特定的搜索实现),那么这些数据可能确实需要存在于宿主网络中。

It'这是一个好方案。我认为可能还有其他选择。一世'随着系列的进行,我一定会考虑一下。

谢谢,

克里斯。

克里斯·奥'Brien说过...

@Hrayr,

不,应用程序Web *内容*不是宿主Web的镜像-没有内容出现。因此,如果您需要访问"Projects"从应用程序网络中的页面在主机网络中列出,然后您'd需要使用SP.RequestExecutor进行跨域调用。

HTH,

克里斯。

未知说过...

克里斯,
感谢您的客气话!只是一点点...你不'无需完全控制即可进行配置,只需进行管理即可。您可以'提交需要完全控制市场的应用程序,但是您可以提交需要管理的应用程序。

但是,我确实同意'似乎不想让您对托管市场的应用程序大失所望,即使当前的指导原则没有批准,如果他们批准它,我会感到惊讶'禁止这种方法。但是,这就是管理员侧安装的目的。

-道格

克里斯·奥'Brien说过...

@道格

谢谢那个'有用的说明!一世'如果可以的话,将更新主体文本。

期待继续讨论:)

克里斯。

未知说过...

克里斯,您好,感谢您提供信息,我想询问将HostUrl保留在cookie中的代码,还想询问TimeTracker应用程序的来源,因为它看起来比MS Samples真实得多。提前致谢。

尼克·帕特尔说过...

非常好的书面思想。。喜欢这篇文章。我同意,在主机网络中配置列表和库以构建协作解决方案会破坏应用程序的目的。应为SharePoint中基于场景的独立应用程序构建应用程序。而且,请相信我,有很多可以被Apps Model取代。

ServéHermans说过...

克里斯,您的大多数文章都经常给我打电话。非常有用,非常感谢您分享您的想法和观点。

我当然同意您在应用程序网站上的观点,不应完全控制宿主网站。它有点类似于我们之前在沙盒解决方案中拥有的全部代理信任。

似乎人们似乎在尝试找到比SharePoint展示的更多使用SharePoint的方法,这不是一件坏事,但通常会导致HTTP处理程序,声明性技巧,代理,控件适配器,客户端注入和自定义库。

好了,最后,在下次升级发生时,这些内容需要重写。就是这样:应用程序网络的本质几乎可以映射到'我们可以更新云服务而不必考虑SharePoint之上的自定义解决方案吗?'.

无论如何,再次感谢您的系列。像往常一样,您以每个人都能理解的方式写信,对此我表示赞赏。

问候,服务赫曼斯
hermansberghem.blogspot.com

克里斯·奥'Brien说过...

谢谢大家的评论。

@斯科特-肯定的事情。一世'将在接下来的两个晚上发布源代码。

克里斯。

堪萨斯州 said...

克里斯,很棒的博客。我已经测试过RTM安装。我看到了与您在博客中提到的错误相同的错误。看来您的解决方法仍会存在一段时间。谢谢!

克里斯·奥'Brien说过...

@KS,

是的,不幸的是,这在RTM中也是一样。一世'我打算就此发表一篇特定的文章,包括我想出的代码。我最近与Microsoft团队开会,他们为SharePoint构建了Visual Studio工具,我们讨论了这一点-在将来的某个时候,Visual Studio可能会自动注入一些代码来解决此问题,但是现在单个开发人员将需要来实现自己的解决方法(将URL持久保存在Cookie或服务器上的某个位置)。

It'虽然我个人并不特别将其视为错误'我仍然不确定这个分类;)

谢谢,

克里斯。

马尼利亚斯说过...

那么对于需要在宿主网站中配置列表的情况,沙盒解决方案仍然是一种好方法吗?例如。我需要部署一些列表,但是我希望这些列表是可搜索的,并且我不想重新创建应用程序页面以返回左侧导航,即顶部导航。

那么最好使用Sandbox设置列表吗?要记住在此示例中无法使用服务器场解决方案吗?

克里斯·奥'Brien说过...

@Fil,

是的,对于这些情况,沙盒解决方案绝对仍然是合适的解决方案。我一件事'd say 是 that it'避免在沙盒解决方案中避免自定义SharePoint服务器端API代码是一个好主意-它'显然Microsoft试图将此类代码移出SharePoint框。

我希望配置列表等是沙盒解决方案可用于通常的情况。

HTH,

克里斯。

克里斯·奥'Brien说过...

@所有,

这里只是注释线程的一个更新-似乎在某些时候有所更改(2013年3月更新?),这意味着许多操作需要完全控制,而不是Manage Web(根据Doug)'的先前评论)。为此,我对文章进行了重新编辑。

谢谢,

克里斯。

保罗·库姆湖说过...

这里的工作非常令人印象深刻。谢谢克里斯,这对我有很大帮助。

Poolio说过...

克里斯,您好,感谢您的精彩系列。我不'不知道什么时候改变了(现在知道这个线程已经使用了两年了),但是似乎存储在应用程序网络中的内容现在确实已被抓取,并出现在宿主网络,搜索中心等的搜索结果中。这很棒因为对我而言,搜索问题是在主机网络中创建内容的主要驱动力之一。

干杯,
安东尼