要使用网站上传文件,在ASP.NET的范畴,我基本上能想到的有两类,一类是通过HTTP POST请求获得文件信息,另外一类是通过WebService或者WCF之类的技术对外发布服务。

以前做3G摄像头项目的时候,做过使用HTTP POST的方式获得照片,方式很简单,就是一个aspx文件(其实用asp也行,最开始是用asp实现的,用aspx的时候还出了点幺蛾子),只是客户端(摄像头)那边需要了解POST请求,将图片做成数据传输上来。这个方式也没什么不好的,就是无奈在集成到系统中的时候总是出点问题,想着反正还要做多种客户端,于是乎改成第二类方式。

需求是要能够实现多个平台(PC,Android,iOS)的文件传输。

我说用WCF吧,之前我用来着,容易上手,但是其他人觉得WCF可能不太容易与非.NET平台互通(没深入探究,但是网上看到过有人用android调用WCF的,以后有时间再探讨),于是乎老老实实的用WebService。

Android调用webservice好像也有两种方式,我们实现的是用ksoap2调用,首先我需要编写WEBSERVICE。

文件用什么参数传递呢?

  1. 简单暴力byte[],使用File类或者FileStream类可以很容易将文件流汇入byte数组,直接传递。
  2. 不简单但是暴力string,使用某种方式将文件变成string,再进行传输。
  3. 其他方法,类似object?或者别的什么。

这里有序列化的知识,我还没深入体会,说说自己的看法吧:

首先序列化个人看来就是把对象什么的变得可以存储和传输,有了这个就能够很方便的实现一些网络应用。然后就是说KSOAP2对基本的数据类型都能够序列化,我看到string了,但是也不知道支持还是不支持byte[]型。

回到正题,干脆2个都来吧,反正也不差多少事。

由于自己有点疑虑,所以先实现了第二种,通过某种方式---base64编码解码。通过这个编码可以将BYTE变成能够直接网络传输的string,server端收到数据之后解码就能够得到原始byte[]。以下列出web端函数。

[WebMethod(MessageName = "UploadSmallString")]
public bool UploadSmallString(string fileName, string serializedData)
{
try
{
byte[] receivedBytes = Convert.FromBase64String(serializedData);
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
fs.Write(receivedBytes, 0, receivedBytes.Length);
}
return true;
}
catch
{
return false;
}
}

客户端用base64编码就可以了,网上找找很多。细心的客官可能看到函数名SmallString,对的,这个适用于文件不太大的时候传输,传输很大的文件呢?

分块!分块传输的好处在于能够支持断点续传,说说客户端的实现思路:

1.判断文件大小
2.是否适用于分块传输
3.调用服务进行操作

然后服务器端呢,写个重载吧,可是试了试不成功,参见http://www.cnblogs.com/menglin2010/archive/2012/03/29/2421445.html中说不太支持,要改,用[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]如果改成None用以支持重载的话,又怕出现兼容性问题,老老实实的吧还。

/// <summary>
/// 使用BASE64编码接收分块传输的大文件
/// </summary>
/// <param name="fileName">文件名</param>
/// <param name="serializedData">BASE64数据</param>
/// <param name="blockSerial">用以识别文件块的ID</param>
/// <returns>对应成功文件块ID,不成功便成-1</returns>
[WebMethod(MessageName = "UploadBlobString", Description = "支持大文件传输的方法,blockserial为0将创建新文件,这也是默认行为")]
public int UploadBlobString(string fileName, string serializedData, int blockSerial = 0)
{
try
{
byte[] receivedBytes = Convert.FromBase64String(serializedData);
if (blockSerial == 0)
{
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(fileName), FileMode.Create))
{
fs.Write(receivedBytes, 0, receivedBytes.Length);
}
}
else
{
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(fileName), FileMode.Append))
{
fs.Write(receivedBytes, 0, receivedBytes.Length);
}
}
return blockSerial;
}
catch
{
return -1;
}
}

琢磨了一下,好像这个完全可以替代前一个方法,是用.NET默认参数的特性,指定blockSerial默认为0。如果客户端中断了,续传的时候从断点blockSerial开始就OK了。

接下来说说第一种,使用bye[]的方式。

[WebMethod(MessageName = "UploadSmallByte", Description = "直接发送BYTE数组存储")]
public bool UploadSmallByte(string fileName, byte[] fileBytes)
{
try
{
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
fs.Write(fileBytes, 0, fileBytes.Length);
}
return true;
}
catch
{
return false;
}
}

这种方式我没怎么测试过,但是有一个有意思的事情,就是如果ANDROID编码BASE64后的string直接传递给byte[]参数,这个函数依然可以正常工作,上传的图片还是可以正常显示,很是诡异呀,想在.net下试一试,直接由于类型不同,不能编译,以后有机会再琢磨琢磨。

P.S. BASE64方式的代码经过测试能够在ANDROID平台和PC平台下通过,iOS等待BASE64实现(貌似没有内部的BASE64编码方法),从原理上应该没问题,欢迎大家讨论。

WebService支持多平台上传文件的实现的更多相关文章

  1. 采用Sambaserver由win平台,linux平台上传文件

    1.构造yum [root@db /]# cd /etc/yum.repos.d/ [root@db yum.repos.d]# vi yum.repo --改动光盘挂载位置,enabled设置为启动 ...

  2. 扩展 ajaxupload.js ,支持客户端判断上传文件的大小

    onSubmit: function(file, extension){}, 修改为 onSubmit: function(file, extension, size){}, if (! (setti ...

  3. 微信公众号平台上传文件返回错误代码:40005 invalid file type

    错误原因:文件类型(后缀名)不符合要求. 具体到笔者的情况是:在将 MultipartFile 类型转换为File 类型时,方法 File.createTempFile("filename& ...

  4. Ajax JQuery HTML 提交上传文件File HTML+ Ajax+ASP.NET+ WebService

    起因:公司最近有些项目用到了HTML+WebService的组合,发现访问速度等都快了许多,但是由于通过Ajax只能应付一些简单的文字类的传输,上传文件就捉襟见肘了,如果一直引用第三方的swf之类上传 ...

  5. 上传文件,使用FormData进行Ajax请求,jsoncallback跨域

    通过传统的form表单提交的方式上传文件: <form id= "uploadForm" action= "http://localhost:8080/cfJAX_ ...

  6. kindeditor在sae上传文件修改,适合php

    kindeditor在sae上传文件修改,适合php 当前位置: 首页  > 论坛  > 经验共享 用户登录   新用户注册   主题: kindeditor在sae上传文件修改,适合ph ...

  7. iframe无刷新跨域上传文件并获得返回值

    原文:http://geeksun.iteye.com/blog/1070607 需求:从S平台上传文件到R平台,上传成功后R平台返回给S平台一个值,S平台是在一个页面弹出的浮窗里上传文件,所以不能用 ...

  8. ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段

    ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...

  9. swagger上传文件并支持jwt认证

    背景 由于swagger不仅提供了自动实现接口文档的说明而且支持页面调试,告别postman等工具,无需开发人员手动写api文档,缩减开发成本得到大家广泛认可 但是由于swagger没有提供上传文件的 ...

随机推荐

  1. 在域信任环境中使用 Team Foundation Server (TFS 2013)

    原文:在域信任环境中使用 Team Foundation Server (TFS 2013) 1. 用户情景和方案: XX公司的大部分软件产品通过软件外包的方式由开发商完成.为加强对软件开发的进度和质 ...

  2. Matlab.NET混合编程调用Figure窗体

    原文:[原创]Matlab.NET混合编程调用Figure窗体 1.前言 做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用.特别是在C#调用M ...

  3. linux tar.gz zip 减压 压缩命令

    http://apps.hi.baidu.com/share/detail/37384818 download ADT link http://dl.google.com/android/ADT-0. ...

  4. 虚拟机安装麒麟3.2时报unkown filesystem,you need to load the linux kernel first

    工作的需要,安装在虚拟机上的麒麟3.2的64位版本号. 使用虚拟机VMware Workstation 9.0,依照常识目标DVD光盘文件的类型选择Other Linux 2.6.x Kernel 6 ...

  5. centos6.5 x86_64安装oracle 11.2.0.3grid

     centos6.5 x86_64安装oracle 11.2.0.3grid 1.安装前的准备 工作 1.1.配置node1 1.1.1.配置虚拟机并安装centos 安装node1----- 1 ...

  6. 如何使用Linq或EF来对数据去重——Distinct方法详解

    刚开始接触LINQ时使用distinct去重时和大家一样遇到了一些麻烦,很感谢 http://www.cnblogs.com/A_ming/archive/2013/05/24/3097062.htm ...

  7. 在VirtualBox安装OS X 10.10

    下面将指导介绍了如何引入自由和强大VirtualBox安装在虚拟机上OS X Yosemite 10.10 法律免责声明:本指南旨在说明如何在定期购买的苹果电脑上创建一个虚拟机执行真正的Mac OS ...

  8. Hibernate_10_继承的例子_单表

     只是建一个表,所有属性都包括在此表.使用discriminator 到父和子类之间的区别. 1)父类(Article): public class Article { private Integer ...

  9. 基础总结篇之五:BroadcastReceiver应用具体解释

    問渠那得清如許?為有源頭活水來.南宋.朱熹<觀書有感> 据说程序猿是最爱学习的群体,IT男都知道,这个行业日新月异,必须不断地学习新知识,不断地为自己注入新奇的血液,才干使自己跟上技术的步 ...

  10. Asp.net MVC + EF + Spring.Net 项目实践(四)

    这篇写一写如何使用Spring.net来解耦各个项目 1. 在接口层添加IStudentBLL文件,里面有GetStudent和GetAllStudents两个方法:然后在StudentBLL类里实现 ...