第58章 elmentUI Upload组件通过IFormFile参数上传注意事项

1 重构Framework.Infrastructure.Middleware. CorsExceptionHandlerMiddleware. InvokeAsync

    /// name="context">HTTP上下文实例。

        ///

        /// 【异步调用】

        ///

        /// 摘要:

        ///    通过该方法向.Net(Core)框架内置管道中集成当前管道中间件,集中解决在由vue/uni-app前端项目跨域(Cors)访问当前后端项目时,浏览器或App中出现的异常:

        ///    1“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

        ///    2“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

        ///    3“has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”

        ///

        ///

        public async Task InvokeAsync(HttpContext context)

        {

            //解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:

            //“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

            if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Headers"))

            {

                context.Response.Headers.Add("Access-Control-Allow-Headers", "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization");

            }

            if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Methods"))

            {

                context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS");

            }

            //解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:

            //“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

            if (!context.Response.Headers.ContainsKey("Access-Control-Allow-Origin"))

            {

                context.Response.Headers.Add("Access-Control-Allow-Origin", "*");

            }

            if (context.Request.Headers.ContainsKey(CorsConstants.Origin))

            {

                //解决在前端通过“axios.post”方式调用后端POST-API,如果前端“axios.post”方法没有加载“headers”参数实例,下1行语句中的配置,否则“axios.post”方法,访问后端的POST-API,否则会出现:"HTTP:415"错误。

                //context.Request.ContentType = "application/json";

                //在使用“elmentUI”前端时“context.Request.ContentType”的实例值会为:null,所以必须包含:“context.Request.ContentType == null”

                if (context.Request.ContentType == null || !context.Request.ContentType.Contains("multipart/form-data"))

                    context.Request.ContentType = "application/json";

                //解决在由Hbuilder创建的前端Xuni-app项目(Cors)访问当前后端项目时,浏览器或App中会出现异常:

                //“' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.”

                if (context.Request.Method.Equals("OPTIONS"))

                {

                    context.Response.StatusCode = StatusCodes.Status200OK;

                    return;

                }

            }

            await _next(context);

        }

2 重构WebApi.Controllers. CustomerController. PostAvatarStream

/// name="customerId">1个指定的长整型值。

        /// name="formFile">1个指定的上传文件的实例。

        ///

        /// 【上传单个文件--无需权限】

        ///

        ///

        /// 摘要:

        ///     1个指定的上传文件从客户端上传到服务器端的指定目录中。

        /// 说明(elmentUI Upload组件)

        ///   1、如果使用头属性字典传递customerId参数实例,则不用使用“[FromForm]”标记,

        /// URL为:this.actionRequestUrl = "https://localhost:7239/Customer/PostAvatarStream?customerId=" + this.formUser.id;

        ///   2、如果使用“:data”传递customerId参数实例,则必须使用“[FromForm]”标记,否则customerId参数实例会一直为:0

        /// URL为:this.actionRequestUrl = "https://localhost:7239/Customer/PostAvatarStream"

        ///

        ///

        /// 返回:

        ///     1个指定的上传文件上传操作后的状态信息。

        ///

        [HttpPost]

        public async Task<IActionResult> PostAvatarStream([FromForm] long customerId, /*IFormCollection collection [FromForm]*/ IFormFile formFile)

        {

           Customer _customer = await _customerService.GetCustomerByIdAsync(customerId);

            if (_customer != null && formFile != null)

            {

                if(!string.IsNullOrEmpty(_customer.Avatar)&&!_nopFileProvider.GetFileName(_customer.Avatar).Equals("Default.jpg"))

                {

                    //去除网络格式路径字符中的第一个字符“~/”

                    _customer.Avatar = _customer.Avatar.Replace("~/", string.Empty).TrimStart('/');

                    //去除网络格式路径字符中的最后一个字符“/”

                    var pathEnd = _customer.Avatar.EndsWith('/') ? Path.DirectorySeparatorChar.ToString() : string.Empty;

                    //通过拼接操作,拼接出与之相对应的1个本地格式的路径字符串。

                    string _avatarPath = _nopFileProvider.Combine(_nopFileProvider.WebRootPath ?? string.Empty, _customer.Avatar) + pathEnd;

                    _nopFileProvider.DeleteFile(_avatarPath);

                }

                string _filename = Guid.NewGuid().ToString() + _nopFileProvider.GetFileExtension(formFile.FileName);

                string _path = _nopFileProvider.Combine(_nopFileProvider.WebRootPath, @"\images\Avatar\", _filename);

                using FileStream fileStream = new FileStream(_path, FileMode.Create);

                await formFile.CopyToAsync(fileStream);

                _customer.Avatar = "/images/Avatar/" + _filename;

                await _customerService.UpdateCustomerAsync(_customer);

                return Created(WebUtility.UrlEncode(_customer.Avatar), _customer);

            }

            return BadRequest();

        }

3  \src\components\Users\ EditUser.vue

        :model="formUser" label-width="100px" class="demo-ruleForm" label-position="left" status-icon>

           

            v-model:file-list="fileList" class="upload-demo" list-type="picture" :action="actionRequestUrl"

                name="formFile" :before-upload="beforeUpload" :on-change="onUploadChange" :data="paramData">

                type="primary">点击上传

           

            label="编号:" prop="id">

                v-model="formUser.id" disabled />

           

            label="名称:" prop="name">

                v-model="formUser.name" />

           

            label="邮箱:" prop="email">

                v-model="formUser.email" />

           

            label="手机号:" prop="phone">

                v-model="formUser.phone" />

           

            label="头像:" prop="avatar">

                v-model="formUser.avatar" />

           

           

            label="系统帐户:" prop="isSystemAccount">

                v-model="formUser.isSystemAccount" style="width: 100%;">

                    label="系统帐户" :value="true" />

                    label="其它" :value="false" />

               

           

            label="激活:" prop="isActive">

                v-model="formUser.isActive" style="width: 100%;">

                    label="激活" :value="true" />

                    label="禁用" :value="false" />

               

           

            label="可用:" prop="deleted">

                v-model="formUser.deleted" style="width: 100%;">

                    label="已被删除" :value="true" />

                    label="可用" :value="false" />

               

           

       

        #footer>

            class="dialog-footer">

                @click="this.formUser.centerDialogVisible = false">

                type="primary">

           

       

   

scoped lang="scss">

    .my-header {

        display: flex;

        flex-direction: row;

        justify-content: space-between;

    }

对以上功能更为具体实现和注释见:230406_015shopvue(elmentUI Upload组件通过IFormFile参数上传注意事项)。

你可能感兴趣的:(一步一步前后端开发实现,html,vue3,HBuilderX,前后端分离,商城)