由于项目里需要用到在一个表单里使用文件和内容一起提交到服务端,因此需要进行处理。
前端:Vue2.0 Ant-desing
后端:.net WebAPI
界面如下:
页面代码:
<template>
<div class="clearfix" style="background-color:#ffffff;">
<a-form :form="form">
<a-form-item label="资源名称" has-feedback>
<a-input placeholder="请输入资源名称" v-decorator="['title']" />
</a-form-item>
<a-form-item label="资源描述" has-feedback>
<a-input placeholder="请输入资源描述" v-decorator="['description']" />
</a-form-item>
<a-form-item label="资源路径" has-feedback>
<a-input placeholder="请输入资源路径" v-decorator="['path']" />
<a-upload :file-list="fileList" :before-upload="beforeUpload"
v-decorator="[
'upload',
{
valuePropName: 'fileList1',
},
]"
> getValueFromEvent: normFile, name="upload"
<a-button> <a-icon type="upload" /> 请先择文件 </a-button>
</a-upload>
</a-form-item>
<a-form-item label="应用ID" >
<a-select style="width: 100%" placeholder="请选择应用ID" v-decorator="['projectAppId', {rules: [{ required: true, message: '请选择应用ID!' }]}]">
<a-select-option v-for="(item,index) in projectAppIdData" :key="index" :value="item.id">{{ item.title }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="资源类型" >
<a-select style="width: 100%" placeholder="请选择资源类型" v-decorator="['resourceType', {rules: [{ required: true, message: '请选择资源类型!' }]}]">
<a-select-option v-for="(item,index) in resourceTypeData" :key="index" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="版本号" has-feedback>
<a-input placeholder="请输入版本号" v-decorator="['versionId']" />
</a-form-item>
</a-form>
<a-button
type="primary"
:loading="uploading"
style="margin-top: 16px"
@click="handleSubmit"
>
{{ uploading ? 'Uploading' : 'Start Upload' }}
</a-button>
:disabled="fileList.length === 0"
</div>
</template>
<script>
import { axios } from '@/utils/request'
export default {
data() {
return {
fileList: [],
fileList1: [],
uploading: false,
form: this.$form.createForm(this),
projectAppIdData:[{id:1,title:'项目1'}],
resourceTypeData:[{id:1,name:'显示内容'}],
};
},
methods: {
handleRemove(file) {
debugger;
const index = this.fileList.indexOf(file);
const newFileList = this.fileList.slice();
newFileList.splice(index, 1);
this.fileList = newFileList;
},
beforeUpload(file) {
debugger;
this.fileList = [...this.fileList, file];
return false;
},
ProjectAppResourcePage (parameter) {
return axios({
url: '/api/projectappresourcemanager/upload-file',
method: 'post',
// headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: parameter
});
}
,
/**
* 提交表单
*/
handleSubmit () {
const { form: { validateFields } } = this
this.confirmLoading = true
validateFields((errors, values) => {
if (!errors) {
for (const key in values) {
if (typeof (values[key]) === 'object') {
values[key] = JSON.stringify(values[key])
}
}
console.log('form',values);
debugger;
const formData = new FormData();
this.fileList.forEach(file => {
formData.append('upload', file);
});
// Object.keys(values.upload).map(item => (
// formData.append(item, values.upload[item])
// ));
for(var v in values){
if(v!='upload'){
console.log(v+'+',values[v]);
formData.append(v, values[v]);
}
}
debugger;
this.ProjectAppResourcePage(formData).then((res) => {
if (res.success) {
this.$message.success('新增成功')
this.confirmLoading = false
this.$emit('ok', formData)
this.handleCancel()
} else {
this.$message.error('新增失败:' + JSON.stringify(res.message))
}
}).finally((res) => {
this.confirmLoading = false
})
} else {
this.confirmLoading = false
}
})
}
}
}
</script>
C#后端代码
/// <summary>
/// 项目资源管理
/// </summary>
[Route("api/[controller]")]
[ApiDescriptionSettings("11", Name = "ProjectAppResourceManager", Order = 11)]
public class ProjectAppResourceManager
{
/// <summary>
/// 上传文件
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<ProjectAppResourceAddResult>> UploadFile(
[FromForm(Name = "upload")] List<IFormFile> files,
[FromForm] ProjectAppResourceAdd projectAppResourceAdd
)
{
var ss = files;
var result = new List<ProjectAppResourceAddResult>();
return result;
}
}
public class obj
{
/// <summary>
/// 资源名称
/// </summary>
public string Title { get; set; }
/// <summary>
/// 资源描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 资源路径
/// </summary>
public string Path { get; set; }
/// <summary>
/// 应用ID
/// </summary>
public long ProjectAppId { get; set; }
/// <summary>
/// 资源类型,参考ResourceTypeEnum
/// </summary>
public short ResourceType { get; set; }
/// <summary>
/// 当前资源的版本信息
/// </summary>
public string VersionId { get; set; }
}
特别注意:
1.上传内容时一定要指定 [FromForm] 不然会报错
[FromForm(Name = upload)] List files,
[FromForm] obj projectAppResourceAdd
不指定 [FromForm] 报错415 Unsupported Media Type
asp.net WebApi RestFul接口 formdata 415 Unsupported Media Type
如下图:
指定formForm后Swagger正确显示
没增加FormForm特性的swagger错误显示
2.使用Ant-desing 的 a-upload上传文件需要在before-upload 中拦截获取到文件内容。然后再把文件内容通过 formdata 发送到后台。
<template>
<div class="clearfix">
<a-upload :file-list="fileList" :remove="handleRemove" :before-upload="beforeUpload">
<a-button> <a-icon type="upload" /> Select File </a-button>
</a-upload>
<a-button
type="primary"
:disabled="fileList.length === 0"
:loading="uploading"
style="margin-top: 16px"
@click="handleUpload"
>
{{ uploading ? 'Uploading' : 'Start Upload' }}
</a-button>
</div>
</template>
<script>
import reqwest from 'reqwest';
export default {
data() {
return {
fileList: [],
uploading: false,
};
},
methods: {
handleRemove(file) {
const index = this.fileList.indexOf(file);
const newFileList = this.fileList.slice();
newFileList.splice(index, 1);
this.fileList = newFileList;
},
beforeUpload(file) {
this.fileList = [...this.fileList, file];
return false;
},
handleUpload() {
const { fileList } = this;
const formData = new FormData();
fileList.forEach(file => {
formData.append('files[]', file);
});
this.uploading = true;
// You can use any AJAX library you like
axu({
url: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
method: 'post',
processData: false,
data: formData,
success: () => {
this.fileList = [];
this.uploading = false;
this.$message.success('upload successfully.');
},
error: () => {
this.uploading = false;
this.$message.error('upload failed.');
},
});
},
},
};
</script>
注意正常的客户端数据内容: