- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在 ASP.NET 网络服务上有一个 WebMethod,它返回一个枚举数组。如果添加了一个新值,并且该值由函数调用返回,则 Web 服务的使用者将抛出异常,即使它不关心该枚举值。
[WebMethod]
public UserRole[] GetRoles(string token)
部分 wsdl:
<s:simpleType name="UserRole">
<s:restriction base="s:string">
<s:enumeration value="Debug" />
<s:enumeration value="EventEditor" />
<s:enumeration value="InvoiceEntry" />
</s:restriction>
</s:simpleType>
(Consumer 是用这个 wsdl 编译的,但是 wsdl 改变了,现在允许一个新值——如果返回那个值,客户端会抛出一个 XML 异常。)
有什么方法可以覆盖此类型的 SOAP 反序列化,以便我可以捕获错误并从数组中删除该项目或将其替换为默认值?如果这是使用 JSON 而不是 XML,我可以注册一个 JsonConverter 来处理该类型,所以我想我正在寻找一个类似的全局“RegisterConverter”类型函数。我认为这不存在,但希望得到一些帮助...
任何用属性装饰枚举的方法都不起作用,因为所有代码都是由 wsdl 生成的,并且在更新 Web 引用时重新生成。通常,如果我想修改一个由 wsdl 生成的类,我可以创建一个部分类,但这对 Enum 不起作用。甚至不确定我是否可以覆盖 XmlSerialization 代码,即使它是一个类。
一些额外的背景:
这实际上是作为我对动态枚举的尝试而实现的。 wsdl 是从数据库查找生成的,这样我就可以向数据库添加额外的值,并且消费应用程序将可以访问允许的值,而无需重新编译 web 服务。通过这种方式,我可以通过枚举类型获得智能感知和约束实现,但能够在不紧密耦合 Web 服务代码和客户端代码的情况下添加值。问题是,如果我添加一个新值,它可能会破坏未使用新 wsdl 更新的消费者......我宁愿忽略该值,因为消费者不知道如何处理无论如何。
SOAP 扩展可能是解决此问题的方法(我知道如何将 SOAP 扩展添加到 WebService 本身,但不知道如何在客户端添加一个......),但这并不理想,因为我我真的很想有一种通用的方法来轻松地处理这个问题,这样我就可以在我的代码中有更多的动态枚举(它们不是真正的动态,但想法是这些值通过 web 服务的中间层传递而不必重新编译那个中间层)。像“XmlSerialization.RegisterConverter(MyDynamicEnumType, DynamicEnum.Convert)”这样的东西是理想的,我可以在其中定义一个通用函数来使用和注册。)
最佳答案
仍然希望其他人能得到答案,但我至少想出了比我最初使用 Regex.Replace 去除对我不认识的枚举值的引用更好的想法。
我正在为 Web 服务使用部分类并覆盖 GetReaderForMessage,如下所示:
namespace Program.userws //note this namespace must match the namespace
//that the webservice is declared in (in auto-generated code)
{
partial class UserWebService
{
protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize)
{
return new EnumSafeXmlReader(message.Stream);
}
}
}
这是 EnumSafeXmlReader 的定义:
public class EnumSafeXmlReader : XmlTextReader
{
private Assembly _callingAssembly;
public EnumSafeXmlReader(Stream input) : base(input)
{
_callingAssembly = Assembly.GetCallingAssembly();
}
public override string ReadElementString()
{
string typename = this.Name;
var val = base.ReadElementString();
var possibleTypes = _callingAssembly.GetTypes().Where(t => t.Name == typename);
Type enumType = possibleTypes.FirstOrDefault(t => t.IsEnum);
if (enumType != null)
{
string[] allowedValues = Enum.GetNames(enumType);
if (!allowedValues.Contains(val))
{
val = Activator.CreateInstance(enumType).ToString();
}
}
return val;
}
}
我还为 UserRole 添加了一个新值 - UserRole.Unknown
, 并确保它是允许值列表中的第一个。
<s:simpleType name="AcctUserRole">
<s:restriction base="s:string">
<s:enumeration value="Unknown"/>
<s:enumeration value="Debug"/>
<s:enumeration value="EventEditor"/>
<s:enumeration value="InvoiceEntry"/>
</s:restriction>
</s:simpleType>
所以只要这个枚举的值被包装在一个类型名称为<UserRole>UnexpectedRole</UserRole>
的标签中, 如果无法识别,将替换为 UserRole.Unknown
,我的客户可以愉快地忽略它。请注意,如果有另一个名为 UserRole
的标签,这也可能会中断。那不是这种枚举类型,应该是字符串或整数。它相当脆弱。
这个解决方案还有很多不足之处,但它通常适用于枚举值列表......
<GetRolesForUserResult>
<UserRole>InvoiceEntry</UserRole>
<UserRole>UnexpectedRole</UserRole>
</GetRolesForUserResult>
这最终会导致 UserRole[]
包含 UserRole.InvoiceEntry
和 UserRole.Unknown
.
但是如果我有一个 UserRole 类型的字段或属性:
<User>
<ID>5</ID>
<Name>Zorak</Name>
<PrimaryRole>UnexpectedRole</PrimaryRole> <!-- causes an exception -->
</User>
这仍然会失败,因为 Reader 无法知道“PrimaryRole”需要反序列化以键入 UserRole。 XmlSerializer 知道这一点,但据我所知,没有办法覆盖 XmlSerializer,只能覆盖 XmlReader。
我想给 EnumSafeXml 阅读器提供足够的信息来识别将反序列化为枚举类型的标签并非完全不可能,但它比我现在愿意去的麻烦更多 - 我特别需要它在“枚举值数组”案例,它现在这样做了。
我确实在类型上添加了一些缓存,这样我只需检查一次标签名称,看看它是否也是枚举的名称,但为了清楚起见,我在这个例子中删除了它。
我欢迎任何其他可能的解决方案或改进此解决方案的建议。
关于c# - 忽略 SOAP 反序列化中的无效枚举值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146110/
我是 python 的新手。我试图找到我的文本的频率分布。这是代码, import nltk nltk.download() import os os.getcwd() text_file=open(
我对安卓 fragment 感到困惑。我知道内存 fragment 但无法理解什么是 android fragment 问题。虽然我发现很多定义,比如 Android fragmentation re
尝试对 WordPress 进行 dockerise 我发现了这个场景: 2个数据卷容器,一个用于数据库(bbdd),另一个用于wordpress文件(wordpress): sudo docker
这个问题已经有答案了: From the server is there a way to know that my page is being loaded in an Iframe (1 个回答)
我正在玩小型服务器,试图对运行在其上的服务进行docker化。为简化起见,假设我必须主要处理:Wordpress和另一项服务。 在Docker集线器上有许多用于Wordpress的图像,但是它们似乎都
我想要发生的是,当帐户成功创建后,提交的表单应该消失,并且应该出现一条消息(取决于注册的状态)。 如果成功,他们应该会看到一个简单的“谢谢。请检查您的电子邮件。” 如果不是,那么他们应该会看到一条适当
就是这样,我需要为客户添加一个唯一标识符。通过 strip 元数据。这就是我现在完全构建它的方式,但是我只有最后一部分告诉我用户购买了哪个包。 我试着看这里: Plans to stripe 代码在这
我有一个类将执行一些复杂的操作,涉及像这样的一些计算: public class ComplexAction { public void someAction(String parameter
这个问题已经有答案了: maven add a local classes directory to module's classpath (1 个回答) 已关闭10 年前。 我有一些不应更改的旧 E
我使用 fragment 已经有一段时间了,但我经常遇到一个让我烦恼的问题。 fragment 有时会相互吸引。现在,我设法为此隔离了一个用例,它是这样的: Add fragment A(也使用 ad
我的 html 中有一个 ol 列表,上面有行条纹。看起来行条纹是从数字后面开始的。有没有办法让行条纹从数字开始? 我已经包含了正在发生的事情的片段 h4:nth-child(even) {
如何仅使用 css 将附加图像 html 化? 如果用纯 css 做不到,那我怎么能至少用一个图像来做 最佳答案 这不是真正的问题,而是您希望我们为您编写代码。我建议您搜索“css breadcrum
以下是 Joshua 的 Effective Java 的摘录: If you do synchronize your class internally, you can use various te
在这里工作时,我们有一个框向业务合作伙伴提供 XML 提要。对我们的提要的请求是通过指定查询字符串参数和值来定制的。其中一些参数是必需的,但很多不是。 例如,我们要求所有请求都指定一个 GUID 来标
我有 3 个缓冲区,其中包含在 32 位处理器上运行的 R、G、B 位数据。 我需要按以下方式组合三个字节: R[0] = 0b r1r2r3r4r5r6r7r8 G[0] = 0b g1g2g3g4
我最近发现了关于如何使用 History.js、jQuery 和 ScrollTo 通过 HTML5 History API 对网站进行 Ajax 化的要点:https://github.com/br
我们有一个 Spring Boot 应用程序,由于集成需要,它变得越来越复杂——比如在你这样做之后发送一封电子邮件,或者在你之后广播一条 jms 消息等等。在寻找一些更高级别的抽象时,我遇到了 apa
我正在尝试首次实施Google Pay。我面临如何指定gateway和gatewayMarchantId的挑战。 我所拥有的是google console帐户,不知道在哪里可以找到此信息。 priva
昨天下午 3 点左右,我为两个想要从一个 Azure 帐户转移到另一个帐户的网站设置了 awverify 记录。到当天结束时,Azure 仍然不允许我添加域,所以我赌了一把,将域和 www 子域重新指
我正在使用terms facet在elasticsearch服务器中获取顶级terms。现在,我的标签"indian-government"不被视为一个标签。将其视为"indian" "governm
我是一名优秀的程序员,十分优秀!