Api服务代码一:
/// <summary>
/// 服务器接收接口
/// </summary>
[HttpPost]
[Route("ReceiveFile")]
public HttpResponseMessage ReceiveFile()
{
string result = string.Empty;
ArrayList list = new ArrayList();
try
{
Stream postStream = HttpContext.Current.Request.InputStream;
byte[] b = new byte[postStream.Length];
string postFileName = DNTRequest.GetString("fileName");
if (string.IsNullOrEmpty(postFileName) && HttpContext.Current.Request["fileName"] != null)
{
postFileName = HttpContext.Current.Request["fileName"];
}
string fileExtension = Path.GetExtension(postFileName);
string dirName = "other";
if (!string.IsNullOrEmpty(fileExtension))
{
dirName = fileExtension.Substring(fileExtension.LastIndexOf(".") + 1);
}
string dir = "/_temp/file/" + dirName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/";
string fileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff");
fileName += fileExtension;
string filePath = HttpContext.Current.Server.MapPath(dir);
string saveFilePath = Path.Combine(filePath, fileName);
string dirPath = dir + fileName;
list.Add(dirPath);
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
FileStream fs = new FileStream(saveFilePath, FileMode.Create);
byte[] new_b = new byte[1024];
const int rbuffer = 1024;
while (postStream.Read(new_b, 0, rbuffer) != 0)
{
fs.Write(new_b, 0, rbuffer);
}
postStream.Close();
fs.Close();
fs.Dispose();
if (list.Count > 0)
{
result = DNTRequest.GetResultJson(true, "success", string.Join(",", list.ToArray()));
}
}
catch (Exception ex)
{
result = DNTRequest.GetResultJson(false, ex.Message, null);
}
HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "text/plain") };
return responseMessage;
}
Api服务代码二:
[HttpPost]
[Route("ReceiveFileTest")]
public HttpResponseMessage ReceiveFileTest()
{
string result = string.Empty;
var request = HttpContext.Current.Request;
try
{
if (request.Files.Count > 0)
{
var fileNameList = new List<string>();
string dirName = "other";
foreach (string f in request.Files)
{
var file = request.Files[f];
string fileExtension = Path.GetExtension(file.FileName).ToLower();
string fileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff");
fileName += fileExtension;
if (!string.IsNullOrEmpty(fileExtension))
{
dirName = fileExtension.Substring(fileExtension.LastIndexOf(".") + 1);
}
string dir = "/_temp/file/" + dirName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/";
string filePath = HttpContext.Current.Server.MapPath(dir);
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
string fileSavePath = Path.Combine(filePath, fileName);
Stream postStream = file.InputStream;
//
FileStream fs = new FileStream(fileSavePath, FileMode.Create);
byte[] new_b = new byte[1024];
const int rbuffer = 1024;
while (postStream.Read(new_b, 0, rbuffer) != 0)
{
fs.Write(new_b, 0, rbuffer);
}
postStream.Close();
fs.Close();
fs.Dispose();
string dirPath = dir + fileName;
fileNameList.Add(dirPath);
fileNameList.Add(fileName);
}
result = DNTRequest.GetResultJson(true, string.Format("{0}:{1}", HttpStatusCode.OK, string.Join(",", fileNameList.ToArray())), null);
}
else
{
result = DNTRequest.GetResultJson(false, "请选择上传的文件", null);
}
}
catch (Exception ex)
{
result = DNTRequest.GetResultJson(false, ex.Message, null);
}
HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "text/plain") };
return responseMessage;
}
Ajax提交file代码,调用Api代码一的Script:
此方法后端Api代码一中始终获取不到文件名,所以我在Ajax的url中加了?fileName=fileObj.name,这样调试能走通。为什么Ajax提交时不能获取到文件名,我还在研究。
<script>
$("#inpSubmit").click(function () {
//var fileObj = new FormData($("#importModel")[0]);
var fileObj = document.getElementById("inpFileControl").files[0];
if (typeof (fileObj) == "undefined" || fileObj.size <= 0) {
alert("请选择文件");
return;
}
//console.log(fileObj);
var formFile = new FormData();
formFile.append("fileName", fileObj.name);
formFile.append("file", fileObj);
//console.log(JSON.stringify(formFile));
//var paramters = {};
//paramters.timestamp = new Date().getTime();
//paramters.fileName = fileObj.name;
//paramters.file = fileObj;
//console.log(JSON.stringify(paramters));
$.ajax({
type: "post",
url: "http://localhost:19420/Api/ReceiveFile?fileName=" + fileObj.name,
dataType: "json",
//contentType: false,
processData: false,//用于对data参数进行序列化处理,默认值是true。默认情况下发送的数据将被转换为对象,如果不希望把File转换,需要设置为false
cache: false,
data: fileObj,
success: function (json) {
if (json.result) {
$("#inpFileUrl").val(json.data);
console.log(json.data);
}
else {
alert(json.msg);
}
},
error: function (ret) {
console.log(ret.responseText);
}
});
return false;
});
</script>
Ajax提交file代码,调用Api代码一的Html:
<form>
<fieldset>
<legend>Ajax提交到远程服务器Api</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="ds_host">选择文件</label>
<div class="col-sm-4">
<input class="form-control" id="inpFileUrl" name="inpFileUrl" type="text" placeholder="上传后返回地址" />
</div>
<div class="col-sm-4">
<input type="file" id="inpFileControl" name="file" />
</div>
<div class="col-sm-2">
<input id="inpSubmit" name="inpSubmit" type="button" value="提交" />
</div>
</div>
</fieldset>
</form>
Form表单提交Post到远程Api代码二中,这个很顺利。下边是Html
<form action="http://localhost:19420/Api/ReceiveFileTest" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Form表单提交到远程服务器Api</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="ds_host">选择文件</label>
<div class="col-sm-4">
<input class="form-control" id="inpFileUrl2" name="inpFileUrl2" type="text" placeholder="上传后返回地址" />
</div>
<div class="col-sm-4">
<input type="file" name="file" />
</div>
<div class="col-sm-2">
<input type="submit" value="提交" />
</div>
</div>
</fieldset>
</form>
Api服务部署时需要考虑到客户端提交file时有跨域问题,快捷方法是在IIS中设置Access-Control-Allow-Origin:*,但这样做有安全问题。
网站上传文件大小默认4M,所以网站配置文件中需要设置,如下:
<system.web>
<httpRuntime maxRequestLength="409600" />
</system.web>
服务器IIS上传文件大小也有限制,也要做设置,如下:
<system.webServer>
<security>
<requestFiltering>
<!--2G/2072576000|500M/518144000-->
<requestLimits maxAllowedContentLength="518144000"/>
</requestFiltering>
</security>
</system.webServer>
以上是我近2天的研究成果,不算完善还需要改进。
Api中使用了三方框架RestSharp,请在解决方案中找NuGet添加。
外部操作类用到的方法有,一:
/// <summary>
/// 拼装JSON
/// </summary>
static public string GetResultJson(bool result, string msg, Object data)
{
string resultJson = string.Empty;
Hashtable ht = new Hashtable();
try
{
ht.Add("result", result);
ht.Add("msg", msg);
ht.Add("data", data);
}
catch (Exception ex)
{
ht.Add("result", false);
ht.Add("msg", ex.Message);
}
resultJson = Newtonsoft.Json.JsonConvert.SerializeObject(ht);
return resultJson;
}
注意:Html代码中file控件需要有name=“file”属性,否则提交后Api获取不到file对象,如下。
<input type="file" name="file" />
第三种方法是form表单提交调用mvc的control,control在调用Api代码二,这个测试失败,能上传文件,但上传的文件不能打开是损坏的,正在想办法解决。
下边是第三种方法的Html代码:
<form action="/Test/UploadFileTest" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Form表单提交到本地Control</legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="ds_host">选择文件</label>
<div class="col-sm-4">
<input class="form-control" id="inpFileUrl3" name="inpFileUrl3" type="text" placeholder="上传后返回地址" />
</div>
<div class="col-sm-4">
<input type="file" name="file" />
</div>
<div class="col-sm-2">
<input type="submit" value="提交" />
</div>
</div>
</fieldset>
</form>
下边是第三种方法的Control代码:
[HttpPost]
public ActionResult UploadFileTest()
{
string result = string.Empty;
string apiUrl = "http://localhost:19420/Api/ReceiveFileTest";
string contentType = "application/octet-stream";
var files = new List<string>();
foreach (string f in Request.Files)
{
var file = Request.Files[f];
var request = new RestRequest(Method.POST);
request.AlwaysMultipartFormData = true;
//request.AddParameter("fileName", file.FileName);
Stream postStream = file.InputStream;
byte[] b = new byte[postStream.Length];
request.AddFile("file", b, file.FileName, contentType);
var restClient = new RestClient { BaseUrl = new Uri(apiUrl) };
string res = string.Empty;
IRestResponse<Object> response = restClient.Execute<Object>(request);
if (response.StatusCode == HttpStatusCode.OK)
{
res = response.Content;
}
else
{
res = string.Format("{0}:{1}", response.StatusCode, response.Content);
}
files.Add(res);
}
if (files.Count > 0) {
result = string.Join(",", files.ToArray());
}
return Json(result);
}
来源:oschina
链接:https://my.oschina.net/u/4414407/blog/4257216