代码改变世界

EWS编程问题三:调用WebService出现 请求因 HTTP 状态 404 失败 Not Found 错误(解决)

2010-10-11 13:20  努力学习的小熊  阅读(22675)  评论(0编辑  收藏  举报

        这个问题是在如下状况出现的,当初实施人员为了我写程序方便,关掉了Exchange服务器上IIS里面EWS的SSL访问,直接利用http去访问这个WebService,结果上一篇文章中的代码在这个函数就出现了问题。

 

public static FolderIdType FindFolderID
{
    ......
     FindFolderResponseType objFindFolderResponse 
= 
               service.FindFolder(requestFindFolder); 
    ......
}

 

        错误信息就是标题里面写的:请求因 HTTP 状态 404 失败 Not Found。

        查找一些文章后发现这个问题就是因为我上面说到的关闭了IIS中EWS的SSL访问造成的,那么既然找到问题解决就好了,开启了EWS网站的SSL,问题解决。

        参考文章:

        Issue: Getting HTTP 404 error on every request made via Exchange Web Services using EWS HTTP endpoint for Exchange Server 2010

        那么EWS就不支持不开启SSL的访问吗?当然是支持,这个我并没有亲自去尝试,毕竟是客户的生产环境,待以后有时间尝试吧。文章我贴出来链接,按照里面的设置就可以使EWS支持不开启SSL并且可以被正常调用。

        How to configure a HTTP endpoint for Exchange Web Services in Exchange 2010

       

        文章内容也搞过来吧,呵呵,万一哪天不能访问了呢:P

        第一篇:

Issue: Getting HTTP 404 error on every request made via Exchange Web Services using EWS HTTP endpoint for Exchange Server 2010

 

Few of our customer reported that they are getting HTTP 404 Error reported; when they tries to use EWS HTTP service endpoint for their application for Exchange Server 2010. However, the same application work fine with EWS HTTP service endpoint with Exchange Server 2007 without any issue.

If we go into Internet Information Services (IIS) on Exchange 2010 RTM and uncheck the box 'Require secure channel (SSL)' on the EWS virtual directory. And then we attempt to make a request using HTTP using EWS service endpoint as “http://host:port/EWS/Exchange.asmx” then we would receive a HTTP 404 Resource Not Found.

Exchange 2010 Web Services are now based on Windows Communication Foundation (WCF). We receive a HTTP 404 because WCF attempts to locate the endpoint for HTTP but cannot find it and throws a System.ServiceModel.EndpointNotFoundException exception which throws up to the client as a 404 exception.

Using HTTP instead of HTTPS is not the recommended approach for Exchange Web Services but sometimes it is helpful in debugging/troubleshooting to have this option.

Here are the steps posted by my colleague Dave @ How to configure a HTTP endpoint for Exchange Web Services in Exchange 2010 to workaround the issue.

        第二篇:

How to configure a HTTP endpoint for Exchange Web Services in Exchange 2010

 

In Exchange 2007 if you wanted to enable HTTP for Exchange Web Services all you had to do was go into Internet Information Services (IIS) and uncheck the box 'Require secure channel (SSL)' on the EWS virtual directory.  In Exchange 2010 RTM this is no longer possible.  IIS still gives you this option; however it does not give you the behavior you are expecting.  If you uncheck this box and attempt to make a request using HTTP you receive a HTTP 404 Resource Not Found.

Exchange 2010 Web Services are now based on Windows Communication Foundation (WCF). You receive a HTTP 404 because WCF attempts to locate the endpoint for HTTP but cannot find it and throws a System.ServiceModel.EndpointNotFoundException exception which bubbles up to the client as a 404. I can't say that this is an intuitive error message but if you think about it long enough it kinda makes sense.

Using HTTP instead of HTTPS is not the recommended approach for Exchange Web Services but sometimes it is helpful in debugging / troubleshooting to have this option.  Therefore, if you need to enable HTTP do the following (Note: Please proceed with care, a misspelling here could be the difference between working and non-working):

  1. Confirm that you have unchecked the box 'Require SSL' in IIS. 
  2. Navigate to the EWS directory.  By default, C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\exchweb\ews
  3. Find the web.config file, copy it and rename the copy to web.config.old.
  4. Open the web.config in your favorite text editor.
  5. Replace the element:

    <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpsBinding"

     contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

With the following elements:

     <!-- Standard EWS HTTP endpoint-->

    <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpBinding"

     contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

     <!-- Standard EWS HTTPS endpoint -->

     <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpsBinding"

      contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

  1. Replace the element:

    <binding name="EWSHttpsBinding">

     <EWSMessageEncoderSoap11Element />

     <httpsTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

      maxBufferSize="81920" transferMode="Streamed" />

    </binding>

With the following elements:

     <!-- EWS endpoint binding for HTTP -->

     <binding name="EWSHttpBinding">

       <EWSMessageEncoderSoap11Element />

       <httpTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

        maxBufferSize="81920" transferMode="Streamed">

       </httpTransport>

     </binding>

     <!-- EWS endpoint binding for HTTPS-->

     <binding name="EWSHttpsBinding">

     <EWSMessageEncoderSoap11Element />

      <httpsTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

       maxBufferSize="81920" transferMode="Streamed" >

      </httpsTransport>

    </binding>

  1. Save the file

At this point IIS should detect the change in the web.config and reload the settings.  Exchange 2010 SP1 should enable the behavior as it was in Exchange 2007. 

Note: If you forget that the setting 'Require SSL' is disabled in IIS than enable again it will cause your application to quit working.  You will see Internal 500 errors as well as event log entries in the Event log on the Client Access Server.  Here is an example of one:

Log Name:      Application
Source:        System.ServiceModel 3.0.0.0
Event ID:      3
Task Category: WebHost
Level:         Error
Keywords:      Classic
Description:
WebHost failed to process a request.
 Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/27717712
 Exception: System.ServiceModel.ServiceActivationException: The service '/EWS/exchange.asmx' cannot be activated due to an exception during compilation.  The exception message is: Could not find a base address that matches scheme http for the endpoint with binding CustomBinding. Registered base address schemes are [https].. ---> System.InvalidOperationException: Could not find a base address that matches scheme http for the endpoint with binding CustomBinding. Registered base address schemes are [https].
   at System.ServiceModel.ServiceHostBase.MakeAbsoluteUri(Uri relativeOrAbsoluteUri, Binding binding, UriSchemeKeyedCollection baseAddresses)
   at System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress)
   at System.ServiceModel.ServiceHostBase.ApplyConfiguration()
   at System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses)
   at System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
   at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses)
   at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CreateService(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   --- End of inner exception stack trace ---
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath)
 Process Name: w3wp
 Process ID: 1234

If you would like to enable 'Require SSL' again on the EWS virtual directory please follow the instructions below: 

  1. Check the box 'Require SSL' on the EWS virtual directory in IIS. Check the 'Require 128-bit SSL box as appropriate. 
  2. Rename the current web.config to web.config.HTTP to create a backup
  3. If you still have the old Web.Config change the name of it from web.config.old back to web.config.  If not, continue to Step 4.
  4. Remove the element:
  5.      <!-- Standard EWS HTTP endpoint-->

        <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpBinding"

         contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

  6. Remove the following element:

     <!-- EWS endpoint binding for HTTP -->

     <binding name="EWSHttpBinding">

       <EWSMessageEncoderSoap11Element />

       <httpTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

        maxBufferSize="81920" transferMode="Streamed">

       </httpTransport>

     </binding>

  1. Save the file