PsychoDUCK PsychoDUCK - 5 months ago 51
Ajax Question

AJAX Cross Domain Image Post to WCF Service

I've been stuck for 2 days on this.

Can someone please provide an example of how to do a cross domain AJAX post to a WCF service?

I'm trying to upload an image to the WCF server.

EDIT

WCF Service:

[WebInvoke(UriTemplate = "/upload", Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped), CorsEnabled]
void UploadImage(Stream image);


Ajax Call:

function UploadImage() {
image = document.getElementById("myimage").src;
var data = '{"image": "' + image + '"}'
//alert(data);
$.ajax({
url: "http://localhost:44665/api/upload",
type: "POST",
contentType: "application/json",
data: data,
success: function (result) {
alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
}
});
}


I can get this to work if I change the WCF paramter from Stream to string. But I need to upload an image and not a string.

I am now getting a WCF error that says:

The server encountered an error processing the request. See server logs for more details.


** Edit 2 **
I added the global.asax code mentioned in the below answer and added this to my web.config:

<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myServiceBehavior">
<servicedebug includeexceptiondetailinfaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>

</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
</configuration>


I now get an error in the Google Chrome console that says:

POST http://localhost:44665/api/upload 500 (Internal Server Error)

Answer

So you are trying to make a POST operation from JavaScript to a WCF service that is hosted in another domain. Normally you can't do that without doing some special settings in the WCF service side.

You have to add the following headers to the response from Global.asax.cs in the service side (If the service project doesn't contains Global.asax.cs create one).

protected void Application_BeginRequest(object sender, EventArgs e)
{
   //..
   EnableCrossDomainCall();
}

private void EnableCrossDomainCall()
{
    // this header tells that from any domain you can access me.
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        // this one tells about the supported methods to client.
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods",
                      "GET, POST, OPTIONS");

        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", 
                       "Content-Type, Accept");

        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");

        HttpContext.Current.Response.End();
    }
}

UPDATE:

You can't just post any file through AJAX, through AJAX you can only transfer data. You can use this plugin that uses hidden iframe to upload files that imitates like AJAX.

You can handle the stream object in WCF side as in this link. Try uploading small size images first and you can control the maximum size by setting the maxRequestLength in web.config.

Comments