峰峦@叠嶂 2025-03-19 13:59 采纳率: 98%
浏览 6
已结题

接口上传的签名不正确

请教个问题,我们需要上传数据表内容,以json格式,传到指定的接口,具体要求如图,但在运行时总提示签名不正确,我问一下平台服务人员,告知是:在发送请求时候的 param参数 后面应该是一个 string类型的串,和 paramJson的值一致;

img

img

我的代码如下,方便时请指导一下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OfficeOpenXml; // 注意安装 EPPLUS 时,选择低于 8.0 版本;
using OfficeOpenXml.FormulaParsing.Excel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Globalization;
using System.Data.SqlClient;

namespace Interfacetest
{
    public partial class Form1 : Form
    {
        private static readonly string ak = "d551";
        private static readonly string sk = "fdafe";

        private static string connectionString = "Data Source=192.168.1.2;Initial Catalog=WHOrganize;User ID=sa;Password=whyy@2021";

        private static readonly HttpClient _httpClient = new HttpClient();

        public Form1()
        {
            // 初始化 EPPlus
            ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;

            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        { }

        public class UploadRequest
        {
            public bool DEL_FLAG { get; set; }
            public List<DrugInfo> DATA { get; set; }
        }

        public class DrugInfo
        {
            public string TRAC_CODG_SN { get; set; }
            public string MED_LIST_CODG { get; set; }
            public string NAT_DRUG_CODG { get; set; }
            public string DRUG_GENNAME { get; set; }
            public string DOSFORM { get; set; }
            public string PREP_SPEC { get; set; }
            public string PACSPEC { get; set; }
            public decimal PAC_CONVRAT { get; set; }
            public string PAC_CONVRAT_EMP { get; set; }
            public string DRUG_MANU_LOTNUM { get; set; }
            public string DRUG_MANU_DATE { get; set; }
            public string DRUG_EXPY_ENDDATE { get; set; }
            public string DRUG_APRVNO { get; set; }
            public string DRUG_APRVNO_DATE { get; set; }
            public string RX_FLAG { get; set; }
            public string NAT_BAS_MEDN_FLAG { get; set; }
            public decimal MANU_CNT { get; set; }
            public string PRODENTP_NAME { get; set; }
            public string PRODENTP_USCC { get; set; }
            public string MANU_ADDR { get; set; }
            public string DRUG_LV { get; set; }
            public string PROD_CODE { get; set; }
        }

        private List<DrugInfo> ReadProductInfoFromDatabase()
        {
            var drugList = new List<DrugInfo>();

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();

                string query = "SELECT batchNo as TRAC_CODG_SN,ICD as MED_LIST_CODG,NDC as NAT_DRUG_CODG" +
                    ",productName as DRUG_GENNAME,type as DOSFORM ,spec as PREP_SPEC,packageSpec as PACSPEC" +
                    ",packConvert as PAC_CONVRAT,packConUnit as PAC_CONVRAT_EMP,batchNo1 as DRUG_MANU_LOTNUM" +
                    ",madeDate as DRUG_MANU_DATE,validateDate as DRUG_EXPY_ENDDATE,authorizedNo as DRUG_APRVNO" +
                    ",dpndate as DRUG_APRVNO_DATE,drugFlag as RX_FLAG,NdrugFlag as NAT_BAS_MEDN_FLAG,amount as MANU_CNT" +
                    ",company as PRODENTP_NAME, uscc as PRODENTP_USCC ,address as MANU_ADDR ,drugLevel as DRUG_LV,bcode as  PROD_CODE" +
                    " FROM w_NdrugUpload";

                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var drug = new DrugInfo
                            {
                                TRAC_CODG_SN = reader["TRAC_CODG_SN"].ToString(),
                                MED_LIST_CODG = reader["MED_LIST_CODG"].ToString(),
                                NAT_DRUG_CODG = reader["NAT_DRUG_CODG"].ToString(),
                                DRUG_GENNAME = reader["DRUG_GENNAME"].ToString(),
                                DOSFORM = reader["DOSFORM"].ToString(),
                                PREP_SPEC = reader["PREP_SPEC"].ToString(),
                                PACSPEC = reader["PACSPEC"].ToString(),
                                PAC_CONVRAT = Convert.ToDecimal(reader["PAC_CONVRAT"]),
                                PAC_CONVRAT_EMP = reader["PAC_CONVRAT_EMP"].ToString(),
                                DRUG_MANU_LOTNUM = reader["DRUG_MANU_LOTNUM"].ToString(),
                                DRUG_MANU_DATE = ConvertToDateString(reader["DRUG_MANU_DATE"].ToString()),
                                DRUG_EXPY_ENDDATE = ConvertToDateString(reader["DRUG_EXPY_ENDDATE"].ToString()),
                                DRUG_APRVNO = reader["DRUG_APRVNO"].ToString(),
                                DRUG_APRVNO_DATE = ConvertToDateString(reader["DRUG_APRVNO_DATE"].ToString()),
                                RX_FLAG = reader["RX_FLAG"].ToString(),
                                NAT_BAS_MEDN_FLAG = reader["NAT_BAS_MEDN_FLAG"].ToString(),
                                MANU_CNT = Convert.ToDecimal(reader["MANU_CNT"]),
                                PRODENTP_NAME = reader["PRODENTP_NAME"].ToString(),
                                PRODENTP_USCC = reader["PRODENTP_USCC"].ToString(),
                                MANU_ADDR = reader["MANU_ADDR"].ToString(),
                                DRUG_LV = reader["DRUG_LV"].ToString(),
                                PROD_CODE = reader["PROD_CODE"].ToString()
                            };

                            drugList.Add(drug);
                        }
                    }
                }

                connection.Close();
            }

            return drugList;
        }

        private string ConvertToDateString(string input) // 解决日期问题
        {
            if (DateTime.TryParseExact(input, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
            {
                return date.ToString("yyyyMMdd");
            }
            return string.Empty;
        }

        private static async Task UploadProductsAsync(List<DrugInfo> products, bool delFlag = false)
        {
            try
            {
                long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                var param = new { data = products };
                string sign = GenerateSignature(ak, timestamp.ToString(), sk, param);

                var uploadRequest = new UploadRequest
                {
                    DEL_FLAG = delFlag,
                    DATA = products
                };

                var payload = new
                {
                    ak,
                    timestamp,
                    sign,
                    param = uploadRequest

                };

                string jsonPayload = JsonConvert.SerializeObject(payload, new JsonSerializerSettings
                {
                    DateFormatString = "yyyyMMdd"
                });

                StringContent content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");

                // 打印请求日志
                Console.WriteLine($"Request payload: {JsonConvert.SerializeObject(payload, Formatting.Indented)}");

                var response = await _httpClient.PostAsync(
                    "https://drugtrac  ed.nhsa.gov.cn/tb/traceability/micDrugInfo",
                    content);

                var responseString = await response.Content.ReadAsStringAsync();

                // 打印响应日志
                Console.WriteLine($"Response: {responseString}");

                // 增强响应处理
                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception($"HTTP 错误: {response.StatusCode}\n响应内容: {responseString}");
                }

                // 解析业务响应
                var result = JObject.Parse(responseString);
                if (result["code"]?.ToString() != "0")  // 根据实际成功码调整
                {
                    throw new Exception($"业务错误: {result["message"]?.ToString()}");
                }
            }
            catch (Exception ex)
            {
                // 记录详细错误日志
                File.AppendAllText("error.log", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 错误: {ex}\n");
                throw;
            }
        }

        private static string GenerateSignature(string ak, string timestamp, string sk, object param)
        {
            string paramJson = JsonConvert.SerializeObject(param, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });

            // 确保签名拼接顺序正确
            string rawString = $"{ak}{timestamp}{sk}{paramJson}";

            using (SHA256 sha256 = SHA256.Create())
            {
                byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(rawString));
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            }

        }

        // 获取 Unix 时间戳(秒)
        //long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        //private static string GenerateSignature(string ak, string timestamp , string sk, object param)
        //{
        //    // 序列化参数为 JSON 字符串
        //    string paramJson = JsonConvert.SerializeObject(param, new JsonSerializerSettings
        //    {
        //        Formatting = Formatting.None // 确保 JSON 字符串紧凑
        //    });
        //    Console.WriteLine("paramJson: " + paramJson); // 调试输出

        //    // 拼接签名字符串
        //    string rawString = $"{ak}{timestamp}{sk}{paramJson}";
        //    Console.WriteLine("rawString: " + rawString); // 调试输出

        //    // 生成 SHA256 签名
        //    using (SHA256 sha256 = SHA256.Create())
        //    {
        //        byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(rawString));
        //        string sign = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
        //        Console.WriteLine("sign: " + sign); // 调试输出
        //        return sign;
        //    }
        //}


        private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                var products = ReadProductInfoFromDatabase();

                this.Cursor = Cursors.WaitCursor;
                btnUp.Enabled = false;

                await UploadProductsAsync(products);

                MessageBox.Show("上传成功!请到平台验证数据",
                    "成功",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"上传失败:{ex.Message}",
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            finally
            {
                this.Cursor = Cursors.Default;
                btnUp.Enabled = true;
            }
        }

        private void btnquery_Click(object sender, EventArgs e)
        {

        }
    }
}


  • 写回答

5条回答 默认 最新

  • 峰峦@叠嶂 2025-03-25 14:10
    关注

    目前都不行

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 4月2日
  • 已采纳回答 3月25日
  • 修改了问题 3月19日
  • 创建了问题 3月19日