uniapp跨域調用ASP.NET Core Web API

一、Web API跨域支持

因爲瀏覽器有CROS(跨域資源共享)的問題,所以我們開發的Web API接口需要添加跨域功能。

1. 在Startup.cs的ConfigureServices方法裏添加如下代碼:

 //支持跨域
services.AddCors(options =>
{
        options.AddPolicy("any", builder =>
        {
            builder
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader();
            //.AllowCredentials();  //指定處理cookie
        });
});

any爲策略名稱,可以自己起名。

2. 在Startup.cs的Configure方法裏添加如下代碼:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseStaticFiles();
app.UseCors("any"); 
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers().RequireCors("any");
});

注意,app.UseCors("any"); 必須放入app.UseRouting和app.UseEndpoints方法之間。

3. 在Controller裏啓用跨域,添加[EnableCors("any")],如下所示:

[EnableCors("any")]
[Route("api/[controller]")]
[ApiController]
public class RegInfoController : ControllerBase
{
    //省略控制器代碼
}

這樣將該Web API發佈到IIS,就可以支持跨域訪問該接口服務了。

 

二、uniapp跨域訪問

這裏我主要用到uniapp的兩個方法,uploadFile和request方法。具體的用法可以參考官方文檔:https://uniapp.dcloud.io/api/request/request.html 。

a. uploadFile示例:

uni.chooseImage({
	sourceType: sourceType[this.sourceTypeIndex],
	sizeType: sizeType[this.sizeTypeIndex],
	count4: this.imageList4.length + this.count4[this.countIndex4] > 1 ? 1 - this.imageList4.length : this.count4[this.countIndex4],
	success: (res) => {
        var size = res.tempFiles[0].size;
		console.log(size);

		if (size > 2097152) {
			uni.showToast({
				title: "圖片大小不能超過2M",
				icon: 'none',
				duration: 1000,
				mask: true
			});
			return
		}
						
		if(size < 100000){
			uni.showToast({
				title: "圖片大小不能少於100K",
				icon: 'none',
				duration: 1000,
				mask: true
			});
			return
		}

		this.imageList4 = this.imageList4.concat(res.tempFilePaths);
		uni.showLoading({
			title: '圖片上傳中'
		});
		var imageSrc = res.tempFilePaths[0]
		uni.uploadFile({
			url: 'http://ip:端口/api/RegInfo/UploadImage', 
			formData: {
				'd': 'Images4' //傳參到Web API
			},
			filePath: imageSrc,
			fileType: 'image',
			name: 'data',
			success: (res) => {
				console.log('uploadImage success, res is:', res.data)
				this.image4 = res.data
				uni.hideLoading();
				uni.showToast({
					title: '上傳成功',
					icon: 'success',
					duration: 1000,
					mask: true
				})
			},
			fail: (err) => {
				console.log('uploadImage fail', err);
				uni.showModal({
					content: err.errMsg,
					showCancel: false
				});
			}
		});
	},
	fail: (err) => {
		console.log("err: ", err);
		// #ifdef APP-PLUS
		if (err['code'] && err.code !== 0 && this.sourceTypeIndex === 2) {
			this.checkPermission(err.code);
		}
		// #endif
		// #ifdef MP
		if (err.errMsg.indexOf('cancel') !== '-1') {
			return;
		}
		uni.getSetting({
			success: (res) => {
				let authStatus = false;
				switch (this.sourceTypeIndex) {
					case 0:
						authStatus = res.authSetting['scope.camera'];
						break;
					case 1:
						authStatus = res.authSetting['scope.album'];
						break;
					case 2:
						authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
						break;
					default:
						break;
				}
				if (!authStatus) {
					uni.showModal({
						title: '授權失敗',
						content: 'Hello uni-app需要從您的相機或相冊獲取圖片,請在設置界面打開相關權限',
						success: (res) => {
							if (res.confirm) {
								uni.openSetting()
							}
						}
					})
				}
			}
		})
		// #endif
	}
})

後臺控制器方法接收上傳的圖片代碼片段:

[HttpPost("UploadImage")]
public string UploadImage()
{
    var file = Request.Form.Files[0];
    byte[] bytes = new byte[file.OpenReadStream().Length];
    file.OpenReadStream().Read(bytes, 0, bytes.Length);

    MemoryStream ms = new MemoryStream(bytes);
    Bitmap bitmap = new Bitmap(ms);

    string d = Request.Form["d"]; //類型對應不同的目錄
    string path = Directory.GetCurrentDirectory() + "/Images/" + d + "/" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
    bitmap.Save(path);
    ms.Close();
    bitmap.Dispose();
    return path; //返回路徑給uniapp,可保存該路徑到數據庫
}

b. request示例:

uni.request({
    url: 'https://xxx.xxx.xxx.xxx:8098/api/RegInfo/AddRegInfo', //僅爲示例,並非真實接口地址,前面的xxx爲服務器ip或者改成域名。
    data: {
        text1: 'text1',
        text2: 'text2'
    },
    success: (res) => {
        console.log(res.data);
        this.text = 'request success';
    }
});

這裏的參數data,裏面可以封裝成一個json對象傳給Web API後臺,後臺方法參數爲對象,該對象的屬性跟text1,text2對應即可,可自由設置這裏僅作演示。

後臺控制器方法接收代碼片段:

[HttpPost("AddRegInfo")]
public string AddRegInfo(RegInfo regInfo)
{
    using (_context as IDisposable)
    {
        _context.RegInfos.Add(regInfo); //_context爲EF數據庫操作對象
        int flag = _context.SaveChanges();
        return flag>0?"添加成功":"添加失敗";
    }
}

RegInfo類裏有兩個屬性Text1和Text2,分爲對應如上的text1和text2。

 

三、發佈到IIS的一些問題

1. .net core HTTP Error 500.31-Failed to load ASP.NET Core runtime錯誤

在服務器運行cmd,輸入dotnet --version,查看.net core版本號。在發佈Web API設置目標框架的時候,選擇匹配這個版本號的.NET Core版本即可。

2. .net core HTTP Error 500.30 -ANCM In-Process Handler Load Failure

a. 找到發佈過的Web API裏的web.config文件並將 hostingModel="InProcess" 配置結點刪除

b. 在IIS該應用的應用程序池中,打開啓用32位應用程序

c. 快速故障防護是否關閉

 

參考資料:

1. uniapp官方首頁: https://uniapp.dcloud.io/

2. 微軟官方Web API教程:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web-api?view=aspnetcore-6.0&tabs=visual-studio

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章