我试图在我的autocompleteextender解决方案之一中使用ajaxcontroltoolkit中的sharepoint(这需要库的较旧版本,因为最近的所有库都需要.NET Framework 4.0),但不幸的是I can't use a page method in a UserControl, only in an actual page。因此,我只剩下一个选择,那就是使用实际Web服务中的方法。问题是我似乎无法弄清楚如何正确部署服务和配置web.config。当我尝试在浏览器中查看元数据信息时,收到一条错误消息,提示“找不到端点”。但是,当我尝试输入在URL后面附加方法名称的URL时,它实际上找到并执行了返回JSON数据的方法-这显然意味着它可以找到我的服务。另外,我可以使用jQuery调用我的服务并返回JSON数据-但我不想在该项目中使用jQuery,而是只保留所有纯C#代码。
我想知道的是,为什么我不能在浏览器中显示“漂亮的元数据信息”,所以却变得“温暖模糊”,并允许其他应用程序以应有的方式正确发现服务?
我对web.config进行了三重检查,并且既有metadataExchange端点,也有引用我的服务的端点,并且我将httpGetEnabled设置为“ true”。我尝试运行svcutil / t:metadata并将其指向我的服务,但是遇到了几个错误,第一个告诉我它无法获取元数据,第二个告诉我Metadata包含无法解析的引用,第三个是HTTP GET错误,指出HTML文档不包含Web服务发现信息。即使我的svc文件与OOTB SharePoint服务位于相同的ISAPI目录中,并且可以为这些服务生成XSD文件,但不能为我的生成。
这是我当前的web.config文件的样子...
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" />
<identity impersonate="true"/>
</system.web>
<system.serviceModel>
<!-- we need this to enable session -->
<client>
</client>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<behaviors>
<endpointBehaviors>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataSupportBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://myserver/sites/mysitecollection/_vti_bin/WebServices/MyService.svc" policyVersion="Policy15"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="false"/>
<serviceCredentials>
<windowsAuthentication includeWindowsGroups="true" />
</serviceCredentials>
</behavior>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
</bindings>
<services>
<service behaviorConfiguration="metadataSupportBehavior" name="Sample.WebServices.MyService">
<clear />
<endpoint address="" binding="basicHttpBinding" contract="Sample.WebServices.IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://myserver/sites/mysitecollection/_vti_bin/WebServices/MyService.svc" />
</baseAddresses>
</host>
</service>
</services>
我在这里真是茫然。有什么想法吗?
提前致谢!!!
更新#1:好的,我几乎可以正常工作了。我的意思是我“技术上”做到了,但仅在浏览器中做了一些警告。
我做的第一件事是将以下代码添加到我的web.config文件中:
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
然后更新我的服务端点,以包括对新配置的引用,如下所示:
<endpoint address="" binding="webHttpBinding" contract="Sample.WebServices.IMyService" behaviorConfiguration="webBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
我还将绑定从basicHttpBinding更改为webHttpBinding。
现在要告诫...
我可以使其完全运行并在浏览器中返回XML响应,但是仅当我在调试模式下运行该服务时,这意味着它是在Visual Studio中而不是IIS中托管的,因此它实际上不计数。
当我不在调试模式下运行服务时,出现一条错误消息,提示“异常消息是'值不能为空。参数名称:source'”。
在调试器中单步执行代码后,我看到了真正的错误:
请求类型为'IBM.Data.DB2.DB2Permission,IBM.Data.DB2,Version = 9.0.0.2,Culture = neutral,PublicKeyToken = 7c307b91aa13d208'的许可失败。
用简单的英语来说,这意味着我试图在我的SharePoint网站中加载IBM.Data.DB2 DLL的32位版本,不幸的是,它仅允许64位程序集。
所以我的第一个反应是“啊哈!”这应该很简单吧?我的意思是我要么需要找到DLL的64位版本,要么仅配置我的SharePoint网站在IIS中用于允许加载32位程序集的应用程序池,并且所有操作都应该是桃红色的!我不聪明吗?但是没有说SharePoint!我不仅不会让您做任何一件事情*,而且还将使整个SharePoint服务器场完全无法使用,甚至无法尝试实施这种可笑的解决方案!!!
因此,现在当我尝试导航到SharePoint场中的任何资源时,我对此表示欢迎。
[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_ApplicationProperties() +134
Microsoft.Office.Server.Administration.UserProfileApplicationProxy.get_PartitionIDs() +44
Microsoft.Office.Server.Administration.UserProfileApplicationProxy.IsAvailable(SPServiceContext serviceContext) +329
Microsoft.Office.Server.WebControls.MyLinksRibbon.get_PortalAvailable() +44
Microsoft.Office.Server.WebControls.MyLinksRibbon.EnsureMySiteUrls() +60
Microsoft.Office.Server.WebControls.MyLinksRibbon.get_PortalMySiteUrlAvailable() +15
Microsoft.Office.Server.WebControls.MyLinksRibbon.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +65
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2427
即使撤消对IIS,应用程序池,DLL的所有更改,重新启动IIS,重新启动服务器等,也无济于事。我完全被搞砸了。
美好的时光。
*公平地说,SharePoint与64位IBM驱动程序不可用无关,但我只是假设即使有一种我可以技术地使用的驱动程序,SharePoint也会找到一种惩罚我试图获得的方法。完成的任何工作。
更新2:好,我修复了整个“ SharePoint网站不起作用”的问题。基本上,所有与SharePoint相关的网站所使用的应用程序池似乎已更改为启用32位应用程序,包括SecurityTokenServiceApplication(对this站点的家伙们表示敬意,因为它不仅具有相同的问题,而且还发布了解决方案)。现在,虽然我不记得要为每个与SharePoint相关的应用程序池专门将值设置为true,但我还是愿意尝试说,也许是在绝望的情况下,我可能只是对它说了些鬼话,然后开始不顾一切地更改配置设置。您知道,因为这正是经验丰富的开发人员所做的。
无论如何...
现在,我的管理中心网站已备份并正在运行,但是UserProfileApplication服务仍然不稳定,而且我仍然倾向于认为我的SecurityTokenServiceApplication服务仍然处于混乱状态,因为出现错误(由于配置了web.config,因此详细信息当然被隐藏了)这样做)告诉我“服务器由于内部错误而无法处理请求”。
详细信息...
更新#3:好的,我已将所有内容恢复为原始工作形式。我确认,仅为SharePoint资源使用的一个应用程序池启用32位应用程序就可以有效地更新所有其他应用程序,以跟风。我之所以知道这一点,是因为我自己并没有为每个与SharePoint相关的应用程序池更改该值。我会记得经历过类似的事情。事实证明,所有这些具有SharePoint Web Services使用的“ GUID式”外观的时髦应用程序池也都进行了更新,以允许运行32位应用程序,这正是导致我的环境陷入困境的原因。
另外,通过遵循here提供的建议,我得到了SecurityTokenService来在浏览器中正确显示它的元数据。尽管它们看起来有点像“ hack”,但它们是小型且可逆的hack,所以我是游戏。
简而言之,您可以像这样编辑每个服务的配置文件:
在spStsActAsBinding绑定中,将httpTransport重命名为httpsTransport。
向绑定安全性添加allowInsecureTransport =” true”并启用enableUnsecuredResponse =” true”。
确保仅定义1个绑定配置(例如,在Profile Service中,您将为http和https协议的同一服务找到2个绑定配置)。
完成所有这些操作后,您应该能够为正在使用的自定义WCF服务获取“热模糊的元数据”。
因此,现在我只需要重新解决我的最初问题,那就是使32位版本的IBM.Data.DB2 DLL与SharePoint 2010一起使用。我还没有尝试过的一件事就是创建一个托管的IIS。独立于SharePoint完全运行的服务。这样做将允许我创建一个单独的应用程序池,该池实际上可以运行32位应用程序,而不会导致SharePoint崩溃。
更新#4:好吧,所以首先我要告诉您忽略上面关于如何使用SecurityTokenService的建议。确保您的更改使“热元数据变得模糊”,但可能会导致SharePoint网站崩溃。
所以无论如何...我现在已经创建了一个完全独立于SharePoint的网站,该网站使用它自己的应用程序池,该池配置为允许32位应用程序,因此从技术上讲应该解决我的所有问题。好吧,当我尝试在文本框中键入文本时,它不会“自动完成”,但是正在发生网络活动,因为我在Fiddler中看到了它。奇怪的是,它只发生一次。意思是,如果我按下退格键并重新输入其他内容,则不会对Web服务进行其他调用。我必须重新加载页面才能再次对其进行测试。当我确实调用该方法时收到的错误消息是“ 405 Method Not Allowed”。现在,我的方法接口签名使用WebInvoke,并将Method属性设置为“ GET”,这被告知应该可以正常工作,并且在过去进行返回JSON数据的REST调用时可以使用,但现在它不起作用。哦,在Web浏览器中它可以工作,并且我看到该方法返回了出色的XML结果。但是,当我尝试在SharePoint UserControl中使用AutoCompleteExtender来调用该方法(或为此使用任何其他客户端)时却没有。我尝试使用WebGet()属性,但是在Web浏览器中也没有任何返回。我认为我遇到了一个415错误。
更新#5:我发现另一篇文章中某个人似乎遇到了与我现在完全相同的问题,唯一的区别是即使我在同一项目中拥有Web服务,我也无法自动完成工作。我还尝试了他的帖子中提出的建议,但这些建议也不起作用。对于感兴趣的人,这是该帖子的link。
最佳答案
对于Webpart项目(使用ASCX),您可以:
1)在IIS中为SP SIte启用匿名身份验证
2)添加SP Mapped文件夹ISAPI
3)在ISAPI中创建YourService.asmx
<%@ WebService Language="C#" Class="YourNamespace.YourService, YourAsm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=YourPublicKeyToken"%>
4)编辑用户控制代码:
public partial class YourControl : UserControl
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
FixFormAction();
CheckScriptManager();
EnsureUpdatePanelFixups();
}
private void FixFormAction()
{
// Fix problem with postbacks and form actions (DevDiv 55525)
Page.ClientScript.RegisterStartupScript(GetType(), ID, "_spOriginalFormAction = document.forms[0].action;", true);
// By default, the onsubmit event for forms in SharePoint master pages call "return _spFormOnSubmitWrapper()"
// which blocks async postbacks after the first one. Not calling "_spFormOnSubmitWrapper()" breaks all postbacks
// and defeats the purpose of _spFormOnSubmitWrapper() which is to block repetitive postbacks.
// To call _spFormOnSubmitWrapper() and allow partial postbacks, remove "return" from the original call.
if (Page.Form != null)
{
string formOnSubmitAtt = Page.Form.Attributes["onsubmit"];
if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
}
}
private void EnsureUpdatePanelFixups()
{
if (this.Page.Form != null)
{
var fixupScript = @"
_spBodyOnLoadFunctionNames.push(""_initFormActionAjax"");
function _initFormActionAjax()
{
if (_spEscapedFormAction == document.forms[0].action)
{
document.forms[0]._initialAction = document.forms[0].action;
}
}
var RestoreToOriginalFormActionCore = RestoreToOriginalFormAction;
RestoreToOriginalFormAction = function()
{
if (_spOriginalFormAction != null)
{
RestoreToOriginalFormActionCore();
document.forms[0]._initialAction = document.forms[0].action;
}
}
";
ScriptManager.RegisterStartupScript(this, this.GetType(), "EnsureUpdatePanelFixup", fixupScript, true);
}
}
private ScriptManager CheckScriptManager()
{
ScriptManager sm = ScriptManager.GetCurrent(Page);
if (sm == null)
{
if (Page.Form != null)
{
sm = new ScriptManager();
sm.ID = Page.Form.ID + "_ScriptManager";
Page.Form.Controls.Add(sm);
//Page.Form.Controls.AddAt(0, sm);
}
}
sm.EnablePageMethods = true;
var sharedPath = @"~/_layouts/Share/";
var path = @"~/_layouts/YourWebPart/";
sm.Scripts.Add(new ScriptReference { Path = @"/_vti_bin/YourService.asmx/JS" });
//Registering ExtJS
Page.ClientScript.RegisterClientScriptInclude(GetType(), "ext-all", sharedPath + "scripts/ext-all.js");
ScriptManager.RegisterClientScriptBlock(this, GetType(), "ext-css",
"<link href='" +
sharedPath + "resources/css/ext-all.css' rel='stylesheet' type='text/css' />", false);
Page.ClientScript.RegisterClientScriptInclude(GetType(), "YourScript", path + "scripts/Script.js");
return sm;
}
}
5)编辑您的服务代码:
[WebService(Namespace = "http://tempuri/ws")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class YourService : WebService
{
//[WebMethod]
[ScriptMethod]
[WebMethod(EnableSession = true)]
//[ScriptMethod(UseHttpGet = true)]
public string YourWebMethod(string arg)
{
return arg;
}
}
6)在控制javascript中使用您的网络服务方法:
YourNamespace.YourService.YourWebMethod(arg, function (result) {
if (result) {
if (typeof result == 'string') {
alert(result);
}
}
}, function (error) { alert('YourWebMethod failed! ' + error.get_message()); });
}
没有webconfig
对于ISAPI子文件夹中的svc
<%@ ServiceHost Debug="true" Language="C#"
Service="Namespace.MyService, MyAsm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=MyPublicKeyToken"
%>
web.config可以是:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2097151"/>
</requestFiltering>
</security>
</system.webServer>
<system.web>
<httpRuntime executionTimeout="60" maxRequestLength="2097151" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyHttpBinding"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
<readerQuotas maxArrayLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CustomServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="CustomServiceBehaviour" name="Namespace.MyService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyHttpBinding" contract="Namespace.IMyService" bindingNamespace="http://tempuri/ws" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
关于wcf - 将WCF服务部署到SharePoint 2010网站时出现“找不到端点”错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15163342/