0

I'm looking for an example of an ajax call for streaming data to a WCF service. I am always getting an error. Any help appreciated, or even links to blogs with a solution. This is my WCF service class

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Images : IImages
{
    string IImages.UploadImage(string fileKey, Stream imageStream)
    {
        using (var fileStream = File.Create(@"Images\" + fileKey))
        {
            imageStream.CopyTo(fileStream);
        }
        return "done";
    }
}

and my contract is

[OperationContract(Name = "UploadImage")]
[WebInvoke(UriTemplate = "?file_key={fileKey}", Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
string UploadImage(string fileKey, Stream imageStream);

I have web.config stream binding

<binding name="PublicStreamBinding"
        maxReceivedMessageSize="2000000000" transferMode="Streamed">
    <security mode="None" />
</binding> 

my ajax client call is like this

var data = '{"image":"' + uri + '"}'
$.ajax({
    url: GetServerUrl()+"images.svc/?file_key="+options.fileKey,
    type: "POST",
    contentType: "application/json",
    data: data,
    success: function (result) {
        console.log("SUCCESS");
    },
    error: function (jqXHR, textStatus, errorThrown) {
        console.log("error in transfer::" + jqXHR.responceText);
    }
});

2 Answers 2

1

I can't comment on the server-side code, but client-side :

  • the data variable should be a plain javascript object, not a JSON representation
  • url shouldn't need the GetServerUrl() prefix; try a leading "/" instead
  • for a POST request it's more normal to include all parameters in the data object rather than tacking them onto the URL, which is the GET approach. It depends what the server-side code is set up to expect but as far as I can tell, it expects file_key to be in the POST.

You should end up with something like this :

var data = {
    image: uri,
    file_key: options.fileKey
};
$.ajax({
    url: "/images.svc/",//probably
    type: "POST",
    contentType: "application/json",
    data: data,
    success: function (result) {
        console.log("SUCCESS");
    },
    error: function (jqXHR, textStatus, errorThrown) {
        console.log("errror in transfer::" + jqXHR.responceText);
    }
});
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the tips, I tried to have the data set up like you said but i get a message "errror in transfer::undefined". I should really spell error correctly, will fix my post.
You can see above the service is set up for a POST. Do you know how i can get a more maningful error message?
I rather like "errror" with three 'r's - it has a certain je ne sait qqqouoi. For a more meaningful error message, try exploring the two parameters textStatus and errorThrown passed to the error handler.
On that same point, c# should let you set HTTP response headers such that an application error stimulates an HTTP response error. That way (client-side), success will always end up in the success handler and errors of all types will end up in the error handler. Otherwise, you have to handle application errors in the success handler, which is messy. I have only ever needed to do this in PHP but the principles must be identical regardless of which server-side technology is used.
0

Install Fiddler ( www.telerik.com/fiddler ). Launch it. Make the web service call. Click on the record of the call in Fiddler. Click on the 'Raw' tabs for request and response. It will be enlightening and you will see exactly what is passed between server and client. Perhaps some addition WCF troubleshooting data as well in the response.

Also, don't forget to check your Application event log on the machine running the WCF service. You can also add a Global.asax to the WCF project (if its a web project) and put logging code in the Application_Error method. Something like this:

    protected void Application_Error(object sender, EventArgs e)
    {       
        Exception ex = Server.GetLastError();

        if (ex is ThreadAbortException)
        {
            // Nothing to do here. The thread abended.
        }
        else
        {
            activityMgr.Add(System.Reflection.MethodBase.GetCurrentMethod(), ex);
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.