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

泛微OA调用接口步骤文档

泛微OA发送消息接口文档

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

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

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

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存到了数据库中

#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

#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

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

#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请求

#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加密

#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

实体类 入参和出参

/// <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; }
}

### 如何使用C#调用OA系统API #### 使用WebService接口进行文档管理操作 对于ecology9.0文档(DocService)的WebService接口,可以通过如下方式利用C#来完成基本的操作,比如上传、下载以及删除文件。首先需引入System.Web.Services命名空间以便于访问Web服务[^1]。 ```csharp using System; using System.Web.Services; // 定义客户端程序集中的代理类用于连接到WebService public class DocServiceClient : WebClient { private readonly string _serviceUrl; public DocServiceClient(string serviceUrl) { this._serviceUrl = serviceUrl; } // 实现具体的功能函数,例如上传文件 } ``` 为了确保能够正确执行上述动作,应当遵循官方提供的参数定义与返回值解析指南,这有助于开发者构建有效的请求并处理响应结果。 #### 发送消息OA平台 当涉及到向OA发送通知或消息时,则可参照已有的.NET框架下的实践案例来进行开发。下面给出一段简化版的消息推送代码片段: ```csharp using System; using System.Net.Http; using Newtonsoft.Json.Linq; class Program { static async Task Main() { using (var client = new HttpClient()) { var content = new StringContent(JsonConvert.SerializeObject(new { title = "Test Title", message = "This is a test message." }), Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.PostAsync("http://your-oa-server/api/message/send", content); if (!response.IsSuccessStatusCode) throw new Exception($"Error occurred: {await response.Content.ReadAsStringAsync()}"); Console.WriteLine(await response.Content.ReadAsStringAsync()); } } } ``` 注意这里的URL应替换为实际的服务端地址,并且可能还需要附加认证信息等额外设置以满足安全性的要求[^2]。 #### RSA加密用户ID作为HTTP头部字段 考虑到安全性因素,在某些场景下需要对`userid`实施RSA公钥加密后再将其加入HTTP头中传递给服务器端验证身份合法性。此过程涉及到了密钥管理和加解密算法的应用: ```csharp /// <summary> /// 获取带有必要鉴权信息的HTTP头部集合. /// </summary> /// <param name="token">令牌.</param> /// <param name="userId">未加密前的用户标识符.</param> /// <returns>包含所有必需项在内的字典对象.</returns> public static Dictionary<string, string> GetHttpHeaders(string token, string userId) { var headers = new Dictionary<string, string>(); // 添加固定不变的部分如APP ID 和 Token headers["appid"] = ConfigurationManager.AppSettings.Get("OAApiAppId"); headers["token"] = token; // 对用户ID应用RSA加密保护隐私 RsaEncryption rsaEncrption = new RsaEncryption(); string encryptedUserId = rsaEncrption.Encrypt(userId); // 将经过加密后的用户ID放入headers里边去 headers["userid"] = encryptedUserId; return headers; } // 假设存在这样一个辅助类负责具体的加密逻辑... private sealed class RsaEncryption { internal string Encrypt(string plainText) => /* ... */; } ``` 以上展示了如何基于C#语言环境内实现针对OA API的安全调用模式之一——即通过对敏感数据采取适当措施加以防护从而保障通信链路间的数据交换更加可靠稳定[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个程序员_zhangzhen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值