Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不使用XmlDocument.Loadxml()函数将XML反序列化为JSON_C#_Xml_Json_.net 2.0_Sqlclr - Fatal编程技术网

C# 不使用XmlDocument.Loadxml()函数将XML反序列化为JSON

C# 不使用XmlDocument.Loadxml()函数将XML反序列化为JSON,c#,xml,json,.net-2.0,sqlclr,C#,Xml,Json,.net 2.0,Sqlclr,我有一个独特的问题。我将dll注册为SQL Server数据库中的程序集,该数据库接收一个SQLXml变量和两个字符串,并将数据序列化为JSON格式 以下是方法调用供参考: [SqlProcedure] public static void Receipt(SqlString initiatorPassword, SqlString initiatorId, SqlXml XMLOut,

我有一个独特的问题。我将dll注册为SQL Server数据库中的程序集,该数据库接收一个SQLXml变量和两个字符串,并将数据序列化为JSON格式

以下是方法调用供参考:

[SqlProcedure]
public static void Receipt(SqlString initiatorPassword,
                           SqlString initiatorId,
                           SqlXml XMLOut,
                           out SqlString strMessge)
如果这是任何其他类型的应用程序,我会在这个应用程序中使用Newtonsoft.Json或Jayrock。通常我会按照给出的答案做类似的事情:

XmlReader r = (XmlReader)XmlOut.CreateReader();
XmlDocument doc = new XmlDocument();
doc.load(r);
但是,因为我使用的是SQLClr,所以有一些规则。其中之一是,
.Load()
和任何其他继承的方法都不能使用。
我认为.Net framework说得最好:

System.InvalidOperationException:无法加载动态生成的序列化程序集。在某些托管环境中 程序集加载功能受到限制, 考虑使用预生成的序列化器。有关详细信息,请参阅内部异常。-->System.IO.FileLoadException:
主机已禁用LoadFrom()、LoadFile()、Load(字节[])和LoadModule()

无论如何,我对SqlClr不太熟悉,但如果我理解正确,这是因为SqlClr的规则不允许.Load()和继承的方法,而没有签名和强名称。我的DLL和我正在使用的第三方DLL没有强名称,我也不能自己重建和签名它们。因此,这让我不得不尝试在不使用load的情况下完成此任务(除非有人知道其他方法)

我唯一能想到的解决方案是一个非常丑陋的while循环,它不能正常工作,我得到了一个“Jayrock.Json.JsonException:Json对象中的Json成员值必须在其成员名称之前”异常。以下是我编写的while循环(我知道这不是我最好的代码):

intlastdepth=-1;
布尔对象=真;
布尔wt=假;
//为省略的标题编写成员/对象语句
JsonWriter w=新的JsonTextWriter()
while(m.Read())
{
如果((lastdepth==-1)和(&(m.IsStartElement()))
{//正在检查根元素
lastdepth=0;
}
if((m.IsStartElement())&&(lastdepth!=-1))
{//正在检查开始元素()
w、 WriteMember(m.Name);
如果(objend)
{//检查元素是否为新的父节点,如果是,则写入开始对象
w、 WriteStartObject();
objend=假;
}
}
if(m.NodeType==XmlNodeType.Text)
{//在此处写入文本。注意:m.Depth>lastdepth在此!!!!!!!
w、 资产净值(m.Value);
wt=真;
}
if(m.NodeType==XmlNodeType.Whitespace)//如果是空白,请继续
{m.Skip();}
if((m.NodeType==XmlNodeType.EndElement)&&(wt==false)&&(lastdepth>m.Depth))
{//End元素,结束一系列“子”节点
w、 WriteEndObject();
objend=true;
}
if((m.NodeType==XmlNodeType.EndElement)&&(wt==true))//el的标准结束
{wt=false;}
lastdepth=m.深度;
}
w、 WriteEndObject();
jout=w.ToString();
}
我的问题是,既然我不能使用
.load()
,而且我的while循环调试起来很混乱,那么这里最好的方法是什么?通常讨论的另一种方法是反序列化为具有匹配变量的对象,但我有一个很大的XML来自SQL Server。我的循环是对动态编程的一种尝试,因为有大约200个字段被用来生成这个XML


注意:我正在使用Jayrock并在.NETFramework2.0中工作。目前我无法更改框架版本。

我希望这适用于您,但除非您尝试,否则我不知道。发件人:

外部访问解决了代码需要访问的场景 服务器之外的资源,例如文件、网络、注册表和 环境变量。每当服务器访问外部 资源,它模拟调用 托管代码

不安全代码权限适用于程序集不安全的情况 不可验证安全或需要额外访问受限 资源,如Microsoft Win32 API

我相信这两者之一就是您所需要的,可能是
外部访问
。更多:

我们建议从程序集文件创建非对称密钥 在主数据库中。必须创建映射到此非对称密钥的登录名 然后创建,并且必须授予登录名外部访问权限 程序集或不安全的程序集权限

注意:您必须创建一个新登录名才能与非对称密钥关联。这 登录仅用于授予权限;不一定要这样 与用户关联,或在应用程序中使用

以及相关代码(我在过去成功地使用过):

我想您还希望在项目中启用“生成序列化程序集”

这实际上回避了您的问题,但这确实是允许成功加载其他DLL的首选方法,以便您可以编写正确的代码。

您的代码正在引发异常:

A JSON member value inside a JSON object must be preceded by its member name.
此异常来自以下方法:

    private void EnsureMemberOnObjectBracket() 
    {
        if (_state.Bracket == JsonWriterBracket.Object)
            throw new JsonException("A JSON member value inside a JSON 
             object must be preceded by its member name.");
    }
来自该代码的包含调用来自:

    public sealed override void WriteString(string value)
    {
        if (Depth == 0)
        {
            WriteStartArray(); WriteString(value); WriteEndArray();
        }
        else
        {
            EnsureMemberOnObjectBracket();
            WriteStringImpl(value);
            OnValueWritten();
        }
    }
代码调用调用
EncuremberonObjectBracket
的方法的唯一时间是从一个位置:

if (m.NodeType == XmlNodeType.Text)
{ //Writes text here.  NOTE: m.Depth > lastdepth here!!!!!!!
 w.WriteString(m.Value);
 wt = true;
}
这意味着这里有一个错误。也许你
    public sealed override void WriteString(string value)
    {
        if (Depth == 0)
        {
            WriteStartArray(); WriteString(value); WriteEndArray();
        }
        else
        {
            EnsureMemberOnObjectBracket();
            WriteStringImpl(value);
            OnValueWritten();
        }
    }
if (m.NodeType == XmlNodeType.Text)
{ //Writes text here.  NOTE: m.Depth > lastdepth here!!!!!!!
 w.WriteString(m.Value);
 wt = true;
}