DataGridView批量删除报List<string>无法转换为string[]错误
问题根因
抛出List<string>无法转换为string[]错误的核心原因是ASMX Web Service的默认序列化规则:旧版.NET Web Service不会直接序列化泛型List<T>类型,在生成客户端代理类时,会自动将所有List<T>类型的成员转换为对应的数组类型。你代码里还有三个额外问题会导致功能异常:
- UI端定义的是无泛型参数的非类型化
List,和代理类要求的string[]类型完全不匹配 - UI端调用的方法名是
yeniadaykayit,和你定义的删除接口secilenID不匹配,后续改完类型也会调错接口 - 数据库删除逻辑在循环第一次执行时就返回结果,只会删除第一条选中记录,且字符串拼接SQL存在注入风险
修复方案
1. 调整UI端赋值逻辑
把非泛型集合改成强类型List<string>存储选中ID,最后调用接口时转成数组匹配代理类的类型要求,同时修正调用的方法名:
List<string> secilen = new List<string>(); for (int i = 0; i < dgv_adaylar.Rows.Count; i++) { DataGridViewRow row = dgv_adaylar.Rows[i]; if (Convert.ToBoolean(row.Cells["secim"].Value) == true) { string secilenid = row.Cells[1].Value.ToString(); secilen.Add(secilenid); } } ESMWebServis.WebService1 ws = new ESMWebServis.WebService1(); // 转成string[]匹配代理类属性类型,调用正确的删除接口 ESMWebServis.outputType returnType = ws.secilenID(new ESMWebServis.Aday() { secilmisler = secilen.ToArray() });
2. (可选)统一服务端和客户端的类型定义
如果不想每次都手动做集合类型转换,可以直接修改服务端Aday类的定义,把secilmisler属性改成数组类型,从根源避免序列化类型不匹配问题:
namespace ESMWebServis { public class Aday { public int id { get; set; } public string adi { get; set; } public string soyadi { get; set; } public string[] secilmisler { get; set; } } }
改完之后需要更新Web Service的Web引用,让客户端代理类同步最新的类型定义。
3. 修复数据库删除逻辑的缺陷
把原来循环内提前返回、字符串拼接SQL的写法改成参数化查询,循环执行完成后再返回结果,避免删不全和SQL注入问题:
public outputType secilenid(Aday a) { outputType returnValueOutputType = outputType.islembasarisiz; if (a.secilmisler == null || a.secilmisler.Length == 0) { return returnValueOutputType; } try { baglantikontrol(); foreach (string idStr in a.secilmisler) { // 用参数化查询杜绝SQL注入风险 cmd = new MySqlCommand("DELETE FROM tbl_adaykayit WHERE id = @id", baglan); cmd.Parameters.AddWithValue("@id", idStr); int affectRows = cmd.ExecuteNonQuery(); if (affectRows > 0) { returnValueOutputType = outputType.islembasarili; } } } finally { baglantikontrol(); } return returnValueOutputType; }
如果选中的删除记录较多,可以把所有ID拼接成
IN条件一次性执行删除,减少数据库交互次数,性能比循环单条删除高很多。
内容的提问来源于stack exchange,提问作者samet
相关产品推荐
相关产品推荐

