.NetCore相关知识点汇总(随笔,更新中....)

一.过滤器

1.如果一个web程序同时包含MVC和WebAPI,现在需要给WebAPI部分单独添加一个接口验证过滤器IActionFilter,注册全局过滤器的方式为:

services.AddControllers(o =>
            {
                // 全局过滤器
                o.Filters.Add(typeof(AccessControlFilter));
          //增加全局异常过滤器
          o.Filters.Add(typeof(GlobalExceptionsFilter)); })

 但是这样做会带来一个问题,那就是MVC部分控制器也会受影响,解决方法是实现ModelConvertion,常见的Convertion有

IApplicationModelConvention
IControllerModelConvention
IActionModelConvention
IParameterModelConvention
IPageRouteModelConvention

1.1-> 实现IControllerModelConvention

 

 1.2 ->实现IApplicationModelConvention

 

 

 那么如何把这个约定注册到应用中呢?在Microsoft.AspNetCore.MVC.MvcOptions中提供了Convertions属性:public IList<IApplicationModelConvention> Conventions;通过操作它就能把自定义约定注入进去

services.AddMvc(options =>
            {
                options.Filters.Add(typeof(GlobalExceptionFilter));
                options.Conventions.Add(new ApiControllerAuthorizeConvention());
            })

2..NetCore中AddMvc/AddMvcCore/AddControllers区别

service.AddMvc()包含的功能最为齐全,如下图

 

 2.全局异常过滤器:实现IExceptionFilter

using Hos.ScheduleMaster.Core;
using Hos.ScheduleMaster.Core.Log;
using Hos.ScheduleMaster.Web.Extension;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hos.ScheduleMaster.Web.Filters
{
    public class GlobalExceptionFilter : IExceptionFilter
    {
        private readonly IWebHostEnvironment _env;
        public GlobalExceptionFilter(IWebHostEnvironment env)
        {
            _env = env;
        }

        public void OnException(ExceptionContext context)
        {
            LogHelper.Error(context.HttpContext.Request.Path, context.Exception);
            if (context.HttpContext.Request.IsAjaxRequest())
            {
                var accept = context.HttpContext.Request.Headers["Accept"].FirstOrDefault();
                if (accept.Contains("application/json"))
                {
                    context.Result = new JsonNetResult()
                    {
                        Data = new { Success = false, Message = "服务出现异常请稍后再试!" }
                    };
                }
                else
                {
                    context.Result = new JavaScriptResult("alert('服务出现异常请稍后再试!')");
                }
          context.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable; }
else { context.Result = new RedirectResult("/Static/Page404"); } context.ExceptionHandled = true; } } }

针对web中包含MVC的页面请求,需要判断请求方式是否是ajax请求,代码如下

/// <summary>
        /// 判断是否异步请求
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static bool IsAjaxRequest(this Microsoft.AspNetCore.Http.HttpRequest request)
        {
            bool isAjax = false;
            var xreq = request.Headers.ContainsKey("x-requested-with");
            if (xreq)
            {
                isAjax = request.Headers["x-requested-with"] == "XMLHttpRequest";
            }
            return isAjax;
        }

JsonNetResult类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Hos.ScheduleMaster.Web.Extension
{
    /// <summary>
    /// 用json.net重写一个ControllerResult
    /// </summary>
    public class JsonNetResult : ActionResult
    {
        // 构造函数
        public JsonNetResult()
        {
            Settings = new JsonSerializerSettings
            {
                //忽略掉循环引用         
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                //设置时间格式
                DateFormatString = "yyyy-MM-dd HH:mm:ss",
                //不使用驼峰样式的key
                ContractResolver = new DefaultContractResolver()
            };
        }

        public override void ExecuteResult(ActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("ActionContext");
            }
            HttpResponse response = context.HttpContext.Response;
            response.ContentType = "application/json";
            if (this.Data != null)
            {
                response.WriteAsync(JsonConvert.SerializeObject(Data, Settings));
            }
        }

        public object Data { get; set; }

        public JsonSerializerSettings Settings { get; private set; }

    }

    /// <summary>
    /// 基于JsonNetResult直接在controller中返回json的扩展方法
    /// </summary>
    public static class JsonNetResultExtension
    {
        public static JsonNetResult JsonNet(this Controller controller, bool success, string msg = "", string url = "", object data = null)
        {
            return JsonNet(new { Success = success, Message = msg, Url = url, Data = data });
        }

        public static JsonNetResult JsonNet(this Controller controller, object data)
        {
            return JsonNet(data);
        }

        /// <summary>
        /// 创建JsonNetResult对象,输出json数据到客户端
        /// </summary>
        /// <param name="data"></param>
        /// <param name="contentType"></param>
        /// <param name="encoding"></param>
        /// <param name="behavior"></param>
        /// <returns></returns>
        private static JsonNetResult JsonNet(object data)
        {
            return new JsonNetResult()
            {
                Data = data
            };
        }
    }
}

JavaScriptResult类:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hos.ScheduleMaster.Web.Extension
{
    public class JavaScriptResult : ActionResult
    {
        public string Scripts;

        public JavaScriptResult()
        {

        }
        public JavaScriptResult(string scrpits)
        {
            this.Scripts = scrpits;
        }
        public override void ExecuteResult(ActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("ActionContext");
            }
            HttpResponse response = context.HttpContext.Response;
            response.ContentType = "application/javascript";
            response.WriteAsync(Scripts);
        }
    }

    public static class JavaScriptResultExtension
    {
        public static JavaScriptResult JavaScript(this Controller controller, string scripts)
        {
            return new JavaScriptResult(scripts);
        }
    }
}

 3.自定义授权认证

3.1 当使用默认的Authorize授权时,当项目中有实现IAuthorizationHandler接口时,会进行自定义的认证

 

 

 3.2 当使用策略授权时,,

 

 

 ,认证会走实现了IAuthorizationRequirement泛型的AuthorizationHandler

 

4.NET Core(C#) POST JSON数据和Form表单的方法

1、POST提交JSON格式数据

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string json = "{\"user\":\"test\"," +
                  "\"password\":\"bla\"}";
    streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    var result = streamReader.ReadToEnd();
}

2、POST提交Form表单数据

1) type为"application/x-www-form-urlencoded"类型的表单

/// <summary>
/// 执行POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="postData"></param>
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
/// <param name="headers">填充消息头</param>        
/// <returns></returns>
public static string HttpPost(string url, string paramData, Dictionary<string, string> headers = null, string contentType = "application/json", int timeOut = 30)
{
    using (HttpClient client = new HttpClient())
    {
        if (headers != null)
        {
            foreach (var header in headers)
                client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }
        using (HttpContent httpContent = new StringContent(paramData, Encoding.UTF8))
        {
            if (contentType != null)
                httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
            HttpResponseMessage response = client.PostAsync(url, httpContent).Result;
            return response.Content.ReadAsStringAsync().Result;
        }
    }
}

2) type为"multipart/form-data"类型的表单

public async Task<string> UploadFile(string filePath)
{
    if (string.IsNullOrWhiteSpace(filePath))
    {
        throw new ArgumentNullException(nameof(filePath));
    }
    if (!File.Exists(filePath))
    {
        throw new FileNotFoundException($"File [{filePath}] not found.");
    }
    using var form = new MultipartFormDataContent();
    using var fileContent = new ByteArrayContent(await File.ReadAllBytesAsync(filePath));
    fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
    form.Add(fileContent, "file", Path.GetFileName(filePath));
    //表单中其它参数
    form.Add(new StringContent("789"), "userId");
    form.Add(new StringContent("some comments"), "comment");
    form.Add(new StringContent("true"), "isPrimary");
    var response = await _httpClient.PostAsync($"{_url}/api/files", form);
    response.EnsureSuccessStatusCode();
    var responseContent = await response.Content.ReadAsStringAsync();
    var result = JsonSerializer.Deserialize<FileUploadResult>(responseContent);
    _logger.LogInformation("Uploading is complete.");
    return result.Guid;
}
posted @ 2021-07-23 18:26  可乐加冰-Mr-Wang  阅读(378)  评论(0编辑  收藏  举报