调用与ASMX Web引用后,使用WCF客户端只能调用SharePoint 2007的Web服务 [英] Can only call SharePoint 2007 web service using WCF client after calling with ASMX Web Reference

查看:138
本文介绍了调用与ASMX Web引用后,使用WCF客户端只能调用SharePoint 2007的Web服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序调用使用WCF端点在SharePoint 2007 Lists.asmx服务。在一整天的尝试,以确定为什么它被调用GetListItems方法时接收500的响应,我发现它开始成功后,我在执行U2U Caml中查询生成器查询。也就是说,执行U2U查询之后,Web应用程序停止得到500响应,并使用其WCF服务引用可以成功地检索列表中的项目,直到我做了一个IISRESET。

在针对这一发现,我创建了一个控制台应用程序,并通过WCF服务引用一个简单的调用GetListItems。我已经收窄,到是从WCF服务引用调用实现从一个传统的.NET 2.0 Web引用代理的电话之后才起作用。下面是从我的控制台应用程序的例子code(这是我一直在Web服务器上运行在VS):

 字符串LISTNAME =可重用内容;
字符串的viewName =的String.Empty;
字符串rowLimit = NULL;

//总是工作
XmlDocument的文档=新的XmlDocument();
ListsAsmx.Lists oldSvc =新ListsAsmx.Lists();
oldSvc.Credentials =新System.Net.NetworkCredential(用户1,passwrod,MYDOMAIN);
XmlNode的结果= oldSvc.GetListItems(LISTNAME,的viewName,doc.CreateElement(查询),doc.CreateElement(ViewFields),rowLimit,doc.CreateElement(QueryOptions),NULL);


//只适用上述成功后,
查询字符串=<查询>< /查询>中;
串viewFields =&其中; ViewFields>&所述; / ViewFields>中;
串queryOptions =&其中; QueryOptions>&所述; / QueryOptions>中;

ListsService.ListsSoapClient SVC =新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(查询),XElement.Parse(viewFields),rowLimit,XElement.Parse(queryOptions),NULL);
 

所以,如果我注释掉sv2.GetListItems(...),做一个IISRESET,我从svc.GetListItems 500响应(...)。有趣的是,它并不重要所在的Web引用呼叫发起。当我发现它使用U2U Caml中查询生成器,U2U是源自于我的本地开发计算机,和WCF客户端呼叫发起的Web服务器上。在code以上也成功,即使我没有明确设置凭据SVC(presumably,因为它会自动使用我的用户的凭据)。下面是配置的ListsSoapClient。你能帮助我了解这里发生了什么,以及如何得到SVC接替自己?

 <绑定名称=ListsSoap2closeTimeout =00:01:00openTimeout =00:01:00receiveTimeout =00:10:00的SendTimeout = 0点01分零零秒allowCookies =假bypassProxyOnLocal =假hostNameComparisonMode =StrongWildcardmaxBufferSize =500000maxBufferPoolSize =524288maxReceivedMessageSize =500000messageEncoding =文本textEncoding =UTF-8transferMode = 缓冲useDefaultWebProxy =真正的>
            < readerQuotas MAXDEPTH =32maxStringContentLength =8192maxArrayLength =16384maxBytesPerRead =5120000maxNameTableCharCount =16384/>
            <安全模式=TransportCredentialOnly>
            <交通运输clientCredentialType =NTLM/>
            < /安全>
        < /装订>
    < / basicHttpBinding的>
< /绑定>
<客户端>
    <端点地址=htt​​p://devpladmin.mydomain.com/_vti_bin/Lists.asmx
        绑定=basicHttpBinding的bindingConfiguration =ListsSoap2
        合同=ListsService.ListsSoapNAME =ListsSoap/>
< /客户>
 

修改

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

 异常信息:
异常类型:FileLoadException
异常消息:无法加载文件或程序集Microsoft.SharePoint.intl,版本= 12.0.0.0,文化=中性公钥= 71e9bce111e9429c或它的某一个依赖。要么未提供所需的模拟级别,或提供的模拟级别无效。 (从HRESULT异常:0x80070542)

请求信息:
请求URL:https://devpladmin.mydomain.com:443/_vti_bin/Lists.asmx
请求路径:/_vti_bin/Lists.asmx

线程信息:
线程ID:10
线程帐户名:MYDOMAIN \ USER1
是假冒:假
堆栈跟踪:在System.Reflection.Assembly._nLoad(的AssemblyName文件名,字符串codeBase的,证据assemblySecurity,大会locationHint,StackCrawlMark和放大器; stackMark,布尔throwOnFileNotFound,布尔forIntrospection)
在System.Reflection.Assembly.InternalLoad(的AssemblyName assemblyRef,证据assemblySecurity,StackCrawlMark和放大器; stackMark,布尔forIntrospection)
在System.Reflection.Assembly.InternalLoad(字符串assemblyString,证据assemblySecurity,StackCrawlMark和放大器; stackMark,布尔forIntrospection)
在System.Reflection.Assembly.Load(字符串assemblyString)
在Microsoft.SharePoint.CoreResource..cctor()
 

解决方案

由于在事件查看器中发现的错误和杰里·欧曼的博客文章,<一个href="http://blogs.msdn.com/b/jorman/archive/2009/12/22/mystery-of-the-sharepoint-white-screens.aspx"相对=nofollow> 在SharePoint之谜白色屏幕的,我已经解决了这个问题。总之,我需要一个行为添加到我的WCF客户终端允许服务器冒充特定用户:

 &LT;行为&GT;
       &LT; endpointBehaviors&GT;
          &LT;行为NAME =SPServiceBehavior&GT;
              &LT; clientCredentials&GT;
                    &LT;窗​​户allowedImpersonationLevel =模拟allowNtlm =真/&GT;
              &LT; / clientCredentials&GT;
          &LT; /行为&GT;
       &LT; / endpointBehaviors&GT;
    &LT; /行为&GT;
 

所以,我最好的猜测是这样的:Lists.asmx服务使用Microsoft.SharePoint.intl.dll。加载Microsoft.SharePoint.intl.dll需要一个授权用户的模仿(也许是因为它没有标记为安全控件?我不知道这一点)。重置IIS后,该组件没有被加载。如果我所说的Lists.asmx服务,我的WCF代理,没有明确指定 allowedImpersonationLevel 模拟,则默认为鉴定,并从事件查看器试图加载Microsoft.SharePoint.intl.dll在给上面的模拟误差。列表服务处理的异常,并与500响应响应,以确保您作为一个Web服务的消费者,不知道这个问题实际上可能是什么**。不过,如果我先打电话与.NET 2.0 Web引用代理服务,它显然不会(这是我的假设),导致服务器来模拟特定用户和Microsoft.SharePoint.intl.dll装配负荷。现在,如果我用我的WCF代理,该组件已加载,并且不需要模拟。这种解释可能不是很正确,但添加行为上面有我的WCF服务参考工作。

约翰·桑德斯,我AP preciate你的努力。谢谢!

**来吧......我无法通过这一切,在SharePoint不抹布至少一次。

I have a web app that calls the SharePoint 2007 Lists.asmx service using a WCF endpoint. 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. 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.

In response to that discovery, I created a console app that does a simple call to GetListItems via a WCF Service Reference. 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. Here's the example code from my console app (which I have been running within VS on the web server):

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(...). What's interesting is that it doesn't matter where the Web Reference call originates. 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. 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). Below is the config for ListsSoapClient. Can you help me understand what's happening here and how to get svc to succeed on its own?

        <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:

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. In short, I needed to add a behavior to my WCF client endpoint allowing the server to impersonate the given user:

    <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. 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). After resetting IIS, the assembly is not loaded. 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. 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**. 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. Now if I use my WCF proxy, the assembly is already loaded and impersonation is not required. This explanation may not be quite right, but adding the behavior above got my WCF Service Reference to work.

John Saunders, I appreciate your efforts. Thanks!

**Come on...I can't go through all this and not rag on SharePoint at least once.

这篇关于调用与ASMX Web引用后,使用WCF客户端只能调用SharePoint 2007的Web服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆