我们有一个很大的List<object>
,我们将其转换为json字符串,然后发送到存储过程。为了使这篇文章简单,我们假设对象看起来像这样:
public class Customer
{
public string Name { get; set; }
}
其中一位客户是“鲍勃的维修店”。当包含此值的列表被序列化时,它将包含以下内容:
{
"Name": "Bob's Repair Shop"
}
没关系,直到我们想要将此json发送到存储过程中为止。当到达那里时,该单引号会引发错误(据我所知)。
最初,我们通过在C#代码中的json字符串上执行.replace("'", "~")
,然后在存储的proc中进行相反操作来处理此问题。那工作了一段时间。但是我们现在遇到的是,我们拥有List <>的对象比这个小例子要复杂得多,并且我们还处理列表中的数十万条记录。当json字符串很大时,.replace("'", "~")
会引发Out of Range
异常。老实说,无论如何,这种.replace("'", "~")
方法是一种黑客。
我希望找到一种以序列化过程中的单引号转义的方式对List<object>
进行序列化的方法。这可能吗?如果可以,怎么办?
编辑:
我本来应该这样说的。对不起,我错过了。这是存储的proc接收json字符串的方式:
ALTER PROCEDURE [dbo].[name_of_proc]
@jsonString NVARCHAR(MAX)
AS
然后我们用@jsonString
将OPENJSON
转换为表变量
编辑2:
sp的调用方式
public void UpdateBulk(List<object> myObject)
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(myObject);
json.replace("'", "~");
var dParam = new DynamicParameters();
dParam.Add("@jsonString", json);
QuerySP<myObject>("name_of_proc", dParam);
}
protected IEnumerable<T> QuerySP<T>(string storedProcedure, object param = null)
{
using (var db = this.Context)
{
var output = db.Query<T>(storedProcedure, param: param, commandType: CommandType.StoredProcedure,commandTimeout: 32767);
return output;
}
}
编辑3: 指向可能重复的线程询问如何更改它:
{"key" : "value"}
对此:
{'key' : 'value'}
这不是我要的。我在问如何改变这个:
{
"Name": "Bob's Repair Shop"
}
对此:
{
"Name": "Bob\'s Repair Shop"
}
答案 0 :(得分:4)
您可以添加一个自定义JSON转换器,以在进行序列化时对单个string
实例执行替换。这仍在使用string.Replace
,但是此时所有的字符串实例都应该很小。
public class EscapeQuotes : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var escapedValue = ((string)value).Replace("'", "\\'");
writer.WriteValue(escapedValue);
}
}
用法:
Customer myObject = new Customer() { Name = "Bob's repair shop" };
var output = JsonConvert.SerializeObject(myObject, new EscapeQuotes());
输出:
{“名称”:“鲍勃的维修店”}