0

I'm trying to upload a complex object to my WCF REST service. I'm doing this because it seems to be the easiest way to upload a Stream type object and other parameters to a endpoint at the same time.

Service:

[OperationContract]
[WebInvoke(Method = "POST",
    BodyStyle = WebMessageBodyStyle.Bare,
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    UriTemplate = "Upload")]
public string upload(UploadObject uploadObject)
{
    return uploadObject.stream.ToString() + " " + uploadObject.guid; 
}

[DataContract]
public class UploadObject
{
    [DataMember]
    public Stream stream { get; set; }
    [DataMember]
    public string guid { get; set; }
}

JQuery

var guid = getParameterByName("guid");  //<--gets value from query string parameter
var file = $('#btnUpload').val();  //<--value from a file input box
var uploadObject = { stream: file, guid: guid };

$.ajax({
    type: "POST",            
    contentType: "application/json",
    url: "localhost/service/Upload", 
    data: uploadObject,
    datatype: "jsonp",
    processData : false,          
    success: function(data){
        alert(data);
    },
    error: function (xhr, status, error) {
        alert("fail");
    }
});
user1134179
  • 539
  • 1
  • 12
  • 24

1 Answers1

0

By default $.ajax will encode objects using the application/x-www-form-urlencoded format. You say that the content-type is JSON, so you should also encode the object using that format (using JSON.stringify should do the trick):

var guid = getParameterByName("guid");  //<--gets value from query string parameter 
var file = $('#btnUpload').val();  //<--value from a file input box 
var uploadObject = { stream: file, guid: guid }; 

$.ajax({ 
    type: "POST",             
    contentType: "application/json", 
    url: "localhost/service/Upload",  
    data: JSON.stringify(uploadObject), 
    processData : false,           
    success: function(data){ 
        alert(data); 
    }, 
    error: function (xhr, status, error) { 
        alert("fail"); 
    } 
}); 

Also, you cannot specify dataType: "jsonp" for POST requests. JSONP is only applicable to GET requests.

One more problem with your contract: you cannot have Stream as part of your data contract; Stream is an abstract class, and the WCF serializer doesn't know how to deserialize into an abstract class. What exactly is the type of "file" in your JS code? If it's the file contents, is it stored in a string? If so, use string as the data type for it on your contract.

carlosfigueira
  • 85,035
  • 14
  • 131
  • 171
  • The whole purpose of the contract was to post a stream and a string to the service. What's the best approach of accomplishing this then? Also I was trying to get the actual file from the input type file – user1134179 Oct 11 '12 at 18:00