要使用网站上传文件,在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. C++“窗体”程序设计启蒙

    [摘要]本文以C++菜菜鸟(仅仅须要学习了C++数据类型和控制结构就可以)为目标读者,用求解一元二次方程作为实例,展示窗体式程序的开发过程,获得初步体验.写作目的包含:(1)让学生通过模仿,开发出类似 ...

  2. ABP展现层——动态生成WebApi

    ABP展现层——动态生成WebApi 点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerp ...

  3. lucene两个分页操作

    基于lucene两个分页: lucene3.5查询方式(每次查询所有记录,然后取当中部分记录.这样的方式用的最多),lucene官方的解释:因为我们的速度足够快. 处理海量数据时.内存easy内存溢出 ...

  4. redis权限认证(设置密码)的方法

    redis可以通过设置密码来增强安全强度.除了设置密码,我们还可以通过修改redis的默认端口.对端口做防火墙等.那么如何开启redis的密码功能呢?以下就是详细的步骤方法: 打开redis.conf ...

  5. Android而一个超级漂亮的日历控件

    ※效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluZ2xvbmd4aW4yNA==/font/5a6L5L2T/fontsize/400/fil ...

  6. HDU 2841 Visible Trees(数论)

    标题效果:给你个m*n方格,广场格从(1,1)开始. 在树中的每个点,然后让你(0,0)点往下看,问:你能看到几棵树. 解题思路:假设你的视线被后面的树和挡住的话以后在这条线上的树你是都看不见的啊.挡 ...

  7. HDU 4303 Hourai Jeweled 树dp 所有权利和航点 dfs2次要

    意甲冠军: long long ans = 0; for(int i = 1; i <= n; i++) for(int j = i+1; j <= n; j++) ans += F(i, ...

  8. Fireasy

    Fireasy与Asp.net MVC结合   Fireasy之前都是使用HttpService来为jquery ajax提供服务,这个HttpService实际上和MVC的原理机制是一样的,只是它支 ...

  9. hdu2191 悼念512汶川大地震遇难同胞——珍惜如今,感恩生活

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 Problem ...

  10. 收集的css布局

    1 <title>左定宽,右自动</title> 2 <style> 3 body{margin:0px;padding:0px;} 4 .box .left,.b ...