在innerXML中获取引号以作为"

Aar*_* B. 5 .net c# wcf

(警告 - 下面的xml和无偿字符编码的unholy混合.)

简短版本: 为什么我不能得到我的服务引用调用(c#,.net 3.5,添加到VS2008的自动服务引用代码)来正确编码一个看起来像这个电线的参数:(查找"位..那是我的祸根.)

(为清楚起见,删除了其他额外的肥皂碎片)

<SOAP-ENV:Body><SOAPSDK4:SetCondition xmlns:SOAPSDK4="http://tempuri.org/message/">
<sharedSecret>buggerall</sharedSecret>

<xmlData>&lt;SEARCHINFO_LIST&gt;&lt;SEARCH_INFO action=&quot;add&quot; status=&
quot;3&quot; name=&quot;TestProfile2&quot; mask=&quot;0&quot; campaign_id=&quot;33&quot; 
campaign_protected=&quot;N&quot; condition_protected=&quot;N&quot;&gt;&lt;CONDITIONS/&
gt;&lt;EXPRESSIONS/&gt;&lt;/SEARCH_INFO&gt;&lt;/SEARCHINFO_LIST&gt;</xmlData>
</SOAPSDK4:SetCondition></SOAP-ENV:Body>   
Run Code Online (Sandbox Code Playgroud)

我设置参数,拨打电话......服务返回一条很好的消息,上面写着"没有SOU--肥皂给你!"

我在传递给webservice参数字符串中尝试了其他几种格式:

action=\"add\"
Run Code Online (Sandbox Code Playgroud)

这给了我这个电线(通过提琴手): action="add"

action=&quot;add&quot;
Run Code Online (Sandbox Code Playgroud)

这给了我这个电报: action=&amp;quot;add&amp;quot;

和各种组合(action =""add""?​​!)与html.encode,url.encode几乎完全被轰炸,或在电线上显示为双引号.

哦,我甚至试过<![CDATA[&quot;]]周围.那也行不通.

有没有办法在soap消息的innerHtml位强制使用双引号编码?

*(因为这就是服务所需要的.不要问问题.这些不是您正在寻找的机器人)

*** 长而曲折的版本:

我正在编写一个应用程序来自动化一些目前由(winform)管理GUI应用程序处理的程序.(实际上,它是一个mmc snap in.无论如何.)

为了完成它的任务,winform应用程序通过标准的Web服务调用与它的服务器进行通信.

我正在使用VS2008的漂亮的"Web服务参考"自动生成东西(这是技术说明),并且我已成功通过Web服务进行身份验证.为了确保我正确地做事,我从GUI应用程序中捕获了调用,然后将它们与我在线上发送的内容进行了比较.一切都很好.然后我遇到了&符号的邪恶.(更恰当的说,如何正确编码)

对于其中一个调用,Web服务期望看到这样的内容:(我捕获了通过提琴手发送此应用程序的应用程序)

<?xml version="1.0" encoding="UTF-8" standalone="no"?><SOAP-ENV:Envelope
xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" xmlns:SOAPSDK2="
http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAPSDK3="
http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="
http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAPSDK4:SetCondition
xmlns:SOAPSDK4="http://tempuri.org/message/"><sharedSecret>0500001007C3525F3-F315-460D-
AF5C-D84767130126094</sharedSecret><xmlData>&lt;SEARCHINFO_LIST&gt;&lt;SEARCH_INFO  
action=&quot;add&quot; status=&quot;3&quot; name=&quot;TestProfile2&quot; mask=&
quot;0&quot; campaign_id=&quot;33&quot;campaign_protected=&quot;N&quot;
condition_protected=&quot;N&quot;&gt;&lt;CONDITIONS/&gt;&lt;EXPRESSIONS/&gt;&
lt;/SEARCH_INFO&gt;&lt;/SEARCHINFO_LIST&gt;</xmlData></SOAPSDK4:SetCondition></SOAP-
ENV:Body></SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

剥离所有额外的SOAP-y东西以显示相关位 - 这是<xmlData>传递的部分.注意&quot;周围的参数:

&lt;SEARCHINFO_LIST&gt;&lt;SEARCH_INFO action=&quot;add&quot;
status=&quot;3&quot; name=&quot;TestProfile2&quot; mask=&quot;0&quot;
campaign_id=&quot;33&quot; campaign_protected=&quot;N&quot;
condition_protected=&quot;N&quot;&gt;&lt;CONDITIONS/&gt;&lt;EXPRESSIONS/&gt;&
lt;/SEARCH_INFO&gt;&lt;/SEARCHINFO_LIST&gt;
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我有一个像这样构建的字符串:

var serviceParams = "<SEARCHINFO-LIST><SEARCH_INFO action=\"add\"
status=\"3\" name=\"TestProfileFromExternApp\" mask=\"0\" campaign_id=\"33\"
campaign_protected=\"N\"
condition_protected=\"N\"><CONDITIONS/><EXPRESSIONS/></SEARCH_INFO></SEARCHINFO_LIST>";
Run Code Online (Sandbox Code Playgroud)

当我的应用程序通过网络发送它时,fiddler捕获这个:(再次,剥离所有SOAP的东西)

&lt;SEARCHINFO-LIST&gt;&lt;SEARCH_INFO action="add" status="3"
name="TestProfileFromExternApp" mask="0" campaign_id="33"
campaign_protected="N" condition_protected="N"&gt;&lt;CONDITIONS/&gt;
&lt;EXPRESSIONS/&gt;&lt;/SEARCH_INFO&gt;&lt;/SEARCHINFO_LIST&gt;
Run Code Online (Sandbox Code Playgroud)

接收服务发回一个它不喜欢它的错误.它想要&quot;d ## nit.

尖括号被正确编码,但引号在HTTP字符串中有效,并且不会被编码.

"哈哈!" 我说,"我只是预先手动编码!".我试图做这样的事情:

var serviceParams = "<SEARCHINFO-LIST><SEARCH_INFO action=&quot;add&quot;
status=&quot;3&quot; name=&quot;TestProfileFromExternApp&quot;
mask=&quot;0&quot; campaign_id=&quot;33&quot;
campaign_protected=&quot;N&quot;
condition_protected=&quot;N&quot;><CONDITIONS/><EXPRESSIONS/></SEARCH_INFO></SEARCHINFO_LIST>";
Run Code Online (Sandbox Code Playgroud)

这被发送出来(再次,通过提琴手)和我所有的&符号(在 &quot;)中转换为&amp;quot; 如此:

&lt;SEARCHINFO-LIST&gt;&lt;SEARCH_INFO action=&amp;quot;add&amp;quot;
status=&amp;quot;3&amp;quot;
name=&amp;quot;TestProfileFromExternApp&amp;quot; mask=&amp;quot;0&amp;quot;
campaign_id=&amp;quot;33&amp;quot; campaign_protected=&amp;quot;N&amp;quot;
condition_protected=&amp;quot;N&amp;quot;&gt;&lt;CONDITIONS/&gt;&lt;EXPRESSIONS/&gt;&lt;/SEARCH_INFO&gt;&lt;/SEARCHINFO_LIST&gt;
Run Code Online (Sandbox Code Playgroud)

而且,正如你猜测的那样,接收网络服务带回"BZZT!谢谢你玩!".

我尝试了各种类型的转义和编码序列,结果相似.实际上,我所有的操作后,经过类似HttpUtility.HtmlEncode 正确的线路上出门前,并在字符串中的任何&符号转换为:&amp;.并且在转换中忽略引号(单引号或双引号).并且接收网络服务 希望那些被称为&quot;狗的报价,或者它将把它带回家并回家.

我最后一个绝望的希望就是在使用IClientMessageInspector 在BeforeSendRequest事件中实现消息检查之前,正确地抓住消息(我想),并在它进入线路之前手动设置这些消息.

我捕获的信息很好.我甚至可以手动输入&quot;.

但当它被发送时,wireshark和小提琴手都向我保证它的格式很好......用引号我非常想要摆脱它.

<xmlData xsi:type="xsd:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
&lt;SEARCHINFO-LIST&gt;&lt;SEARCH_INFO action="add" status="3" 
name="TestProfileFromExternApp" mask="0" campaign_id="33" campaign_protected="N" 
condition_protected="N"&gt;&lt;CONDITIONS/&gt;&lt;EXPRESSIONS/&gt;
&lt;/SEARCH_INFO&gt;&lt;/SEARCHINFO_LIST&gt;</xmlData>
Run Code Online (Sandbox Code Playgroud)

我的智慧结束了.我会接受任何建议,包括在[邪恶的神灵]的变化上牺牲[小可爱的东西]或者出售我的[灵魂/心灵/儿子的生物系列].相信我,它是较小的邪恶.

根据下面的请求,这里是生成的消息存根:(我认为这是你要求的......)

public int SetCondition(string sharedSecret, string xmlData, out string resultValue) 
{
    tzGui.tzCampaign.SetConditionRequest inValue = new tzGui.tzCampaign.SetConditionRequest();
    inValue.sharedSecret = sharedSecret;
    inValue.xmlData = xmlData;
    tzGui.tzCampaign.SetConditionResponse retVal = ((tzGui.tzCampaign.CampaignSoapPort)(this)).SetCondition(inValue);
    resultValue = retVal.resultValue;
    return retVal.Result;
}
Run Code Online (Sandbox Code Playgroud)

以下是它的调用方式:

void SetConditionTask()
{
    //ok, now we *try* and create a new profile
    var tzCampaignCxn = new tzCampaign.CampaignSoapPortClient("CampaignSoapBinding");
    //no worky
    //string xmlData = "<SEARCHINFO-LIST><SEARCH_INFO action=\"add\" status=\"3\" name=\"TestProfileFromExternApp\" mask=\"0\" campaign_id=\"33\" campaign_protected=\"N\" condition_protected=\"N\"><CONDITIONS/><EXPRESSIONS/></SEARCH_INFO></SEARCHINFO_LIST>";

    //this one doesn't work
    //string xmlData = "<SEARCHINFO-LIST><SEARCH_INFO action=<![CDATA[ &quot; ]]>add<![CDATA[ &quot; ]]> status=<![CDATA[ &quot; ]]>3<![CDATA[ &quot; ]]> name=<![CDATA[ &quot; ]]>TestProfileFromExternApp<![CDATA[ &quot; ]]> mask=<![CDATA[ &quot; ]]>0<![CDATA[ &quot; ]]> campaign_id=<![CDATA[ &quot; ]]>33<![CDATA[ &quot; ]]> campaign_protected=<![CDATA[ &quot; ]]>N<![CDATA[ &quot; ]]> condition_protected=<![CDATA[ &quot; ]]>N<![CDATA[ &quot; ]]>><CONDITIONS/><EXPRESSIONS/></SEARCH_INFO></SEARCHINFO_LIST>";

    //this one doesn't either
    string xmlData = "<SEARCHINFO-LIST><SEARCH_INFO action=&quot;add&quot; status=&quot;3&quot; name=&quot;TestProfileFromExternApp&quot; mask=&quot;0&quot; campaign_id=&quot;33&quot; campaign_protected=&quot;N&quot; condition_protected=&quot;N&quot;><CONDITIONS/><EXPRESSIONS/></SEARCH_INFO></SEARCHINFO_LIST>";

    string createProfileResultVal = string.Empty;
    tzCampaignCxn.SetCondition(SharedSecret, xmlData, out createProfileResultVal);
    txtResults.AppendText(Environment.NewLine + Environment.NewLine + createProfileResultVal);
    }
Run Code Online (Sandbox Code Playgroud)

And*_*tan 0

您需要将该字符串作为 CDATA 部分放入 SOAP 消息中,以便可以完全按照您想要的格式设置它,并且 WCF 不会触及它。

您目前遇到的问题是,该服务需要介于 xml 和 html 之间的编码 - 因此 Soap 格式化程序使用的格式不能很好地处理这种编码 - 所以您总是必须自己转义引号。

不过,我有一种预感,如果您将其包含在<![CDATA[*yourstring*]]>字符串参数中的 CDATA 标记中,则该标记将通过线路转义并到达另一端,如下所示&lt;![[*yourstring-XML-element-encoded*]]&gt;

如果是这种情况,您可以做的是更改 VS 服务引用生成器自动生成的代码,以便代理上方法调用的参数类型接受与字符串基本相同的类型,但序列化本身作为 CDATA 部分。这种类型是基于 Marc Gravell 为回答另一个问题而编写的代码提供的。这样做的问题是,如果有人在 VS 中对该服务引用使用“更新引用”命令,则您所做的任何更改都将丢失。

因此,相反,使用 svcutil 命令行实用程序生成引用(与普遍的看法相反,VS 不使用此工具 - 遗憾的是它更灵活),手动将其生成的配置和代码导入到您的项目中,然后摆脱“服务参考”。这样,您就可以随意修改代码,并且可以轻松地在 VS 的项目树中看到它。