Getting “EndPoint Not Found” error with WCF service deployed to SharePoint 2010 site

不羁岁月 提交于 2019-12-05 22:03:28

For webpart project (with ASCX) you can:

1) Enable Anonymous Authentication for SP SIte in IIS

2) Add SP Mapped folder ISAPI

3) Create YourService.asmx in ISAPI

<%@ WebService Language="C#" Class="YourNamespace.YourService, YourAsm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=YourPublicKeyToken"%>

4) Edit user control code:

public partial class YourControl : UserControl
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        FixFormAction();
        CheckScriptManager();           
        EnsureUpdatePanelFixups();
    }

    private void FixFormAction()
    {
        // Fix problem with postbacks and form actions (DevDiv 55525)
        Page.ClientScript.RegisterStartupScript(GetType(), ID, "_spOriginalFormAction = document.forms[0].action;", true);

        // By default, the onsubmit event for forms in SharePoint master pages call "return _spFormOnSubmitWrapper()" 
        // which blocks async postbacks after the first one.   Not calling "_spFormOnSubmitWrapper()" breaks all postbacks
        // and defeats the purpose of _spFormOnSubmitWrapper() which is to block repetitive postbacks.  
        // To call _spFormOnSubmitWrapper() and allow partial postbacks, remove "return" from the original call.  
        if (Page.Form != null)
        {
            string formOnSubmitAtt = Page.Form.Attributes["onsubmit"];
            if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
            {
                Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
            }
        }
    }

    private void EnsureUpdatePanelFixups()
    {
        if (this.Page.Form != null)
        {
            var fixupScript = @"
            _spBodyOnLoadFunctionNames.push(""_initFormActionAjax"");
            function _initFormActionAjax()
            {
            if (_spEscapedFormAction == document.forms[0].action)
            {
            document.forms[0]._initialAction = document.forms[0].action;
            }
            }
            var RestoreToOriginalFormActionCore = RestoreToOriginalFormAction;
            RestoreToOriginalFormAction = function()
            {
            if (_spOriginalFormAction != null)
            {
            RestoreToOriginalFormActionCore();
            document.forms[0]._initialAction = document.forms[0].action;
            }
            }
            ";
            ScriptManager.RegisterStartupScript(this, this.GetType(), "EnsureUpdatePanelFixup", fixupScript, true);
        }
    }

    private ScriptManager CheckScriptManager()
    {
        ScriptManager sm = ScriptManager.GetCurrent(Page);
        if (sm == null)
        {
            if (Page.Form != null)
            {
                sm = new ScriptManager();
                sm.ID = Page.Form.ID + "_ScriptManager";
                Page.Form.Controls.Add(sm);
                //Page.Form.Controls.AddAt(0, sm);  
            }
        }
        sm.EnablePageMethods = true;

        var sharedPath = @"~/_layouts/Share/";
        var path = @"~/_layouts/YourWebPart/";

        sm.Scripts.Add(new ScriptReference { Path = @"/_vti_bin/YourService.asmx/JS" });

        //Registering ExtJS
        Page.ClientScript.RegisterClientScriptInclude(GetType(), "ext-all", sharedPath + "scripts/ext-all.js");

        ScriptManager.RegisterClientScriptBlock(this, GetType(), "ext-css",
                                    "<link href='" +
                                    sharedPath + "resources/css/ext-all.css' rel='stylesheet' type='text/css' />", false);

        Page.ClientScript.RegisterClientScriptInclude(GetType(), "YourScript", path + "scripts/Script.js");

        return sm;
    }

}

5) Edit your service code:

[WebService(Namespace = "http://tempuri/ws")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class YourService : WebService
{
    //[WebMethod]
    [ScriptMethod]
    [WebMethod(EnableSession = true)]
    //[ScriptMethod(UseHttpGet = true)]
    public string YourWebMethod(string arg)
    {           
        return arg;
    }
}

6) Use you web service methods in control javascript:

YourNamespace.YourService.YourWebMethod(arg, function (result) {
        if (result) {
            if (typeof result == 'string') {
                alert(result);
            }
        }
    }, function (error) { alert('YourWebMethod failed! ' + error.get_message()); });
}

No webconfig

For svc in ISAPI subfolder

<%@ ServiceHost Debug="true" Language="C#"
Service="Namespace.MyService, MyAsm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=MyPublicKeyToken"
%>

web.config can be:

<system.webServer>    
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="2097151"/>
      </requestFiltering>
    </security>
  </system.webServer>
  <system.web>
    <httpRuntime executionTimeout="60" maxRequestLength="2097151" />        
  </system.web>  
  <system.serviceModel>    
    <bindings>
      <basicHttpBinding>        
        <binding name="MyHttpBinding"
         maxBufferPoolSize="2147483647"
         maxBufferSize="2147483647"
         maxReceivedMessageSize="2147483647">          
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>          
          <readerQuotas maxArrayLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647"/>
        </binding>
      </basicHttpBinding>      
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CustomServiceBehaviour">          
          <serviceMetadata httpGetEnabled="true"/>          
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>          
        </behavior>
      </serviceBehaviors>      
    </behaviors>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
      <service behaviorConfiguration="CustomServiceBehaviour" name="Namespace.MyService">        
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyHttpBinding" contract="Namespace.IMyService" bindingNamespace="http://tempuri/ws" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>      
    </services>
    </system.serviceModel>
Ami Schreiber

So I still can't get the to work with my WCF service but I did figure out how to fix the EndPoint Not Found error.

So there are three things at play here that I didn't fully understand or overlooked.

  1. The WCF Client Test Utility from Microsoft only tests SOAP requests.
  2. How all of the different bindings worked and what they meant.
  3. That you need to make sure the right account is being used for the Anonymous User Identity in IIS.

With items #1 and #2 I needed to add another endpoint to handle soap requests that either used or . I had only one binding specified that was and although that gave me the warm fuzzies in the browser it essentially caused the WCF Client Utility not to work because I basically didn't have any SOAP endpoints defined. Read more about the differences here.

As for item #3, I found my answer here. It took days of weaving through posts about changing the web.config, writing stuff in code with usernames and passwords to enabling and disabling every form of authentication type known to man in IIS. This was what ultimately did the trick and allowed me to use the WCF Client Test Utility without the pesky EndPoint Not Found error.

Also, for those of you that are interested, I've actually started a new post that focuses specifically on the issue that can be found here.

FYI: I have managed to get to the point where I can return identical JSON data from my WCF service that looks just like the JSON data that gets returned when the code is executed from the ASPX's CodeBehind page and actually works...but for some reason when using the WCF method nothing gets autocompleted. The only thing I notice that's different when using the WCF service method is that before getting the sweet http 200 message with the JSON data there is always an http 401 authentication error that precedes it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!