2014-02-11 27 views
1

我有一个使用WCF端点调用SharePoint 2007 Lists.asmx服务的Web应用程序。为了确定为什么在调用GetListItems方法时收到500响应,我发现它在U2U Caml查询生成器中执行查询后开始成功。也就是说,执行U2U查询后,Web应用程序将停止获取500响应,并可以使用其WCF服务引用成功检索列表项,直到执行iisreset。使用ASMX Web参考调用后,只能使用WCF客户端调用SharePoint 2007 Web服务

作为对此发现的回应,我创建了一个控制台应用程序,通过WCF服务参考对GetListItems进行简单调用。我已经缩小到的是来自WCF服务引用的调用仅在从传统的.net 2.0 Web引用代理进行调用后才起作用。下面是我的控制台应用程序示例代码(这是我一直在VS Web服务器上运行):

string listName = "Reusable Content"; 
string viewName = String.Empty; 
string rowLimit = null; 

//Always Works 
XmlDocument doc = new XmlDocument(); 
ListsAsmx.Lists oldSvc = new ListsAsmx.Lists(); 
oldSvc.Credentials = new System.Net.NetworkCredential("user1", "passwrod", "mydomain"); 
XmlNode result = oldSvc.GetListItems(listName, viewName, doc.CreateElement("Query"), doc.CreateElement("ViewFields"), rowLimit, doc.CreateElement("QueryOptions"), null); 


//Only works after the above succeeds 
string query = "<Query></Query>"; 
string viewFields = "<ViewFields></ViewFields>"; 
string queryOptions = "<QueryOptions></QueryOptions>"; 

ListsService.ListsSoapClient svc = new ListsService.ListsSoapClient(); 

svc.ClientCredentials.Windows.ClientCredential.UserName = "user1"; 
svc.ClientCredentials.Windows.ClientCredential.Domain = "passwrod"; 
svc.ClientCredentials.Windows.ClientCredential.Password = "mydomain"; 

svc.GetListItems(listName, viewName, XElement.Parse(query), XElement.Parse(viewFields), rowLimit, XElement.Parse(queryOptions), null); 

所以,如果我注释掉sv2.GetListItems(...),做一个IISRESET,我得到的来自svc.GetListItems(...)的500响应。有趣的是,Web引用调用的起源并不重要。当我使用U2U Caml查询生成器发现它时,U2U始发于我的本地开发机器,并且WCF客户端调用始于Web服务器。即使我没有明确地设置svc的凭据(大概是因为它自动使用我的用户凭证),上面的代码也会成功。以下是ListsSoapClient的配置。你能帮我理解这里发生了什么,以及如何让svc自己成功?

 <binding name="ListsSoap2" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="500000" maxBufferPoolSize="524288" maxReceivedMessageSize="500000" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> 
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="5120000" maxNameTableCharCount="16384" /> 
      <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Ntlm" /> 
      </security> 
     </binding> 
    </basicHttpBinding> 
</bindings> 
<client> 
    <endpoint address="http://devpladmin.mydomain.com/_vti_bin/Lists.asmx" 
     binding="basicHttpBinding" bindingConfiguration="ListsSoap2" 
     contract="ListsService.ListsSoap" name="ListsSoap" /> 
</client> 

编辑

附加信息:
这是记录在事件查看器时,我收到了500:

Exception information: 
Exception type: FileLoadException 
Exception message: Could not load file or assembly 'Microsoft.SharePoint.intl, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. Either a required impersonation level was not provided, or the provided impersonation level is invalid. (Exception from HRESULT: 0x80070542) 

Request information: 
Request URL: https://devpladmin.mydomain.com:443/_vti_bin/Lists.asmx 
Request path: /_vti_bin/Lists.asmx 

Thread information: 
Thread ID: 10 
Thread account name: MYDOMAIN\user1 
Is impersonating: False 
Stack trace: at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) 
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) 
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) 
at System.Reflection.Assembly.Load(String assemblyString) 
at Microsoft.SharePoint.CoreResource..cctor() 
+0

据我所知,SharePoint从不支持WSE。如果您的WSE代理工作正常,那将归因于它不使用WSE的任何功能,并且仅使用基本的ASMX功能。 –

+0

而且,BTW,WSE不是“传统”,它已经过时。尤其是WSE 2.0,它比过时的WSE 3.0更为陈旧。我没有理由甚至在SharePoint的背景下思考WSE。 –

+0

好的,也许我不知道我在说什么。我刚刚在.NET中开始使用WSE,并且可能误解了它包含的内容。当我说上面的WSE时,我的意思是VS 2010称为.NET 2.0 Web Reference(而不是服务引用)。请帮助我纠正我的语言,然后我会更新我的问题。对困惑感到抱歉。 – xr280xr

回答

1

由于在事件查看器,并透露错误的博客文章由杰里奥曼,Mystery of the SharePoint "White Screens",我已经解决了这个问题。总之,我需要一个行为添加到我的WCF客户终端允许服务器来模拟特定用户:

<behaviors> 
     <endpointBehaviors> 
      <behavior name="SPServiceBehavior"> 
       <clientCredentials> 
        <windows allowedImpersonationLevel="Impersonation" allowNtlm="True"/> 
       </clientCredentials> 
      </behavior> 
     </endpointBehaviors> 
    </behaviors> 

所以我最好的猜测是这样的:Lists.asmx服务使用Microsoft.SharePoint.intl.dll 。加载Microsoft.SharePoint.intl.dll需要模仿授权用户(可能是因为它没有标记为安全控件?我不知道这一点)。重置IIS后,程序集未加载。如果我用我的WCF代理调用Lists.asmx服务,但没有明确指定allowedImpersonationLevelImpersonation,它默认为Identification,并在尝试加载Microsoft.SharePoint.intl.dll时在事件查看器中提供上述模拟错误。列表服务处理该异常并以500响应作出响应,以确保作为Web服务消费者,您不知道问题实际可能是什么**。但是,如果我第一次使用.NET 2.0 Web Reference代理调用该服务,显然会(这是我的假设)导致服务器模拟给定的用户并加载Microsoft.SharePoint.intl.dll程序集。现在,如果我使用我的WCF代理,程序集已经加载并且不需要模拟。这个解释可能不太对,但添加上面的行为让我的WCF服务引用发挥作用。

约翰桑德斯,我感谢你的努力。谢谢!

**来吧......我不能经历所有这些,而不是在SharePoint上抹布至少一次。

+0

只是想补充说,我的肥皂故障细节(具有完全相同的问题)是:从HRESULT异常:0x81070201。当我搜索到每一个结果都出现了不同的问题时,我都会包括b/c,所以希望谷歌能够将这篇文章与该结果联系起来。感谢一万美元的计算结果! – eol

+0

@Kiquenet嗯,我在这里回忆,但我很确定这是添加allowedImpersonationLevel =“模拟”,帮助我。我遇到了奇怪的作品/不工作类型错误调用SP的Web服务,我注意到,如果我手动打开我的Web浏览器中的列表,我可以然后调用Web服务确定。添加此设置意味着我不必首先执行手动打开步骤。 – eol