安卓调用wcf服务file wcf 怎么接收

3666人阅读
在WCF 4.0中,为我们创建Restful API有了更好的支持。通过定义UriTemplate,WebInvoke就可以快速开发API接口。
这里我记录一下HTTP POST数据时要如何接收POST过来的数据。
1,方法一:Stream inputStream 输入流方法(注意看方法
例如我的代码
[OperationContract]
[WebInvoke(Method = &POST&, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = &json/ui/{projectName}/{entityName}?q={queryString}&id={indentity}&)]
UpdateOrInsertEntityResponse UpdateOrInsertEntityResponse (String projectName, String entityName, String queryString,String indentity,Stream pstream);
UriTemplate定义了参数匹配关系。
&json/ui/{projectName}/{entityName}?q={queryString}&id={indentity}&
对应的参数
String projectName,
String entityName,
String queryString,String indentity
名称必须相同,否则不能匹配。所有字段必须是String类型。
如何获取POST过来的数据信息。
定义Stream pstream参数。
如果你现在运行应用程序的话,会在页面爆出一个错误信息:
System.InvalidOperationException: For request in operation UpdateOrInsertEntityResponse to be a stream the operation
must have a single parameter whose type is Stream.
如何解决。
第一步,修改你自己的Service.svc文件。
ServiceHost Language=&C#&
Debug=&true&
Service=&Vine.DataMan.RestfulService.EntityService&
CodeBehind=&EntityService.svc.cs&
增加新的属性:
Factory=&System.ServiceModel.Activation.WebServiceHostFactory&
最后结果是:
ServiceHost Language=&C#&
Debug=&true&
Service=&Vine.DataMan.RestfulService.EntityService&
CodeBehind=&EntityService.svc.cs&
Factory=&System.ServiceModel.Activation.WebServiceHostFactory&
修改配置文件Web.config
&system.serviceModel&
&services&
name=&Vine.DataMan.RestfulService.EntityService&&
binding=&webHttpBinding&
contract=&Vine.DataMan.RestfulService.ServiceContracts.IEntityCommonService&
behaviorConfiguration=&webHttp&/&
&/service&
&/services&
&behaviors&
&endpointBehaviors&
name=&webHttp&&
&webHttp/&
&/behavior&
&/endpointBehaviors&
&serviceBehaviors&
&behavior&
&!-- To avoid disclosing metadata information, set the value below
to false and remove the metadata endpoint above before deployment --&
&serviceMetadata
httpGetEnabled=&true&/&
&!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment to avoid disclosing exception information
&serviceDebug
includeExceptionDetailInFaults=&true&/&
&/behavior&
&/serviceBehaviors&
&/behaviors&
&serviceHostingEnvironment
aspNetCompatibilityEnabled=&true&/&
&/system.serviceModel&
注意加粗的文字。必须定义webHttp的行为。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:121356次
积分:1619
积分:1619
排名:第19593名
原创:37篇
转载:108篇
(1)(2)(1)(1)(3)(9)(2)(1)(1)(1)(1)(15)(3)(30)(2)(3)(2)(1)(1)(40)(4)(1)(4)(4)(9)(1)(1)(3)君,已阅读到文档的结尾了呢~~
利用WCF REST方式上传文件如图片并和安卓做测试
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
利用WCF REST方式上传文件如图片并和安卓做测试
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口最近一直在搞android上传图片、视频、文件,服务端使用wcf接收,本文对调试中的遇到的问题进行记录。
&&&&&& 首先android上传一些小图片是比较容易的一天下来差不多就能调试出来,但是上传一些大的文件时就出现各种问题,包括wcf默认支持64k的文件,后来大图片可以上传了,但是传视频又有问题,上传的视频打不开,经过努力google最后问题终于解决了。作者
以下是调试代码:原文链接:
一、Android:
package com.kwstu.
import java.io.F
import java.io.FileInputS
import java.io.IOE
import org.apache.http.HttpR
import org.apache.http.client.ClientProtocolE
import org.apache.http.client.HttpC
import org.apache.http.client.methods.HttpP
import org.apache.http.entity.InputStreamE
import org.apache.http.impl.client.DefaultHttpC
import android.app.A
import android.graphics.B
import android.graphics.BitmapF
import android.os.B
import android.os.E
import android.os.H
import android.os.M
import android.view.V
import android.view.View.OnClickL
import android.widget.B
import android.widget.ImageV
public class UpladeActivity extends Activity {
&&&private Button update_
&&&private ImageView img_
&&&/** Called when the activity is first created. */
&&&@Override
&&&public void onCreate(Bundle savedInstanceState) {
&&&&&&super.onCreate(savedInstanceState);
&&&&&&setContentView(R.layout.uploadactivity);
&&&&&&findAll();
&&&&&&bind();
&&&public void findAll() {
&&&&&&update_btn = (Button) this.findViewById(R.id.update_btn);
&&&&&&img_img = (ImageView) this.findViewById(R.id.img_img);
&&&public void bind() {
&&&&&&update_btn.setOnClickListener(mylistener);
&&&private View.OnClickListener mylistener = new OnClickListener() {
&&&&&&public void onClick(View v) {
&&&&&&&&&switch (v.getId()) {
&&&&&&&&&case R.id.update_btn:
&&&&&&&&&&&&Thread th1 = new Thread(new mythread());
&&&&&&&&&&&&th1.start();
&&&&&&&&&&&&break;
&&&&&&&&&default:
&&&&&&&&&&&&break;
&&&&&&&&&}
&&&Handler hd = new Handler() {
&&&&&&@Override
&&&&&&public void handleMessage(Message msg) {
&&&&&&&&&if (msg.what == 123) {
&&&&&&&&&&&&String jason = msg.obj.toString();
&&&&&&&&&&&&String filepath = Environment.getExternalStorageDirectory()
&&&&&&&&&&&&&&&&&&&+ File.separator +
&&&&&&&&&&&&Bitmap bitmap1 = BitmapFactory.decodeFile(filepath);
&&&&&&&&&&&&img_img.setImageBitmap(bitmap1);
&&&&&&&&&}
&&&class mythread implements Runnable {
&&&&&&public void run() {
&&&&&&&&&HttpClient hc = new DefaultHttpClient();
&&&&&&&&&HttpPost hp = new HttpPost(wcf地址);
&&&&&&&&&HttpR
&&&&&&&&&InputStreamEntity reqE
&&&&&&&&&String path = 上传文件路径;
&&&&&&&&&File f = new File(path);
&&&&&&&&&if (f.exists()) {
&&&&&&&&&&&&System.out.println("successful");
&&&&&&&&&&&&try {
&&&&&&&&&&&&&&&&reqEntity = new InputStreamEntity(new FileInputStream(path), -1);
&&&&&&&&&&&&&&&&reqEntity.setContentType("binary/octet-stream");
&&&&&&&&&&&&&&&&reqEntity.setChunked(true);
&&&&&&&&&&&&&&&&hp.setEntity(reqEntity);
&&&&&&&&&&&&&&&&System.out.println("4");
&&&&&&&&&&&&&&&&HttpResponse response = hc.execute(hp);
&&&&&&&&&&&&&&&&System.out.println("5");
&&&&&&&&&&&&} catch (ClientProtocolException e) {
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&System.out.println(e.getMessage());
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&System.out.println(e.getMessage());
&&&&&&&&&&&&}
&&&&&&&&&}
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string update_pictrue(Stream getStream);
public string update_pictrue(Stream getStream)
&&&&&&&&&&&&Console.WriteLine("setData service has bean started!");
&&&&&&&&&&&&string uploadFolder = @"C:\kkk\";
&&&&&&&&&&&&string savaPath = "sss";
&&&&&&&&&&&&
&&&&&&&&&&&&string fileName ="ddd.mp4";
&&&&&&&&&&&&
&&&&&&&&&&&&FileStream targetStream = null;
&&&&&&&&&&&&if (!getStream.CanRead)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&throw new Exception("数据流不可读!");
&&&&&&&&&&&&}
&&&&&&&&&&&&if (savaPath == null) savaPath = @"Photo\";
&&&&&&&&&&&&if (!savaPath.EndsWith("\\")) savaPath += "\\";
&&&&&&&&&&&&uploadFolder = uploadFolder + savaP
&&&&&&&&&&&&if (!Directory.Exists(uploadFolder))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Directory.CreateDirectory(uploadFolder);
&&&&&&&&&&&&}
&&&&&&&&&&&&string filePath = bine(uploadFolder, fileName);
&&&&&&&&&&&&using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&const int bufferLen = 4096;
&&&&&&&&&&&&&&&&byte[] buffer = new byte[bufferLen];
&&&&&&&&&&&&&&&&int count = 0;
&&&&&&&&&&&&&&&&while ((count = getStream.Read(buffer, 0, bufferLen)) & 0)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&targetStream.Write(buffer, 0, count);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&targetStream.Close();
&&&&&&&&&&&&&&&&getStream.Close();
&&&&&&&&&&&&}
&&&&&&&&&&&&return "";
配置很重要必须支持大文件上传
&?xml version="1.0"?&
&configuration&
&&&&&system.serviceModel&
&&&&&&&behaviors&
&&&&&&&&&serviceBehaviors&
&&&&&&&&&&&behavior name="Host.ServiceBehavior"&
&&&&&&&&&&&&&serviceMetadata httpGetEnabled="true"/&
&&&&&&&&&&&&&serviceDebug includeExceptionDetailInFaults="false"/&
&&&&&&&&&&&&&dataContractSerializer maxItemsInObjectGraph=""/&
&&&&&&&&&&&/behavior&
&&&&&&&&&/serviceBehaviors&
&&&&&&&&&endpointBehaviors&
&&&&&&&&&&&behavior name="json"&
&&&&&&&&&&&&&enableWebScript /&
&&&&&&&&&&&/behavior&
&&&&&&&&&/endpointBehaviors&
&&&&&&&/behaviors&
&&&&&&&services&
&&&&&&&&&service name="Host.Service" behaviorConfiguration="Host.ServiceBehavior"&
&&&&&&&&&&&endpoint& binding="webHttpBinding" contract="Host.IService" behaviorConfiguration="json" bindingConfiguration="LargeBuffer"&
&&&&&&&&&&&identity&
&&&&&&&&&&&&&dns value="localhost"/&
&&&&&&&&&&&/identity&
&&&&&&&&&&&/endpoint&
&&&&&&&&&&&endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/&
&&&&&&&&&&&host&
&&&&&&&&&&&&&baseAddresses&
&&&&&&&&&&&&&&&add baseAddress=""/&
&&&&&&&&&&&&&/baseAddresses&
&&&&&&&&&&&/host&
&&&&&&&&&/service&
&&&&&&&/services&
&&&&&&&bindings&
&&&&&&&&&webHttpBinding&
&&&&&&&&&&&binding name="LargeBuffer"
&&&&&&&&&&maxBufferSize="" maxReceivedMessageSize=""&
&&&&&&&&&&&&&readerQuotas
&&&&&&&&&&&&maxStringContentLength="" maxArrayLength=""/&
&&&&&&&&&&&&&security mode="None"&&/security&
&&&&&&&&&&&/binding&
&&&&&&&&&/webHttpBinding&
&&&&&&&/bindings&
&&&&&/system.serviceModel&
&&&system.webServer&
&&&&&modules runAllManagedModulesForAllRequests="true"/&
&&&/system.webServer&
&startup&&supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/&&/startup&&/configuration&
阅读(...) 评论()随笔 - 690&
文章 - 8&评论 - 825&trackbacks - 19
当有大量的数据要传输(例如文件的上传和下载)时,WCF的流模式是比较好的选择,因为流模式不是全部传输完后才响应,而是一边读取一边传输消息,改善了系统的吞吐量和响应效率。
但是,WCF对于Stream操作有一些限制:
1. 绑定的限制。由于低层协议特性限制,WCF的流模式只支持如下四种:
BasicHttpBinding
NetTcpBinding
NetNamedPipeBinding
WebHttpBinding
2. OperationContract接口的限制。若要对数据进行流处理,服务的 OperationContract 必须满足两个要求:
最多只能有一个参数。
参数和返回值的类型中至少有一个必须是 Stream, Message 或 IXmlSerializable。
3. 会话模式限制。
  当InstanceContextMode设置为Single或PerSession的时,多个服务请求可能会使用同一数据通道。此时就无法实现并发下载,只能依次顺序执行,而这往往不是我们所期望的结果。因此,对于使用流模式的服务,需要将InstanceContextMode设置为PerCall。
如下是几个有效的示例:
&&&&[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]&&&&public
IstreamingSample&&&&{&&&&&&&&[OperationContract]&&&&&&&&Stream GetStream(string data);&&&&&&&&[OperationContract]&&&&&&&&bool UploadStream(Stream stream);&&&&&&&&[OperationContract]&&&&&&&&Stream EchoStream(Stream stream);&&&&&&&&[OperationContract]&&&&&&&&Stream GetReversedStream();&&&&}
如果有许多信息需要作为参数传递,可以使用MessageContract构造一个复杂点的消息。
&&&&[MessageContract]&&&&public
UploadStreamMessage&&&&{&&&&&&&&[MessageHeader]&&&&&&&&public
string&&&&&&&&[MessageBodyMember]&&&&&&&&public
Stream&&&&}
这个参数的限制并不难理解:
一次请求-响应之间只发送一个数据包,本质上来说只能携带一个参数。
在缓冲模式下,系统可以把多个参数全部加载到内存中后,然后通过序列化的方式将其合并为一个数据包再发送,这样看起来可以发送多个参数了。
流模式并不能使用这种方案,因此顶多只能发一个参数。要发多个参数,必须自己定义数据包格式(需要满足MessageContract),将多个参数整合到一个参数中发送。
下面我就以一个文件上传为例,简单的演示一下如何实现流模式数据传输。
一. 服务器端修改配置
设置TransferMode。它支持四种模式(Buffered、Streamed、StreamedRequest、StreamedResponse),请根据具体情况设置成三种Stream模式之一。
修改MaxReceivedMessageSize。该值默认大小为64k,因此,当传输数据大于64k时,则抛出CommunicationException异常。(可以直接设置为int.max)
修改receiveTimeout 和sendTimeout。大数据传送时间较长,需要修改这两个值,以免传输超时。
& &&&basicHttpBinding&&&&&& &&&binding
name="BasicBinding"
receiveTimeout="00:30:00"
sendTimeout="00:30:00"&maxReceivedMessageSize=""
transferMode="Streamed" /&& &&&/basicHttpBinding&
二. 定义契约,并实现服务
这个接口很简单,就是实现上传一个文件:
&&&&[ServiceContract]&&&&public
IService1&&&&{&&&&&&&&[OperationContract]&&&&&&&&Task UploadFile(Stream stream);&&&&}
由于接口中除了Stream没有其它的有限参数,我这里的实现也很简单,只是直接把它保存为1.jpg。
&&&&public
Service1 : IService1&&&&{&&&&&&&&public
Task UploadFile(Stream stream)&&&&&&&&{&&&&&&&&&&&&using (stream)&&&&&&&&&&&&using (var file = File.Create(@"R:\server\1.jpg"))&&&&&&&&&&&&{&&&&&&&&&&&&&&&&await stream.CopyToAsync(file);&&&&&&&&&&&&}&&&&&&&&}&&&&}
三. 访问服务
客户端的实现一如既往的简单,为了示例简单,这里客户端是以同步的方式访问的。
&&&&static
void Main(string[] args)&&&&{&&&&&&&&var client = new WcfClient.Service.Service1Client();&&&&&&&&using (var file = File.OpenRead(@"R:\client\1.jpg"))&&&&&&&&{&&&&&&&&&&&&client.UploadFile(file);&&&&&&&&}&&&&&&&&Console.WriteLine("finished");&&&&}
四. 扩展功能
前面的例子作为文件上传还是不够的,主要存在如下两个缺点:
不能指定文件名
不能获取上传进度
首先来解决文件名问题,不能指定文件名的主要原因就是消息体中对参数个数有限制,因此,必须把文件名和stream放在一起作为参数传入。这个只需要用MessageContract定义一个消息即可:
&&&&[MessageContract]&&&&public
UploadStreamMessage&&&&{&&&&&&&&[MessageHeader]&&&&&&&&public
string Name { get; set; }&&&&&&&&[MessageBodyMember]&&&&&&&&public
Stream Stream { get; set; }&&&&}
这样,把UploadStreamMessage作为参数,就可以携带文件名信息了。
&&&&[ServiceContract]&&&&public
IService1&&&&{&&&&&&&&[OperationContract]&&&&&&&&Task UploadFile(UploadStreamMessage msg);&&&&}&&&&public
Service1 : IService1&&&&{&&&&&&&&public
Task UploadFile(UploadStreamMessage msg)&&&&&&&&{&&&&&&&&&&&&using (msg.Stream)&&&&&&&&&&&&using (var file = File.Create(@"R:\server\"&+ msg.Name))&&&&&&&&&&&&{&&&&&&&&&&&&&&&&await msg.Stream.CopyToAsync(file);&&&&&&&&&&&&}&&&&&&&&}&&&&}
重新启动服务后,更新客户端,此时就会发现生成的代码中都把参数给分离出来了,非常贴心。
&&&&static
void Main(string[] args)&&&&{&&&&&&&&var client = new WcfClient.Service.Service1Client();&&&&&&&&using (var file = File.OpenRead(@"R:\client\1.jpg"))&&&&&&&&{&&&&&&&&&&&&client.UploadFile("test.jpg", file);&&&&&&&&}&&&&&&&&Console.WriteLine("finished");&&&&}
至于当前上传了多少数据,直接取一下FileStream的Position就可以了,就不用远程服务器提供接口了。
PS:关于大数据传输,流模式并非唯一选择,我这里也只是对流模式进行了蜻蜓点水般的介绍,更多信息可以参看MSDN的相关文章:1. ,2. 。CodeProject上的文章介绍得非常详细,强烈推荐一下。
阅读(...) 评论()

我要回帖

更多关于 wcf服务接收http请求 的文章

 

随机推荐