创建一个接受文件的Web服务(Stream)不需要其他参数

我有一个文件,我想上传到Web服务,但它需要额外的参数,所以我创建一些隐藏的字段与相关的名称:值对,以推送到服务器请求。 但问题是服务的定义。

[错误]

合同“IFormServices”中的“NewImage”操作有多个请求体参数,其中一个是Stream。 当Stream是参数时,正文中不能有其他参数。

[接口]

[OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json)] string NewImage(Stream data, string server,string datasource, string document, string image_id); 

[定义]

 public string NewImage(Stream data, string server, string datasource, string document, string image_id) { //this should, similar to others, need a server, datasource, and some sort of document in which to append the images. WebClient wsb = new WebClient(); string str = "_URL_"; byte[] byte_data = new byte[data.Length]; data.Read(byte_data, 0, byte_data.Length); byte[] response = wsb.UploadData(str,"POST",byte_data); string retVal = Convert.ToString(response); //want to return a JSON.serialized dictionary of: given image_id + id returned from response. Dictionary retDict = new Dictionary(); retDict["filename"] = image_id; retDict["id"] = ""; //return new JavaScriptSerializer().Serialize(json); return "-1"; } 

[javascript代码]

 var $form = $("
").attr({ method: "POST", enctype: "multipart/form-data", target: "image_processing", action: "webservices/FormServices.svc/NewImage", id: "push_image_to_server" } ).appendTo( "body" ); var im_id = $( this ).attr( "image_id" ); $( this ).appendTo( "form#push_image_to_server" ); $( "" ).attr( { name: "server", value: BASE_URL } ).appendTo( $form ); $( "" ).attr( { name: "datasource", value: SELECTED_DATASOURCE } ).appendTo( $form ); $( "" ).attr( { name: "document", value: SELECTED_DOCUMENT } ).appendTo( $form ); $( "" ).attr( { name: "image_id", value: im_id } ).appendTo( $form ); $("iframe#image_processing").bind("load", function (a,b,c) { console.log("SUCCESS", arguments); $( "iframe#image_processing" ).unbind( "load", function (a,b,c) { console.log( arguments ); _IMAGE_UPLOADS_[a["filename"]] = a["id"]; } ); $( "form#push_image_to_server" ).remove(); } );

所以我想找出一种方法将4个字符串+一个文件发送到服务器。

这怎么办?

编辑:将错误代码放在顶部。

只是一个想法 – 如何使用HTTP标头? 然后,您可以使用WebOperationContext.IncomingRequest进行处理。

当您发送流时,它实际上会发送请求中的所有内容。 我这样做是为了得到数据:

 public string NewImage(Stream data){ NameValueCollection PostParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd()); string server = PostParameters["server"], string datasource = PostParameters["datasource"], string document = PostParameters["document"]; string image_id = PostParameters["image_id"]; var img = PostParameters["File"]; //do other processing... } 

这篇文章: 如何:使用WCF创建一个接受任意数据的服务REST编程模型描述了另一种发布流和一些数据的方法。

它们显示了如何发送文件名(但您可以使用任何字符串参数添加和/或替换它)以及文件。

合同是:

 [ServiceContract] public interface IReceiveData { [WebInvoke(UriTemplate = "UploadFile/{strParam1}/{strParam2}")] void UploadFile(string strParam1, string strParam2, Stream fileContents); } 

公开的服务将通过POST接受流​​以及定义的参数。

这是WCF的问题\错误,在使用Stream输入时不接受任何其他参数。

我们也遇到了与WCF类似的问题,经过所有研究后我们决定将其他输入参数转换为流并将其附加到带有分隔符的输入

如果NewImage方法上的string结果参数是某种唯一标识符,您可以创建一个名为NewImageAttributes的第二个方法,它接受额外的数据以及唯一标识符,然后您可以在服务中再次将数据绑定在一起。

当然,这意味着两次调用该服务,但它可能会解决您的问题。

如何使用HttpRequest.QueryString[]

 [OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "NewImage")] string NewImage(Stream data); 

你通过URL调用它,如:

 \NewImage?server={server}&datasource={datasource}&document={doc}&image_id={id} 

然后在你的代码中:

 public string NewImage(Stream imgStream) { var request = System.Web.HttpContext.Current.Request; var server= request.QueryString["server"]; var datasource = request.QueryString["datasource"]; var document= request.QueryString["document"]; var image_id= request.QueryString["image_id"]; ... } 

我一直在寻找这样的东西,今天偶然发现它。