2015年7月15日,星期三

SharePoint加载项(应用程序)开发中的调试错误

If I was to summarize this 发布in one sentence, I’d say “if 您 r SharePoint app/add-in is giving a generic error such as ‘An error occurred while processing 您 r request’, then 您 ’可能是错误的外接程序注册/身份验证!”。这适用于提供程序托管的SharePoint加载项,而不适用于SharePoint托管的加载项,并且’不适用于使用Office 365 API替代SharePoint加载项模型的应用程序。但是对于开发/部署SharePoint加载项的任何人来说, SharePoint / Office 365开发人员的常见经验– 大家 在某个时候搞砸了这个问题:)有很多论坛帖子,可能还有一些有关此的现有文章,但是我似乎总是陷入这个陷阱(通常是有错字之类的东西),然后花1-2个小时调试和搜索互联网直到我记得具体的问题是什么。所以,我只是想从我的身上转移一下 Office 365开发中的挑战–以及解决这些问题的方法 关于这个的系列部分是为了让我下次遇到问题时有个快速参考,因为我知道我肯定会:)

问题症状

当你 click on 您 r add-in, 您 are taken to the remote website (e.g. on 本地主机, or in Azure, IIS, or wherever 您 published it to) but instead of seeing the default page 您 simply see a white page with a simple message:
clip_image001
发生这种情况是由于大多数SharePoint加载项中都存在此样板代码–请参阅“ CanNotRedirect”案例:

Uri redirectUrl;

switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl)) 
{ 
    case RedirectionStatus.Ok: 
    return;

    case RedirectionStatus.ShouldRedirect: 
        Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true); 
    break;

    case RedirectionStatus.CanNotRedirect: 
        Response.Write("An error occurred while processing 您 r request."); 
        Response.End(); 
    break; 
}


如果你 perform any debugging and step through the code, 您 ’最终可能会在TokenHelper类中查看此方法:

public static string GetContextTokenFromRequest(HttpRequestBase request) 
{ 
    string[] paramNames = { "AppContext", "AppContextToken", "AccessToken", "SPAppToken" }; 
    foreach (string paramName in paramNames) 
    { 
        if (!string.IsNullOrEmpty(request.Form[paramName])) 
        { 
            return request.Form[paramName]; 
        } 
        if (!string.IsNullOrEmpty(request.QueryString[paramName])) 
        { 
            return request.QueryString[paramName]; 
        } 
    }

    return null; 
}

在很多情况下,’会发现此方法返回null–实际上,在URL或帖子正文中找不到任何指定表单参数的值。我们’已成功传递了许多早期代码,并且有效的上下文令牌已从SharePoint / Office 365传递到加载项中,但是我们’在这一点上失败了。

深层发掘

当您单击加载项时(例如,在“ SharePoint网站内容”页面中),您将被带到AppRedirect.aspx–此页面最终会重定向到您应在应用程序注册中指定的重定向URL。这是POST形式,在请求的主体中是远程代码所需的令牌。或者至少应该如此。在没有事情的情况下’t working, 您 ’会注意到未传递令牌(例如,在Fiddler中):
加载项重定向-Fiddler 1
加载项重定向-Fiddler 2
We can see two things about the body of the form 发布from the image above:
  • 的SPAppToken parameter is 空的
  • 的SPRedirectMessage parameter gives us a clue about my specific problem, with a value of “EndpointAuthorityDoesNotMatch
要明确的是, EndpointAuthorityDoesNotMatch 消息只是此问题的一种味道– 您 might see something else here depending on precisely 怎么样 您 ’ve messed up 您 r app registration/authentication setup :) For example, 您 might have the add-in registration all correct, but 您 ’重新尝试在HTTP而不是HTTPS上运行应用程序– in that case, 您 ’ll see:
  • 空的SPAppToken
  • SPErrorInfo参数包含类似“请求的操作需要HTTPS(SSL)通道。确保目标端点地址支持SSL,然后重试。”
该邮件将被编码,因此看起来将更像这样(对于将其粘贴到互联网搜索中的任何人):
SPErrorInfo =请求的操作+需要+一个HTTPS +%28SSL%29 +通道。++确保+目标+端点+地址+再次支持SSL +和+ try +。
clip_image002
如果你’在重新开发高信任度的外接程序(用于本地SharePoint)时,问题的另一种味道是您没有’t列出了身份验证要求–特别是通过证书方面的令牌签名。看到 打包和发布SharePoint 2013的高信任度应用程序 for more info if this is 您 r scenario.
就我而言 EndpointAuthorityDoesNotMatch 告诉我,远程应用程序的URL与该客户端ID的应用程序注册中期望的不匹配。我可以使用/_layouts/15/AppInv.aspx页面查找在/_layouts/15/AppRegNew.aspx注册应用程序时指定的详细信息。重要提示:如果最后一句话没有’对你和/或你没有多大意义’重新开始于外接程序开发,那么您的错误可能是您刚刚没有’根本没有注册加载项!下一节可能会有所帮助:

背景-开发外接程序时要了解/记住的关键事项

加载项注册

加载项需要向SharePoint / Office 365注册,并要求一组必需的权限(安装加载项的人必须同意)–否则,您实际上只能在SharePoint之外拥有一些随机代码,这些代码试图读取/写入数据,因此安全机制开始发挥作用,您的代码被阻止。可以通过针对广泛分布的加载项(即使只是在您自己的环境中)的卖方仪表板来完成此操作,也可以通过将AppRegNew.aspx页用于其他类型来完成此操作。如果您需要一些背景知识,建议您阅读以下内容- 为SharePoint 2013注册应用程序的准则
“Development mode” vs. “打包用于部署模式”
在开发外接程序时,Visual Studio确实会尽力帮助您。当我按F5键启动并调试加载项时,已经做好了很多事情,因此我可以快速运行并查看我的代码-我认为这是“development mode”. Let’讨论这里发生的事情,以及以后打包部署到另一个环境时需要考虑的问题。
开发模式:
在按F5键时,加载项将打包并部署到指定的SharePoint网站-该网站可以是本地的,也可以在SharePoint Online中,并且删除那里的所有先前安装。此外,外接程序会自动在此SharePoint环境中注册。假定确实可以在指定的URL上浏览加载项的网站(即远程ASP.NET站点),则F5进程将打开一个浏览器窗口,在该窗口中正在安装/信任该应用程序,然后您可以单击图标,然后进入应用。其他注意事项:
  • 的URL for the remote ASP.NET website is specified in the properties 用于加载项Web项目 – by default, a “localhost” URL such as http:// _ localhost:44311 / is used against 您 r local IIS Express instance. It’可以在项目属性中对此进行更改,例如,更改为用于完整IIS实例的命名虚拟目录URL。
  • 如果使用IIS Express,则应考虑是否可以将localhost与计算机上的HTTPS一起使用。我脑子里有可能在某处指定它不应该用于远程网站SSL– but frankly I can’现在,请记住是否为真或如何找到它’现在有可能,所以这可能是胡说八道:)我总是在完整的本地IIS实例上运行,并且SSL在本地主机上运行,​​这对我有用。
  • 身份验证也需要考虑。通常你’ll need to ensure “Windows验证”可以在Web项目上启用,以便可以标识当前用户,并可以进行向SharePoint的身份验证。但是,如果您’重新开发将向Azure AD进行身份验证的Office 365加载项,这是’t the case.
  • In 发展模式, 您 r app manifest is expected to have a ClientID value of “*”。 Visual Studio将在打包/调试时将其替换为正确的值。
打包为部署模式:
当你’准备考虑将加载项部署到其他人可以看到的位置(例如,Azure,某些IIS服务器或其他地方)’(在本地开发箱中),则需要在部署之前更改文件中的几项内容。有关部署过程的端到端演练(使用Azure Web Apps作为托管平台),请参见 将SP2013提供程序托管的应用程序/远程事件接收器部署到Azure网站(用于Office 365应用程序) 发布–这是前一段时间写的,但我’自从考虑到Azure和Visual Studio中的更改以来,已经对其进行了更新。但是,这是从中进行的关键更改“development mode”:
  • 处理加载项注册–转到将在其中使用外接程序的SharePoint环境中的AppRegNew.aspx,并注册外接程序(提醒–要么查看我的最后一个链接,要么 为SharePoint 2013注册应用程序的准则 if 您 ’re not clear on this step!) For the app/add-in ID, either generate a new GUID on the page or use the existing ClientId value in 您 r project files –关键是它们匹配,’s all.
    • 记下AppRegNew.aspx页上使用/生成的ClientId和ClientSecret– 您 ’ll need these!
  • 确保web.config的AppSettings部分包含外接程序注册中的ClientId和ClientSecret(上一步)–如果需要,覆盖现有值。 Visual Studio工具(TokenHelper.cs)烘焙到每个外接程序中的身份验证代码将从此处读取值。
  • (可选)找到您的appmanifest.xml文件并替换“*”在ClientId值中,并带有注册中的附加ID–有效地将其中的值硬编码。此步骤在技术上是可选的,因为在Visual Studio中打包应用程序的过程(下一步)实际上将替换“*”使用您始终指定的GUID值,但是不要依赖它,而是在appmanifest.xml中显式指定GUID是有意义的-例如,如果您’重新分发VS项目文件,或者也许是aren’期望做更多的本地开发/测试。否则,我们’下一步将处理。
  • (可选)更换“~remoteAppUrl”appmanifest.xml中的值也– it’与上一点完全相同的交易/考虑。
  • 使用Visual Studio发布外接程序的两个元素(外接程序远程网站和外接程序包)“Publish..”机制。右键单击该外接程序项目,然后单击“Publish..”,您应该会看到一个对话框,可帮助您发布两个VS项目的输出:
    VS SP加载项发布对话框1
    您 ’我需要同时按下这两个按钮:)第一个按钮将帮助您发布Web项目–如果要轻松发布到Azure,请确保已安装Azure SDK。这将使您能够“discover”并在您的订阅中发布到Azure Web Apps(网站),而不必单独下载用于连接的发布配置文件。

    第二个按钮将打包应用程序– 您 ’系统会要求您提供一些关键详细信息,这些详细信息将放入包装中:

    VS加载项发布对话框2

    在打包过程中,将在生成的.app文件中将几件事烘焙到appmanifest.xml中(这就是为什么前面的某些步骤是可选的):
    • 的〜remoteAppUrl token will be replaced with the remote website URL 您 specify
    • 的“*”ClientId值中的将会替换为上面Client ID文本框中的值

      NOTE - 您 won’t see any changes in 您 r source appmanifest.xml file. It’s only if 您 crack open the add-in, by renaming from .app to .zip, and examining the files inside will 您 see where this has happened.
  • 获取外接程序包并将其部署到您的环境的SharePoint外接程序目录中(在Office 365或本地SharePoint中)。将.app文件拖到目录中,然后将所有其他详细信息(例如,加载项说明,屏幕截图等)添加到该文件的列表项中。
的add-in is now available to be installed to SharePoint sites.

回到我的问题

无论如何,AppInv.aspx允许我输入客户端ID /应用程序ID(标识加载项/一些远程代码)并查看注册的详细信息:
AppInv.aspx
当我点击“Lookup”按钮,其他文本框将使用注册详细信息填充,如上所示。就我而言,我现在可以看到自己犯的错误– it’s the “www.”在应用程序域/ URL中。当我考虑我的远程站点实际上正在运行的URL时,它’s actually just http:// _ cob- [foo] .azurewebsites.net 没有“www.” – as 您 can see if 您 look back 在 the first image in this article.

因此,我的解决方案是使用正确的URL重新注册加载项。
It’s not possible to modify an existing add-in registration, so 您 need to do a new registration with a new App ID (and update the Client ID value in 您 r app manifest etc.) 您 can tidy up the old app registration by going to AppPrincipals.aspx and deleting the original app principal there.

概要

开发SharePoint加载项存在一些常见的陷阱,即使具有一定的经验水平也是如此’容易陷入其中之一!要寻找的一些关键事项包括加载项注册中的错误,以确保您知道两者之间的区别“development mode” and “包装生产方式”,以及远程Web应用程序上对HTTPS的需求。如果一切正常,则您的加载项应该工作正常。
史蒂夫·佩斯卡(Steve Peschka)在以下方面对此领域提供了更多好的提示 //samlman.wordpress.com/2015/03/01/more-troubleshooting-tips-for-high-trust-apps-on-sharepoint-2013/

在下一篇文章中,我’我将继续在 Office 365开发中的挑战–以及如何解决.