Search code examples
c#ajaxwcfuserscriptsscriptish

Calling a local WCF service via Scriptish or Greasemonkey


I'm trying to expose a local WCF service that checks to see if a file exists in my database that can be accessed from a Scriptish script.

Is it possible to call a local URL from Scriptish or Greasemonkey (GET or POST)? I've created a WCF service hosted in IIS on my local machine, and the service is working fine. However, when I try to call the service from Scriptish the Network tab in Chrome/Firefox just says the following:

Request URL: http://localhost/service/service.svc/MatchPartial
Request Method: OPTIONS
Status code: 405 Method Not Allowed

Here is my ajax call:

$.ajax({
    url: 'http://localhost/service/service.svc/MatchPartial',
    type: 'POST',
    contentType: 'application/json; charset=UTF-8',
    dataType: 'json',
    processData: true,
    data: '{ "partialFilename": "testing" }',
    success: function (result) {
        console.log(result);
    }
});

My method is decorated with:

[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public int MatchPartial(string partialFilename)
{
    ...
}

I have the following above my service class:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

I've tried adding the following to my service with no luck:

[WebInvoke(Method = "OPTIONS", UriTemplate = "*")]
public void GetOptions()
{
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
}

I feel like I've tried everything. Any help would be appreciated!


Solution

  • I figured out how to do it via a GET request thanks to M.Babcock for pushing me in that direction (unimportant parts intentionally left out to save space).

    Service.svc:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service : IService
    {
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        public bool MatchPartial(string partialFilename)
        {
            ...
        }
    }
    

    Web.config:

    <configuration>
      ...
      ...
      <system.web>
        <compilation debug="true"
                     targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>
      <system.webServer>
        <httpProtocol>
          <customHeaders>
            <!-- IMPORTANT FOR THIS TO WORK USING JQUERY GET OR AJAX -->
            <add name="Access-Control-Allow-Origin" 
                 value="*" />
          </customHeaders>
        </httpProtocol>
      </system.webServer>
      <system.serviceModel>
        <services>
          <service name="MyNamespace.Services.WCF.Service">
            <endpoint address=""
                      binding="webHttpBinding" 
                      bindingConfiguration=""
                      contract="MyNamespace.Core.Interfaces.IService" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost/Service" />
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true" />
              <!-- For Debugging --->
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior>
              <webHttp />
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
                                   multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
      </system.webServer>
    </configuration>    
    

    Here's how to do it in Scriptish:

    var service = "http://localhost/service/service.svc";
    
    GM_xmlhttpRequest({
        method: "GET",
        url: service + "/MatchPartial?partialFilename=" + filename,
        headers: { "Accept": "application/json" },
        onload: function (result) {
            if (result != null && result.status == 200 && result.responseJSON == true) {
                videoFrame.remove(); 
            }
        },
        onerror: function (res) {
            GM_log("Error!");
        }
    });
    

    Plain ol' jQuery:

    $.get("service", { partialFilename: filename }, function (result) {
        if (result == true) {
            videoFrame.remove(); 
        }
    });