1、创建Api项目

我用的是VS2019 Core3.1 。打开Vs2019 创建Asp.Net Core Web应用程序命名CoreWebApi 创建选择API 在Controller文件夹下面添加一个Api控制器 FileUp,修改Api的路由  [Route("api/[controller]/[action]")] 这样就可以访问到具体的某一个了  写一个测试 api

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; namespace CoreWebApi.Controllers
{
[Route("api/[controller]/[action]")]//修改路由
//[Route("api/[controller]")]//默认路由
[ApiController]
public class FileUpController : ControllerBase
{
/// <summary>
/// 测试接口
/// </summary>
/// <returns></returns>
[HttpGet]
//[HttpGet,Route("Test")]//默认路由 public string Test()
{
return "这是测试接口";
}
}
}

写Api的时候一定要加上,请求方式  post、get 其他的暂时我没用到。默认的路由是被我注释的,修改一下 让他的访问时api / 控制器 / 方法名称。不改也可以,测试的接口就用注释的那个特性。然后运行项目,地址栏输入https://localhost:44376/api/FileUp/Test

2、上传文件接口

在FileUp里写一个上传文件的接口所有代码都在下,OutPut是一个输出的类,Dto里面是一些参数 应该都有看得懂。里面就是上传文件储存到服务器上 并没有数据库操作,需要的加上去就可以了。

注意:有些会加[Consumes("application/json")]//application/json//application/x-www-form-urlencoded 这样来验证媒体类型,这里我弄了好久才想起来我写了这个。因为文件上传怎么说呢,媒体类型肯定不会是Json之类的。我以前的Api就是在基础Api类里加了这个。给我弄了头皮发麻才看到

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using CoreWebApi.Models;
using Newtonsoft.Json;
using Microsoft.Extensions.Hosting;
using System.IO; namespace CoreWebApi.Controllers
{
[Route("api/[controller]/[action]")]//修改路由
//[Route("api/[controller]")]//默认路由
[ApiController]
public class FileUpController : ControllerBase
{
public IHostingEnvironment env;
public FileUpController(IHostingEnvironment _env)
{
env = _env;
}
/// <summary>
/// 测试接口
/// </summary>
/// <returns></returns>
[HttpGet]
//[HttpGet,Route("Test")]//默认路由 public string Test()
{
return "这是测试接口";
}
/// <summary>
/// 文件上传
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<OutPut> FileUp()
{
var ret = new OutPut();
try
{
//不能用FromBody
var dto = JsonConvert.DeserializeObject<ImagesDto>(Request.Form["ImageModelInfo"]);//文件类实体参数
var files = Request.Form.Files;//接收上传的文件,可能多个 看前台
if (files.Count > )
{
var path = env.ContentRootPath + @"/Uploads/Images/";//绝对路径
string dirPath = Path.Combine(path, dto.Type + "/");//绝对径路 储存文件路径的文件夹
if (!Directory.Exists(dirPath))//查看文件夹是否存在
Directory.CreateDirectory(dirPath);
var file = files.Where(x => true).FirstOrDefault();//只取多文件的一个
var fileNam = $"{Guid.NewGuid():N}_{file.FileName}";//新文件名
string snPath = $"{dirPath + fileNam}";//储存文件路径
using var stream = new FileStream(snPath, FileMode.Create);
await file.CopyToAsync(stream);
//次出还可以进行数据库操作 保存到数据库
ret = new OutPut { Code = , Msg = "上传成功", Success = true };
}
else//没有图片
{
ret = new OutPut { Code = , Msg = "请上传图片", Success = false };
}
}
catch (Exception ex)
{
ret = new OutPut { Code = , Msg = $"异常:{ex.Message}", Success = false };
}
return ret;
}
}
}

Dto与返回的类

 /// <summary>
/// 返回输出类
/// </summary>
public class OutPut
{
/// <summary>
/// 状态码
/// </summary>
public int Code { get; set; }
/// <summary>
/// 消息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 是否成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 返回数据
/// </summary>
public object Data { get; set; }
}
/// <summary>
/// 接收参数Dto
/// </summary>
public class ImagesDto
{
/// <summary>
/// ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 地址
/// </summary>
public string Url { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary>
///
/// </summary>
public int RelationId { get; set; }
/// <summary>
/// 类型
/// </summary>
public int Type { get; set; }
}

3、前台Ajax调用

我在一个MVC程序里面用了个Ajax调用  下面是前端代码,contentType这个资源的类型我转载着坑里好久了,哈哈。

@{
ViewBag.Title = "测试";
} <h2>文件上传测试</h2>
<form enctype="multipart/form-data" id="formData">
<div>
<br /><br /><br />
文件:<input type="file" id="filesp" name="filesp" /><br /><br />
名称:<input type="text" id="fileName" name="fileName" /><br /><br />
备注:<input type="text" id="txtRemake" name="txtRemake" /><br /><br />
RelationId:<input type="number" id="txtRelationId" name="txtRelationId" /><br /><br />
类型:<select id="selType" name="selType">
<option value="1">动物</option>
<option value="2">植物</option>
<option value="3">妹子</option>
<option value="3">风景</option>
<option value="4">滑稽</option>
<option value="100">其他</option>
</select>
<br /><br />
<input type="button" id="btnSave" name="btnSave" value="提交" />
</div>
</form> <script src="~/Scripts/jquery-3.3.1.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnSave").click(function () {
var data = new FormData(document.getElementById("formData"));
//参数
var parame = JSON.stringify({ Name: $("#fileName").val(), Remark: $("#txtRemake").val(), Type: $("#selType").val(), RelationId: $("#txtRelationId").val() });
data.append("ImageModelInfo", parame);
$.ajax({
type: "post",
url: "https://localhost:44376/api/FileUp/FileUp",
dataType: "json",
data: data,
async: true,
contentType: false,//实体头部用于指示资源的MIME类型 media type 。这里要为false
processData: false,//processData 默认为true,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
success: function (data) {
console.log(data);
},
error: function (data) {
console.log("错误" + data);
}
});
});
});
</script>

运行起来看看 测试一下  ,Api那边也打好断点。打来浏览器调式就是很熟悉的bug就来了(一天看不到出错仿佛心里不踏实)

很明显的CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。所以这里我们就要允许前端来访问,从而就要在Api增加跨域;

4、跨域设置

在Startup.cs下面的ConfigureServices 中标添加services.AddCors(option => option.AddPolicy("AllowCors", bu => bu.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()));

 public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//跨域
services.AddCors(option => option.AddPolicy("AllowCors", bu => bu.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()));
}

AllowAnyOrigin  :允许CORS请求从任何源来访问,这是不安全的
AllowAnyHeader:允许所有的请求头

AllowCredentials :服务端也需要允许证书。
AllowAnyMethod允许跨域策略允许所有的方法:GET/POST/PUT/DELETE 等方法 如果进行限制需要 AllowAnyMethod("GET","POST") 这样来进行访问方法的限制


在Configure中添加中间件app.UseCors("AllowCors");,集体要限制哪些看个人了

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); //跨域
app.UseCors("AllowCors");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
}); }
现在就配置好了在需要跨域的地方加上特性[EnableCors("AllowCors")]就行了 ,引用命名空间using Microsoft.AspNetCore.Cors;
    [EnableCors("AllowCors")]
[Route("api/[controller]/[action]")]//修改路由
//[Route("api/[controller]")]//默认路由
[ApiController]
public class FileUpController : ControllerBase
{
public IHostingEnvironment env;
public FileUpController(IHostingEnvironment _env)
{
env = _env;
}
/// <summary>
/// 测试接口
/// </summary>
/// <returns></returns>
[HttpGet]
//[HttpGet,Route("Test")]//默认路由 public string Test()
{
return "这是测试接口";
}

现在再来调用就解决了

前台结果看看。文件夹也创建了。

5、总结

如果所有Api都要跨域的话就建立一个基础的Api 让所有的都继承这个Api,就需要打赏跨域的标签就可以了;

文件上传还可以用From直接提交这边用List<IFormFile>接收,也可以像FromBady一样的一个来接收搞,单词 忘了0.0,参数不能FermBody接收,这样文件就没了。

纸上得来终觉浅,觉知这事不写还是不行哈。

原文链接:https://www.cnblogs.com/w5942066/p/12762076.html

Asp.Net Core 3.0 学习3、Web Api 文件上传 Ajax请求以及跨域问题的更多相关文章

  1. Asp.Net Core 轻松学-一行代码搞定文件上传 JSONHelper

    Asp.Net Core 轻松学-一行代码搞定文件上传   前言     在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建 ...

  2. 用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传

    第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三 ...

  3. Asp.Net Core 轻松学-一行代码搞定文件上传

    前言     在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建自定义绑定模型来实现文件上传. 1. 实现自定义绑定模型 1 ...

  4. asp.net web api 文件上传

    1正确的做法 public class AvaterController : BaseApiController { [HttpPost] public async Task<IHttpActi ...

  5. ios网络学习------11 原生API文件上传之断点续传思路

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmcyMDA5MzAzNTEz/font/5a6L5L2T/fontsize/400/fill/I0 ...

  6. ios网络学习------10 原生API文件上传

    使用原生态的api上传文件的实现: #import "MainViewController.h" @interface MainViewController () @propert ...

  7. 一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

    不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.superviso ...

  8. Asp.Net Core Web Api图片上传(一)集成MongoDB存储实例教程

    Asp.Net Core Web Api图片上传及MongoDB存储实例教程(一) 图片或者文件上传相信大家在开发中应该都会用到吧,有的时候还要对图片生成缩略图.那么如何在Asp.Net Core W ...

  9. 使用Http-Repl工具测试ASP.NET Core 2.2中的Web Api项目

    今天,Visual Studio中没有内置工具来测试WEB API.使用浏览器,只能测试http GET请求.您需要使用Postman,SoapUI,Fiddler或Swagger等第三方工具来执行W ...

随机推荐

  1. Hadoop调度器

    一.FIFO调度器(先进先出调度) 上图为FIFO调度器的执行过程示意图.FIFO Scheduler是最简单也是最容易理解的调度器,它缺点是不适用于共享集群.大的应用可能会占用所有集群资源,这就导致 ...

  2. .NET Core 3 WPF MVVM框架 Prism系列之区域管理器

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用区域管理器对于View的管理 一.区域管理器 我们在之前的Prism系列构建了一个标准式Prism项目,这篇文章将会讲解之前项 ...

  3. JavaScript的URLSearchParams方法

    URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串. 一个实现了 URLSearchParams 的对象可以直接用在 for…of 结构中,不需要使用 entries ...

  4. Lack of free swap space on Zabbix server

    在模板(Template)里找到Linux OS模板,修改触发器 配置>模板>Template OS Linux>触发器 找到swap关键字 修改 {Template OS Linu ...

  5. XCode8 安装模拟器

    1.下载模拟器 参考:http://blog.csdn.net/piratest/article/details/52538978 参考:http://blog.csdn.net/zhangao008 ...

  6. 多线程学习笔记(四)---- Thread类的其他方法介绍

    一.wait和 sleep的区别 wait可以指定时间也可以不指定时间,而sleep必须指定时间: 在同步中时,对cpu的执行权和锁的处理不同: wait:释放执行权,释放锁:释放锁是为了别人noti ...

  7. touch方向锁定

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  8. 1029 Median (25分)

    Given an increasing sequence S of N integers, the median is the number at the middle position. For e ...

  9. 1015 Reversible Primes (20 分)

    A reversible prime in any number system is a prime whose "reverse" in that number system i ...

  10. 以数字资产模型为核心驱动的一站式IoT数据分析实践

    [摘要] 一个不会直播的云服务架构师,不是一个好的攻城狮! 在这个全民直播的时代 一个不会直播的云服务架构师 不是一个好的攻城狮 3月23日15:00-15:50,华为云IoT物联网数据分析服务架构师 ...