峰峦@叠嶂 2025-09-15 15:52 采纳率: 98%
浏览 2
已结题

将查询返回的结果体现在datagridview内,请问怎么处理;

请教一下,我通过接口,查询我们上传到医保平台的数据,目前接口是通过的,查询返回的数据也正常(请见下图),但查询到的内容只出现在平台的返回结果里面,我们想让这个返回的结果,体现在datagridview内,请问以下代码应该怎么修改

img


 public partial class Form1 : Form
 {

     private static readonly string ak = "d550d";//正式环境
     private static readonly string sk = "fdafe";

     private static readonly HttpClient _httpClient = new HttpClient()
     { Timeout = TimeSpan.FromMinutes(10) };// 单次请求,若超时,等待是10分钟

     private static readonly string DRUG_INFO_URL = "https://drugtrac.nhsa.gov.cn/tb/traceability/queryDrugTracInfo";

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

         InitializeComponent();

         Autosize = new AutoAdaptWindowsSize(this);

     }

     AutoAdaptWindowsSize Autosize;

     // 接口响应模型   
     public class ApiResponse
     {
         public int code { get; set; }          // 与API返回的code匹配
         public string type { get; set; }       // 与API返回的type匹配
         public string message { get; set; }    // 与API返回的message匹配
         public List<DrugResult> data { get; set; } // 数组类型
     }

     //药品查询结果模型
     public class DrugResult
     {
         public List<DrugDetail> Items { get; set; }
         public int TotalCount { get; set; }
         public int CurrentPage { get; set; }
         public int PageSize { get; set; }
         public int TotalPages { get; set; }
     }

     // 药品详情模型
     public class DrugDetail
     {
         public string SEL_FLAG { get; set; }       
         public string TRDN_SEL_FLAG { 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 string DRUG_MANU_LOTNUM { get; set; }       
         public DateTime DRUG_MANU_DATE { get; set; }
         public DateTime DRUG_EXPY_ENDDATE { get; set; }
         public DateTime DRUG_APRVNO_DATE { get; set; }
         public string PROD_CODE { get; set; }
         public string LOC_PROV { get; set; }
         public string LOC_CITY { get; set; }

     }   
     public class DrugInfo //国产药字段类的设置
     {
         public string TRAC_CODG_SN { get; set; }
         public int CURRENT_PAGE { get; set; } // 改为int类型,匹配接口的数值型要求
         public string TRAC_TYPE { get; set; }
         public int PAGE_SIZE { get; set; } // 改为int类型,匹配接口的数值型要求
     }

     private static string GenerateSignature(string ak, string timestamp, string sk, string paramJson) // 直接传入已序列化的paramJson
     {
         // 不再重复序列化
         string rawString = $"{ak}{timestamp}{sk}{paramJson}";

         using (SHA256 sha256 = SHA256.Create())
         {
             byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(rawString));
             return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
         }
     }
     private void Form1_Load(object sender, EventArgs e)
     {     

     }
       
     private void Form1_SizeChanged(object sender, EventArgs e)
     {
         if (Autosize != null)
         {
             Autosize.FormSizeChanged();
         }
     }    

     private void textBox1_KeyUp(object sender, KeyEventArgs e)
     {
         if (e.KeyCode == Keys.Enter)
         {

         }
     }

     private bool ValidateInput(out string errorMsg)
     {
         errorMsg = string.Empty;

         // 验证药品追溯码
         if (string.IsNullOrWhiteSpace(textBox1.Text))
         {
             errorMsg = "请输入药品追溯码";
             return false;
         }

         return true;
     }

     private async Task<ApiResponse> QueryDrugInfoAsync(DrugInfo drugInfo)
     {
         try
         {
             // 生成时间戳(秒级)
             var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
             var timestampGenerationTime = DateTimeOffset.UtcNow;

             // JSON序列化设置
             JsonSerializerSettings jsonSettings = new JsonSerializerSettings
             {
                 DateFormatString = "yyyyMMddHHmmss",
                 ContractResolver = new CamelCasePropertyNamesContractResolver(),
                 NullValueHandling = NullValueHandling.Ignore
             };

             // 序列化查询参数
             string paramJson = JsonConvert.SerializeObject(drugInfo, jsonSettings);

             // 生成签名
             string sign = GenerateSignature(ak, timestamp, sk, paramJson);

             // 构建请求负载
             var payload = new
             {
                 ak,
                 timestamp,
                 sign,
                 param = paramJson
             };

             string jsonPayload = JsonConvert.SerializeObject(payload, jsonSettings);
             Console.WriteLine($"请求参数: {jsonPayload}");

             // 发送请求
             var sendTime = DateTimeOffset.UtcNow;
             using (var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"))
             {
                 HttpResponseMessage response = await _httpClient.PostAsync(DRUG_INFO_URL, content);
                 string responseBody = await response.Content.ReadAsStringAsync();
                 Console.WriteLine($"响应状态:{(int)response.StatusCode} {response.ReasonPhrase}");
                 Console.WriteLine($"响应内容:{responseBody}");

                 // 检查时间戳有效性
                 var timeDiff = sendTime - timestampGenerationTime;
                 if (timeDiff.TotalSeconds > 60)
                 {
                     Console.WriteLine($"警告:时间戳生成与请求发送之间的时间差超过60秒,可能导致签名验证失败,时间差: {timeDiff.TotalSeconds} 秒");
                 }

                 // 确保请求成功
                 response.EnsureSuccessStatusCode();

                 // 解析响应
                 return JsonConvert.DeserializeObject<ApiResponse>(responseBody);
             }
         }
         catch (HttpRequestException ex)
         {
             Console.WriteLine($"HTTP请求异常: {ex.Message}");
             throw new Exception($"网络请求失败: {ex.Message}");
         }
         catch (JsonException ex)
         {
             Console.WriteLine($"JSON序列化/反序列化异常: {ex.Message}");
             throw new Exception($"数据处理失败: {ex.Message}");
         }
         catch (Exception ex)
         {
             Console.WriteLine($"操作失败:{ex.GetBaseException().Message}");
             throw new Exception($"查询失败: {ex.GetBaseException().Message}");
         }
     }

     private void ShowResult(DrugResult result)
     {
         if (result == null || result.Items == null || result.Items.Count == 0)
         {
             dataGridView1.DataSource = null;
             lblStatus.Text = "未查询到数据";
             return;
         }

         else
         {
             // 绑定数据到表格
             dataGridView1.DataSource = result.Items;

             // 更新状态信息
             lblStatus.Text = $"共查询到 {result.TotalCount} 条记录,当前第 {result.CurrentPage}/{result.TotalPages} 页";
         }
    
     }

     private async void btnquery_Click(object sender, EventArgs e)
     {          
         try
         {
             // 验证输入
             if (!ValidateInput(out string errorMsg))
             {
                 MessageBox.Show(errorMsg, "输入验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                 return;
             }

             // 准备查询参数
             var drugInfo = new DrugInfo
             {
                 TRAC_CODG_SN = textBox1.Text.Trim(),
                 CURRENT_PAGE = int.Parse(comCurrentPage.Text.Trim()),
                 TRAC_TYPE = "1", // 假设1代表药品
                 PAGE_SIZE = 10 // 每页条数,可根据需求调整
             };

             // 显示加载状态
             btnquery.Enabled = false;
             lblStatus.Text = "正在查询,请稍候...";
             Cursor = Cursors.WaitCursor;

             // 调用接口查询
             var response = await QueryDrugInfoAsync(drugInfo);

             // 处理查询结果
             if (response != null && response.code == 0) // 假设code=0表示成功
             {
                 // 取第一个结果或根据需要处理
                 var firstResult = response.data?.FirstOrDefault();
                 ShowResult(firstResult);

                 MessageBox.Show($"查询成功,共找到 {response.data?.Count ?? 0} 条记录", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);

             }
             else
             {
                 // 关键修改:将Message改为message,与ApiResponse类定义保持一致
                 MessageBox.Show($"查询失败: {response?.message ?? "未知错误"}", "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 lblStatus.Text = $"查询失败: {response?.message ?? "未知错误"}";
             }
         }
         catch (Exception ex)
         {
             MessageBox.Show($"操作失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
             lblStatus.Text = $"错误: {ex.Message}";
         }
         finally
         {
             // 恢复状态
             btnquery.Enabled = true;
             Cursor = Cursors.Default;
         }

     }
 }
  • 写回答

4条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-09-15 15:56
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:阳光总在前方,只要你愿意抬头。
    .

    根据您的代码和需求,您需要将API返回的数据正确绑定到DataGridView控件中。以下是需要修改的关键部分:

    主要问题分析

    1. 模型定义不匹配:API返回的data字段结构与您的DrugResult类定义不一致
    2. 数据绑定问题ShowResult方法期望DrugResult类型,但实际返回的是List<DrugDetail>

    代码修改方案

    1. 修正API响应模型

    // 接口响应模型   
    public class ApiResponse
    {
        public int code { get; set; }
        public string type { get; set; }
        public string message { get; set; }
        public List<DrugDetail> data { get; set; } // 直接改为DrugDetail列表
    }
    
    
    // 删除或注释掉原有的DrugResult类
    // public class DrugResult
    // {
    //     public List<DrugDetail> Items { get; set; }
    //     public int TotalCount { get; set; }
    //     public int CurrentPage { get; set; }
    //     public int PageSize { get; set; }
    //     public int TotalPages { get; set; }
    // }
    

    2. 修改ShowResult方法

    private void ShowResult(List<DrugDetail> result)
    {
        if (result == null || result.Count == 0)
        {
            dataGridView1.DataSource = null;
            lblStatus.Text = "未查询到数据";
            return;
        }
        else
        {
            // 绑定数据到表格
            dataGridView1.DataSource = result;
            
            // 更新状态信息
            lblStatus.Text = $"共查询到 {result.Count} 条记录";
        }
    }
    

    3. 修改btnquery_Click方法中的结果处理

    private async void btnquery_Click(object sender, EventArgs e)
    {          
        try
        {
            // 验证输入
            if (!ValidateInput(out string errorMsg))
            {
                MessageBox.Show(errorMsg, "输入验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
    
    
            // 准备查询参数
            var drugInfo = new DrugInfo
            {
                TRAC_CODG_SN = textBox1.Text.Trim(),
                CURRENT_PAGE = int.Parse(comCurrentPage.Text.Trim()),
                TRAC_TYPE = "1", // 假设1代表药品
                PAGE_SIZE = 10 // 每页条数,可根据需求调整
            };
    
    
            // 显示加载状态
            btnquery.Enabled = false;
            lblStatus.Text = "正在查询,请稍候...";
            Cursor = Cursors.WaitCursor;
    
    
            // 调用接口查询
            var response = await QueryDrugInfoAsync(drugInfo);
    
    
            // 处理查询结果
            if (response != null && response.code == 0) // 假设code=0表示成功
            {
                ShowResult(response.data);
    
    
                MessageBox.Show($"查询成功,共找到 {response.data?.Count ?? 0} 条记录", 
                    "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show($"查询失败: {response?.message ?? "未知错误"}", 
                    "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
                lblStatus.Text = $"查询失败: {response?.message ?? "未知错误"}";
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show($"操作失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            lblStatus.Text = $"错误: {ex.Message}";
        }
        finally
        {
            // 恢复状态
            btnquery.Enabled = true;
            Cursor = Cursors.Default;
        }
    }
    

    4. 可选:优化DataGridView显示

    如果您需要自定义列显示,可以在Form1的构造函数或Load事件中添加:

    private void InitializeDataGridView()
    {
        // 设置自动生成列(根据您的需求选择)
        dataGridView1.AutoGenerateColumns = true;
        
        // 或者手动设置列(推荐)
        dataGridView1.AutoGenerateColumns = false;
        dataGridView1.Columns.Clear();
        
        // 添加需要的列
        dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()
        {
            DataPropertyName = "DRUG_MANU_LOTNUM",
            HeaderText = "生产批号",
            Width = 120
        });
        
        dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()
        {
            DataPropertyName = "DRUG_GENNAME",
            HeaderText = "通用名称",
            Width = 150
        });
        
        dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()
        {
            DataPropertyName = "PACSPEC",
            HeaderText = "包装规格",
            Width = 100
        });
        
        // 根据需要添加其他列...
    }
    

    修改后的关键点

    1. 直接使用List<DrugDetail>作为数据源,而不是嵌套的DrugResult
    2. 移除了不必要的嵌套结构,使模型与API响应完全匹配
    3. 简化了数据绑定流程,直接绑定到DataGridView

    这样修改后,API返回的数据应该能够正确显示在DataGridView中了。如果还有问题,请检查API返回的实际JSON结构是否与您的模型完全匹配。

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

报告相同问题?

问题事件

  • 系统已结题 9月23日
  • 已采纳回答 9月15日
  • 创建了问题 9月15日