泛微OA调用发送消息接口 .Net C#示例

泛微OA调用接口步骤文档

泛微OA发送消息接口文档

详细步骤查看上面两个文档

泛微OA发送消息,只有java代码示例,这里整理了一套.Net版本的示例,仅供参考,目前写的可以调用,后期泛微接口做调整,本文章不做对应更新。

用的.Net Core 3.1框架,需要先依赖注入

cs 复制代码
private readonly string _appid = string.Empty;
private readonly string _ip = string.Empty;
private readonly string _cpk = string.Empty;
private readonly int _time = 1800;
private readonly string _code = string.Empty;
private readonly IRepository<Message, string> _messageRepository;
private readonly IRepository<MessageDetail, string> _messageDetailRepository;
private readonly IGuidGenerator _guidGenerator;
private readonly IObjectMapper _objectMapper;
private readonly MesMessageDbContext _mesMessageDbContext;
private readonly ILogger<MessageDetailService> _logger;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
private readonly IRepository<Appsetting, Guid> _appsettingRepository;

public MessageDetailService(
    IRepository<Message, string> messageRepository,
    IRepository<MessageDetail, string> messageDetailRepository,
    IGuidGenerator guidGenerator,
    IObjectMapper objectMapper,
    MesMessageDbContext mesMessageDbContext,
    ILogger<MessageDetailService> logger,
    IHttpClientFactory httpClientFactory,
    IConfiguration configuration,
    IRepository<Appsetting, Guid> appsettingRepository)
{
    _messageRepository = messageRepository;
    _messageDetailRepository = messageDetailRepository;
    _guidGenerator = guidGenerator;
    _objectMapper = objectMapper;
    _mesMessageDbContext = mesMessageDbContext;
    _logger = logger;
    _httpClientFactory = httpClientFactory;
    _configuration = configuration;
    _appid = configuration["OA:appid"];
    _ip = configuration["OA:ip"];
    _cpk = configuration["OA:cpk"];
    _time = Convert.ToInt32(configuration["OA:time"]);
    _code = configuration["OA:code"];
    _appsettingRepository = appsettingRepository;
}

第一步 获取spk

这里把spk和secret存到了数据库中

cs 复制代码
#region 第一步 获取spk
[UnitOfWork(true)]
private async Task<Result> GetSPKAsync()
{
    var path = "/api/ec/dev/auth/regist";
    Dictionary<string, string> headers = new Dictionary<string, string>();
    headers.Add("appid", _appid);
    headers.Add("cpk", _cpk);

    var resultMsg = await PostAsync(_ip + path, "", "", headers);
    var result = JsonConvert.DeserializeObject<Result>(resultMsg);
    if (result != null && result.status)
    {
        await _appsettingRepository.DeleteAsync(d => d.Code == "spk" || d.Code == "secret");
        AppsettingDto spkInDto = new AppsettingDto()
        {
            Code = "spk",
            Value = result.spk,
            CreateTime = DateTime.Now
        };
        var spkItem = _objectMapper.Map<AppsettingDto, Appsetting>(spkInDto);
        await _appsettingRepository.InsertAsync(spkItem);

        AppsettingDto secretInDto = new AppsettingDto()
        {
            Code = "secret",
            Value = result.secret,
            CreateTime = DateTime.Now
        };
        var secretItem = _objectMapper.Map<AppsettingDto, Appsetting>(secretInDto);
        await _appsettingRepository.InsertAsync(secretItem);
    }
    return result;
}
#endregion

第二步 获取token

cs 复制代码
#region 第二步 获取token
/// <summary>
/// 获取token
/// </summary>
/// <returns></returns>
public async Task<string> GetTokenAsync()
{
    var path = "/api/ec/dev/auth/applytoken";
    var spkValue = _appsettingRepository.FirstOrDefault(d => d.Code == "spk")?.Value;
    var secretValue = _appsettingRepository.FirstOrDefault(d => d.Code == "secret")?.Value;
    if (string.IsNullOrWhiteSpace(spkValue) || string.IsNullOrWhiteSpace(secretValue))
    {
        var spkResult = await GetSPKAsync();
        spkValue = spkResult.spk;
        secretValue = spkResult.secret;
    }
    var secret = RsaEncrypt(secretValue, spkValue);
    Dictionary<string, string> headers = new Dictionary<string, string>();
    headers.Add("appid", _appid);
    headers.Add("time", _time.ToString());
    headers.Add("secret", secret);

    var resultMsg = await PostAsync(_ip + path, "", "", headers);
    var result = JsonConvert.DeserializeObject<Result>(resultMsg);

    return await Task.FromResult(result.token);
}
#endregion

第三步 调用泛微接口发送消息

cs 复制代码
#region 第三步 调用泛微接口发送消息
public async Task<Result> SendMessageAsync(Content content)
{
    var path = "/api/ec/dev/message/sendCustomMessageSingle";
    var token = await GetTokenAsync();
    Dictionary<string, string> headers = new Dictionary<string, string>();
    headers.Add("token", token);
    headers.Add("appid", _appid);
    //headers.Add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
    headers.Add("skipsession", "1");

    //var parameter = JsonConvert.SerializeObject(content);
    Dictionary<string, string> data = new Dictionary<string, string>();
    data.Add(nameof(content.code), content.code);
    data.Add(nameof(content.userIdList), content.userIdList);
    data.Add(nameof(content.creater), content.creater);
    data.Add(nameof(content.title), content.title);
    data.Add(nameof(content.context), content.context);
    var resultMsg = await Post2Async(_ip + path, data,"", headers);

    //var data = $"code={content.code}&userIdList={content.userIdList}&creater={content.creater}&title={content.title}&context={content.context}";
    //var resultMsg = await Post3Async(_ip + path, data, headers);
    var result = JsonConvert.DeserializeObject<Result>(resultMsg);
    return result;
}
#endregion

http post请求

cs 复制代码
#region http post请求
/// <summary>
/// http post请求
/// </summary>
/// <param name="requestUri">地址</param>
/// <param name="parameter">入参</param>
/// <param name="token"></param>
/// <param name="headers">头信息</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private async Task<string> PostAsync(string requestUri, string parameter, string token, Dictionary<string, string> headers)
{
    try
    {
        var client = _httpClientFactory.CreateClient();
        var content = new StringContent(parameter, Encoding.UTF8, "application/json");
        // 添加token到请求头中
        if (token != null)
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }
        foreach (var header in headers)
        {
            client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }
        var response = await client.PostAsync(requestUri, content);
        string statusCode = ((int)response.StatusCode).ToString();
        response.EnsureSuccessStatusCode();
        string resultMsg = await response.Content.ReadAsStringAsync();
        _logger.LogWarning($"返回结果:{resultMsg},入参:{parameter}");
        return resultMsg;
        //result = JsonConvert.DeserializeObject<Result>(resultMsg);
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message, ex);
    }
}

private async Task<string> Post2Async(string requestUri, Dictionary<string, string> parameter, string token, Dictionary<string, string> headers)
{
    try
    {
        var client = _httpClientFactory.CreateClient();
        var content = new FormUrlEncodedContent(parameter);
        // 添加token到请求头中
        if (token != null)
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }
        foreach (var header in headers)
        {
            client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }
        var response = await client.PostAsync(requestUri, content);
        string statusCode = ((int)response.StatusCode).ToString();
        response.EnsureSuccessStatusCode();
        string resultMsg = await response.Content.ReadAsStringAsync();
        _logger.LogWarning($"返回结果:{resultMsg},入参:{parameter.ToJsonString()}");
        return resultMsg;
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message, ex);
    }
}

private async Task<string> Post3Async(string url, string parameter, Dictionary<string, string> headers)
{
    using (var client = new HttpClient())
    {
        //var data = new StringContent("param1=value1&param2=value2", Encoding.UTF8, "application/x-www-form-urlencoded");
        var data = new StringContent(parameter, Encoding.UTF8, "application/x-www-form-urlencoded");
        _logger.LogWarning($"data:{data.ToJsonString()};parameter:{parameter}");
        // 添加header参数
        //client.DefaultRequestHeaders.Add("Authorization", "Bearer your_token_here");
        foreach (var header in headers)
        {
            client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }
        _logger.LogWarning($"header:{client.DefaultRequestHeaders.ToJsonString()}");

        try
        {
            var response = await client.PostAsync(url, data);
            response.EnsureSuccessStatusCode();

            var responseBody = await response.Content.ReadAsStringAsync();
            return responseBody;
        }
        catch (HttpRequestException e)
        {
            throw new Exception(e.Message);
        }
    }
}
#endregion

RSA加密

cs 复制代码
#region RSA加密
/// <summary>
/// RSA加密
/// </summary>
/// <param name="content">需加密文本</param>
/// <param name="xmlpublickey">公钥</param>
/// <returns></returns>
private string RsaEncrypt(string content, string xmlpublickey)
{
    string encryptedcontent = string.Empty;
    using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
    {
        rSACryptoServiceProvider.FromXmlString(RSAPublicKeyBase64ToXml(xmlpublickey));
        byte[] encrypteddata = rSACryptoServiceProvider.Encrypt(Encoding.Default.GetBytes(content), false);
        encryptedcontent = Convert.ToBase64String(encrypteddata);
    }
    return encryptedcontent;
}

/// <summary>
/// Base64 编码字符串转 XML 字符串(公钥)
/// </summary>
/// <param name="publicKey"></param>
/// <returns></returns>
private static string RSAPublicKeyBase64ToXml(string publicKey)
{
    RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
    return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
                         Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                         Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}
#endregion

实体类 入参和出参

cs 复制代码
/// <summary>
/// OA返回结果
/// </summary>
public class Result
{
    public string msg { get; set; }
    public int code { get; set; }
    public string msgShowType { get; set; }
    public string secrit { get; set; }
    public string secret { get; set; }
    public bool status { get; set; }
    public string spk { get; set; }
    public string token {  get; set; }
}
/// <summary>
/// 发送消息入参
/// </summary>
public class Content
{
    /// <summary>
    /// 客户提供
    /// </summary>
    public string code { get; set; }
    /// <summary>
    /// 接收人OA系统id
    /// </summary>
    public string userIdList { get; set; }
    / <summary>
    / 登录名
    / </summary>
    //public string loginIdList { get; set; }
    / <summary>
    / 用户编号
    / </summary>
    //public string workCodeList { get; set; }
    / <summary>
    / 接收人姓名
    / </summary>
    //public string lastNameList { get; set; }
    /// <summary>
    /// 创建人 OA系统id/登录名/编号/姓名(对应接收人所传入的形式)
    /// </summary>
    public string creater { get; set; }
    /// <summary>
    /// 标题
    /// </summary>
    public string title { get; set; }
    /// <summary>
    /// 内容
    /// </summary>
    public string context { get; set; }
}
相关推荐
He BianGu4 小时前
笔记:TypeDescriptor和反射
c#
星河队长6 小时前
wpf界面和net web界面的相同和不同点
ui·c#
J-SL7 小时前
C#接口的一些坑
c#
lingxiao1688810 小时前
C#Modbus通信
服务器·开发语言·网络·c#
WineMonk10 小时前
ArcGIS Pro SDK (七)编辑 15 版本控制选项
arcgis·c#·gis·arcgis pro sdk
Eiceblue12 小时前
C# 验证PDF数字签名的有效性
pdf·c#·asp.net·.netcore·visual studio
c#上位机13 小时前
C#静态类与非静态类
java·开发语言·c#
danielli13 小时前
C# 用户权限界面的测试内容
c#·用户界面
token-go15 小时前
学习.NET 8 MiniApis入门
网络·学习·.net
V言微语15 小时前
2.5 C#视觉程序开发实例1----IO_Manager实现脉冲输出控制
java·开发语言·c#