简体   繁体   English

使用ASMX Web参考调用后只能使用WCF客户端调用SharePoint 2007 Web服务

[英]Can only call SharePoint 2007 web service using WCF client after calling with ASMX Web Reference

I have a web app that calls the SharePoint 2007 Lists.asmx service using a WCF endpoint. 我有一个Web应用程序,该应用程序使用WCF终结点调用SharePoint 2007 Lists.asmx服务。 In an all day attempt to determine why it was receiving a 500 response when calling the GetListItems method, I discovered that it starts succeeding after I execute a query in U2U Caml Query Builder. 一整天的尝试以确定为什么在调用GetListItems方法时为什么收到500响应,我发现在U2U Caml Query Builder中执行查询后,它开始成功。 That is, after executing a U2U query, the web app stops getting the 500 response and can successfully retrieve list items using its WCF service reference until I do an iisreset. 也就是说,执行U2U查询后,Web应用程序将停止获得500响应,并且可以使用其WCF服务引用成功检索列表项,直到执行iisreset。

In response to that discovery, I created a console app that does a simple call to GetListItems via a WCF Service Reference. 为了响应这一发现,我创建了一个控制台应用程序,该应用程序通过WCF服务参考对GetListItems进行了简单的调用。 What I've narrowed it down to is the call from the WCF service reference only works after making a call from a legacy .net 2.0 Web Reference proxy. 我将其范围缩小为WCF服务引用的调用仅在从旧版.net 2.0 Web参考代理进行调用之后才有效。 Here's the example code from my console app (which I have been running within VS on the web server): 这是我的控制台应用程序(我已经在Web服务器上的VS中运行)的示例代码:

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);

So if I comment out sv2.GetListItems(...) and do an iisreset, I get the 500 response from svc.GetListItems(...). 因此,如果我注释掉sv2.GetListItems(...)并进行iisreset,我将从svc.GetListItems(...)获得500响应。 What's interesting is that it doesn't matter where the Web Reference call originates. 有趣的是,Web Reference调用的来源无关紧要。 When I discovered it using U2U Caml Query Builder, U2U was originating on my local dev machine, and the WCF client call was originating on the web server. 当我使用U2U Caml Query Builder发现它时,U2U起源于我的本地开发机,而WCF客户端调用起源于Web服务器。 The code above also succeeds even if I don't explicitly set the credentials for svc (presumably because it's automatically using my user's credentials). 即使我没有显式设置svc的凭据,上面的代码也成功了(大概是因为它是自动使用用户的凭据)。 Below is the config for ListsSoapClient. 下面是ListsSoapClient的配置。 Can you help me understand what's happening here and how to get svc to succeed on its own? 您能帮助我了解这里发生了什么以及如何使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>

Edit 编辑

Additional Info: 附加信息:
This is logged in the event viewer when I receive the 500: 当我收到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()

Thanks to the error revealed in the Event Viewer and the blog post by Jerry Orman, Mystery of the SharePoint "White Screens" , I've resolved the issue. 由于事件查看器和Jerry Orman的博客( SharePoint的“白屏”之谜)中的错误揭示了错误,我已经解决了此问题。 In short, I needed to add a behavior to my WCF client endpoint allowing the server to impersonate the given user: 简而言之,我需要向WCF客户端端点添加一个行为,以允许服务器模拟给定的用户:

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

So my best guess is this: The Lists.asmx service uses Microsoft.SharePoint.intl.dll. 因此,我最好的猜测是:Lists.asmx服务使用Microsoft.SharePoint.intl.dll。 Loading Microsoft.SharePoint.intl.dll requires impersonation of an authorized user (perhaps because it is not marked as a safe control? I don't know about this). 加载Microsoft.SharePoint.intl.dll需要模拟授权用户(可能是因为未将其标记为安全控件?我对此一无所知)。 After resetting IIS, the assembly is not loaded. 重置IIS后,不加载程序集。 If I call the Lists.asmx service with my WCF proxy, without explicitly specifying an allowedImpersonationLevel of Impersonation , it defaults to Identification and gives the impersonation error above from the event viewer when trying to load Microsoft.SharePoint.intl.dll. 如果我使用WCF代理调用Lists.asmx服务,但未显式指定ImpersonationallowedImpersonationLevel ,则默认为Identification并在尝试加载Microsoft.SharePoint.intl.dll时从事件查看器给出上述模拟错误。 The Lists service handles that exception and responds with a 500 response to make sure you, as a web service consumer, have no idea what the problem actually may be**. Lists服务会处理该异常,并以500响应进行响应,以确保您作为Web服务使用者,不知道问题实际上可能是什么**。 However, if I first call the service with the .NET 2.0 Web Reference proxy, it evidently does (this is my assumption) cause the server to impersonate the given user and the Microsoft.SharePoint.intl.dll assembly loads. 但是,如果我首先使用.NET 2.0 Web参考代理调用该服务,则显然是(这是我的假设)导致服务器模拟给定的用户,并且Microsoft.SharePoint.intl.dll程序集加载。 Now if I use my WCF proxy, the assembly is already loaded and impersonation is not required. 现在,如果我使用WCF代理,则程序集已经加载,并且不需要模拟。 This explanation may not be quite right, but adding the behavior above got my WCF Service Reference to work. 这种解释可能不太正确,但是添加上述行为可以使我的WCF服务参考起作用。

John Saunders, I appreciate your efforts. 约翰·桑德斯(John Saunders),感谢您的努力。 Thanks! 谢谢!

**Come on...I can't go through all this and not rag on SharePoint at least once. **来吧...我无法经历所有这些,并且至少不能一次在SharePoint上乱糟糟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM