2013-10-27 511 views
1

目前我在使用EWS時遇到問題,原來的要求是連接到特定用戶的郵件,然後搜索特定文件夾,搜索郵件然後將附件下載到本地計算機的特定文件夾,以便稍後可以由Integration Services處理該附件,但我不想使用EWS託管API,因爲我不想在遷移到生產服務器時安裝任何內容,現在我的想法是開發一個WCF服務,通過.asmx uri連接到EWS服務,並且能夠滿足我的要求,現在我可以連接到公司的EWS,但我有一些疑問:ExchangeServiceBinding,EWS,Exchange Web服務

根據微軟:http://msdn.microsoft.com/en-us/library/exchange/bb408524(v=exchg.150).aspx他們說你必須添加一個我們b服務引用到你的項目,儘管它只提到VS 2005和VS 2008(我正在使用VS 2012),它應該自動創建類ExchangeServiceBinding,它爲你提供了一切你需要的模仿一個帳戶,我的第一個問題是:爲什麼我沒有看到這個課程添加到我的項目中?我應該期待這是因爲我使用VS 2012嗎?

好吧,無論如何,我可以使用一些方法,如getPasswordExpirationTime,但是當我使用FindFolder方法時,我收到錯誤:「該帳戶沒有模仿所請求的用戶的權限」,這是我的方法:

using (ExchangeServicePortTypeClient exchangeServicePortTypeClient = new ExchangeServicePortTypeClient()) 
       { 
        exchangeServicePortTypeClient.ChannelFactory.Endpoint.Address = new EndpointAddress("https://email.kraft.com/EWS/Exchange.asmx"); 


        FindFolderResponseType findFolderResponseType = null; 

        exchangeServicePortTypeClient.FindFolder(
         new ExchangeImpersonationType 
         { 
          ConnectingSID = new ConnectingSIDType 
          { 
           Item = @"[email protected]", 
           ItemElementName = ItemChoiceType1.PrimarySmtpAddress 
          } 
         }, 
         null, 
         new RequestServerVersion { Version = ExchangeVersionType.Exchange2010_SP2 }, 
         null, 
         new FindFolderType 
         { 
          FolderShape = new FolderResponseShapeType 
          { 
           BaseShape = 
            DefaultShapeNamesType.Default 
          } 
         }, out findFolderResponseType); 

       }     

我試圖通過這個設置憑據:

exchangeServicePortTypeClient.ClientCredentials.Windows.ClientCredential.UserName 
exchangeServicePortTypeClient.ClientCredentials.Windows.ClientCredential.Password  
exchangeServicePortTypeClient.ClientCredentials.Windows.ClientCredential.Domain    
exchangeServicePortTypeClient.ChannelFactory.Credentials.Windows.ClientCredential.UserName 
exchangeServicePortTypeClient.ChannelFactory.Credentials.Windows.ClientCredential.Password 
exchangeServicePortTypeClient.ChannelFactory.Credentials.Windows.ClientCredential.Domain 

沒有運氣:(

順便說一下,這是我的WCF的conf ig文件。

<?xml version="1.0" encoding="utf-8"?> 

<configuration> 

    <!--Diagnostics section, we will only catch error and warning in production--> 

    <system.diagnostics> 
     <sources> 
      <source propagateActivity="true" name="System.ServiceModel" switchValue="Error, Warning"> 
       <listeners> 
        <add type="System.Diagnostics.DefaultTraceListener" name="Default"> 
         <filter type="" /> 
        </add> 
        <add type="System.Diagnostics.DefaultTraceListener" name="SellOut.ExchangeWcfService"> 
         <filter type="" /> 
        </add> 
        <add name="ServiceModelTraceListener"> 
         <filter type="" /> 
        </add> 
       </listeners> 
      </source> 
      <source name="System.ServiceModel.MessageLogging" switchValue="Error, Warning"> 
       <listeners> 
        <add type="System.Diagnostics.DefaultTraceListener" name="Default"> 
         <filter type="" /> 
        </add> 
        <add type="System.Diagnostics.DefaultTraceListener" name="SellOut.ExchangeWcfService"> 
         <filter type="" /> 
        </add> 
        <add name="ServiceModelMessageLoggingListener"> 
         <filter type="" /> 
        </add> 
       </listeners> 
      </source> 
     </sources> 
     <sharedListeners> 
      <add initializeData="C:\Users\LFH2623\Documents\SellOut\SellOut\SellOut.Hosts.ExchangeWcfService\SellOut.ExchangeWcfService_web_tracelog.svclog" 
       type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
       name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Callstack"> 
       <filter type="" /> 
      </add> 
      <add initializeData="C:\Users\LFH2623\Documents\SellOut\SellOut\SellOut.Hosts.ExchangeWcfService\SellOut.ExchangeWcfService_web_messages.svclog" 
       type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
       name="ServiceModelMessageLoggingListener" traceOutputOptions="LogicalOperationStack, DateTime, Callstack"> 
       <filter type="" /> 
      </add> 
     </sharedListeners> 
     <trace autoflush="true" /> 
    </system.diagnostics> 

    <!--Framework Section--> 

    <appSettings> 
     <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    </appSettings> 

    <!--Web section--> 

    <system.web>   
     <compilation debug="true" targetFramework="4.5" /> 
     <httpRuntime targetFramework="4.5" maxRequestLength="2147483646" /> 
    </system.web> 

    <!--Web server section--> 

    <system.webServer> 
     <directoryBrowse enabled="false"/> 
     <defaultDocument enabled="true"/>    
     <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 

    <!--WS section--> 

    <system.serviceModel> 

     <diagnostics> 
      <messageLogging logMalformedMessages="true" 
          maxMessagesToLog="10000" 
          logMessagesAtTransportLevel="true" 
          logMessagesAtServiceLevel="True" 
          logEntireMessage="true"/> 
      <endToEndTracing activityTracing="false" /> 
     </diagnostics> 

     <!--For the ExchangeWebService we will aply the following service and endpoint behaviors--> 

     <behaviors> 

      <serviceBehaviors> 
       <behavior name="ExchangeWebService"> 
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" /> 
        <serviceDebug includeExceptionDetailInFaults="false" httpHelpPageEnabled="true" /> 
        <dataContractSerializer maxItemsInObjectGraph="2147483646" /> 
        <serviceTimeouts transactionTimeout="01:00:00" /> 
        <serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" maxConcurrentInstances="100"/> 
        <serviceDiscovery> 
         <announcementEndpoints> 
          <endpoint kind="udpAnnouncementEndpoint"></endpoint> 
         </announcementEndpoints> 
        </serviceDiscovery> 
       </behavior>    
      </serviceBehaviors> 

      <!-- Define the corresponding scope for the clients to find the service through resolve message --> 

      <endpointBehaviors> 
       <behavior name="ExchangeWebService"> 
        <endpointDiscovery enabled="true"> 
         <scopes> 
          <add scope="http://SellOut.ExchangeWcfService/"/> 
         </scopes> 
        </endpointDiscovery> 
       </behavior> 
      </endpointBehaviors> 

     </behaviors> 

     <!-- In case you want to scale this service --> 

     <standardEndpoints> 

      <!-- We allow the service to be discoverable through the network in an adhoc architecture through UDP --> 

      <udpDiscoveryEndpoint> 
       <standardEndpoint name="adhocDiscoveryEndpointConfiguration" 
            discoveryMode="Adhoc" 
            discoveryVersion="WSDiscovery11" 
            maxResponseDelay="00:00:10"> 
       </standardEndpoint> 
      </udpDiscoveryEndpoint> 

      <!-- We allow the service to be discoverable through the network in a managed architecture --> 

      <discoveryEndpoint> 
       <standardEndpoint name="managedDiscoveryEndpoint" discoveryMode="Managed" maxResponseDelay="00:01:00"/> 
      </discoveryEndpoint> 

      <!-- We announce the service with hello & bye --> 

      <announcementEndpoint> 
       <standardEndpoint name="udpAnnouncementEndpointConfiguration" 
            discoveryVersion="WSDiscovery11" /> 
      </announcementEndpoint> 

     </standardEndpoints> 

     <!--All the Kraft's clients are .net, so we will use the proprietary binary message encoding to reduce the message's size --> 

     <bindings> 
      <customBinding> 
       <binding name="wsHttpBindingBynaryEncoding" 
         closeTimeout="00:10:00" 
         openTimeout="00:10:00" 
         receiveTimeout="00:10:00" 
         sendTimeout="00:10:00"> 
        <binaryMessageEncoding> 
         <readerQuotas maxDepth="32" 
             maxStringContentLength="5242880" 
             maxArrayLength="2147483646" 
             maxBytesPerRead="4096" 
             maxNameTableCharCount="5242880" /> 
        </binaryMessageEncoding> 
        <httpTransport 
            transferMode="Buffered" 
            maxBufferPoolSize="2147483646" 
            maxReceivedMessageSize="2147483646"> 
        </httpTransport> 
       </binding> 
      </customBinding> 

      <basicHttpBinding> 
       <binding name="KraftEWS" messageEncoding="Text" transferMode="Buffered"> 
        <security mode="Transport"> 
         <transport clientCredentialType="Windows" proxyCredentialType="Windows"></transport>       
        </security>    
       </binding> 
      </basicHttpBinding> 

     </bindings> 

     <!-- We reference the Kraft EWS --> 

     <client> 
      <endpoint binding="basicHttpBinding" bindingConfiguration="KraftEWS" 
         contract="KraftEWS.ExchangeServicePortType"          
         name="ExchangeServiceBinding_ExchangeServicePortType">     
      </endpoint> 
     </client> 

     <!--Services section--> 

     <services> 
      <service name="SellOut.Services.Exchange.ExchangeWebService" behaviorConfiguration="ExchangeWebService"> 
       <endpoint name="rules" 
          address="rules" 
          binding="customBinding" 
          bindingConfiguration="wsHttpBindingBynaryEncoding" 
          behaviorConfiguration="ExchangeWebService" 
          contract="SellOut.Contracts.Exchange.IExchangeRulesContract"/> 
       <endpoint name="udpDiscovery" 
          kind="udpDiscoveryEndpoint" 
          endpointConfiguration="adhocDiscoveryEndpointConfiguration" /> 
       <endpoint name="mex" 
          address="mex" 
          binding="mexHttpBinding" 
          contract="IMetadataExchange" />    
      </service> 
     </services> 

     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 

    </system.serviceModel> 

</configuration> 

另一件事更何況,在這個配置:

<basicHttpBinding> 
        <binding name="KraftEWS" messageEncoding="Text" transferMode="Buffered"> 
         <security mode="Transport"> 
          <transport clientCredentialType="Windows" proxyCredentialType="Windows"></transport>       
         </security>    
        </binding> 
       </basicHttpBinding> 

如果我刪除了部分客戶端憑據類型「窗口」,試圖運行該服務的異常,當是:

的HTTP請求未經授權,客戶端身份驗證方案爲「匿名」。從服務器收到的驗證頭是'Negotiate,NTLM'。

你們可以幫我一把嗎。

感謝您的建議。

回答

0

我強烈建議您爲此使用EWS託管API。當你聲明你不想在生產服務器上安裝任何東西時,我不明白你的意思,因爲你必須在生產服務器上安裝WCF服務,以及由添加Web服務參考創建的對象模型項目。但是,看起來你已經通過了這部分,所以讓我們繼續...

非常好,很高興知道你可以打電話給getPassowrdExpirationTime。感謝您提供給我的信息。

您收到消息「該帳戶沒有模擬所請求的用戶的權限」的原因是因爲運行您的WCF服務的帳戶沒有該郵箱的模擬權限。在您的服務帳戶可以訪問用戶的帳戶之前,您需要登錄setup Exchange impersonation。一旦您的服務擁有Exchange可以在AD中查找的憑據(它已經擁有),並且它有權模擬您的用戶(位於您的TODO列表中),則您的代碼應該可以工作,因爲身份驗證是基於服務帳戶的身份完成的。

代碼示例後的問題的所有部分都不在範圍內。您不需要對web.config進行任何更改(至少我不這麼認爲)。由於Auth方案是Negotiate和NTLM,因此我假定您正在對內部部署的服務器進行測試。

與問候,

您鏈接到

+0

感謝您的回覆邁克爾的物品,通過在服務器上安裝任何東西我的意思是,我不希望安裝EWS API的服務器,該服務器已經有.NET框架4.5安裝,所以我們可以認爲WCF將功能確定。另外我想告訴你,我發現問題,exchangeservicebinding類不是自動創建的,因爲你必須像舊服務引用一樣添加服務引用,我的意思是,單擊高級屬性,然後添加Web引用,所以在這個類中,我能夠連接指定我想要的任何憑證,而不需要模仿 –

+0

仍然邁克爾你是正確的說你在Exchange中的模擬和是的驗證計劃是談判和NTLM,非常感謝邁克。 –

相關問題