标签: datacontractserializer

WCF Datacontract,某些字段不反序列化

问题:

我有一个WCF服务设置作为来自外部系统的呼叫的端点.该调用是发送普通的xml.我正在通过使用RequestBuilder从Fiddler向服务发送调用来测试系统.

问题是我的所有字段都被反序列化,但两个字段除外.price_retailprice_wholesale.

我错过了什么?所有其他字段反序列化没有问题 - 服务响应.只是这些领域.

XML消息:

<widget_conclusion>
    <list_criteria_id>123</list_criteria_id>
    <list_type>consumer</list_type>
    <qty>500</qty>
    <price_retail>50.00</price_retail>
    <price_wholesale>40.00</price_wholesale>
    <session_id>123456789</session_id>
</widget_conclusion>
Run Code Online (Sandbox Code Playgroud)

服务方式:

public string WidgetConclusion(ConclusionMessage message)
{
    var priceRetail = message.PriceRetail;
}
Run Code Online (Sandbox Code Playgroud)

消息类:

[DataContract(Name = "widget_conclusion", Namespace = "")]
public class ConclusionMessage  
{
    [DataMember(Name = "list_criteria_id")]
    public int CriteriaId  { get; set;}
    [DataMember(Name = "list_type")]
    public string ListType { get; set; }
    [DataMember(Name = "qty")]
    public int ListQuantity { get; set; }
    [DataMember(Name = "price_retail")]
    public decimal PriceRetail { get; set; } …
Run Code Online (Sandbox Code Playgroud)

wcf datacontractserializer

28
推荐指数
1
解决办法
1万
查看次数

忽略DataContractSerializer中的字段顺序

反序列化时,DataContractSerializer不仅要求元素名称匹配,还要求它与其他元素的顺序相同.

我的应用程序是这样的,每个字段都可以通过其名称唯一标识.因此,我希望XML文件可以按任何顺序包含元素,并且反序列化器仍然可以工作.

是否可以像这样设置DataContract?

数据成员订单中的介绍性段落建议可选择强制执行订单,但我还没有找到实际使其可选的方法.

后续问题:使用DataContractSerializer进行简单的数据文件版本控制

.net datacontractserializer

27
推荐指数
1
解决办法
6063
查看次数

WCF服务参考 - 获取"XmlException:名称不能以'<'字符开头,十六进制值0x3C"在客户端

我有一个智能客户端应用程序通过WCF与其服务器通信.数据在客户端上创建,然后通过服务发送以进行持久化.服务器和客户端通过共享dll使用相同的域类,我在Visual Studio中使用方便的"添加服务引用"功能包装SvcUtil.exe并生成客户端和代理类.

尝试调用服务时出现以下错误:

System.Xml.XmlException occurred
  Message=Name cannot begin with the '<' character, hexadecimal value 0x3C.
  Source=System.Xml
  LineNumber=0
  LinePosition=1
  StackTrace:
       at System.Xml.XmlConvert.VerifyNCName(String name, ExceptionType exceptionType)
  InnerException: 
Run Code Online (Sandbox Code Playgroud)

这特别麻烦,因为该服务一次可以工作数周而不会发生此错误,然后突然且没有警告它将再次出现.我根本无法找出导致它的原因.当它确实发生时,我会深入研究如何解决它,并且通常不会提出任何比实际尝试以编程方式将事物序列化为xml而遇到相同错误的人.我只使用生成的客户端和代理来尝试发送此数据.

我已经查看Service References\AwesomeService了我的解决方案文件夹中生成的代理,看不到任何与众不同的内容.生成的文件中唯一出现的尖括号是:

  • *.svcinfo,Reference.svcmap,AwesomeService.disco,AwesomeService.wsdl和*.xsd文件中的xml标记
  • Reference.cs文件中泛型集合的参数

我用来调用服务的代码是这样的:

using (var client = new AwesomeServiceClient())
{
    client.SaveAwesomeness(instanceOfAwesomeness);
}
Run Code Online (Sandbox Code Playgroud)

这是在上面列出的调用代码上方的第一帧开始的堆栈:

System.Xml.dll!System.Xml.XmlConvert.VerifyNCName(string name, System.Xml.ExceptionType exceptionType) + 0xb5 bytes 
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.IsValidNCName(string name) + 0x27 bytes  
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.EncodeLocalName(string localName) + 0x1d bytes   
System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ImportDataMembers() + 0x2e1 bytes   
System.Runtime.Serialization.dll!System.Runtime.Serialization.ClassDataContract.ClassDataContractCriticalHelper.ClassDataContractCriticalHelper(System.Type type) + 0x10d bytes 
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(int id, System.RuntimeTypeHandle typeHandle, System.Type type) + 0x198 bytes   
System.Runtime.Serialization.dll!System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(int id, …
Run Code Online (Sandbox Code Playgroud)

.net c# wcf serialization datacontractserializer

24
推荐指数
2
解决办法
2万
查看次数

wcf将enum反序列化为字符串

我正在尝试使用WCF使用RESTful Web服务.我无法控制Web服务的格式,所以我必须在这里和那里做一些解决方法.然而,我似乎无法解决的一个主要问题是如何使WCF将枚举反序列化为字符串.

这是我的代码(显然名称已更改):

[DataContract]
public enum Foo
{
    [EnumMember( Value = "bar" )]
    Bar,

    [EnumMember( Value = "baz" )]
    Baz
}

[DataContract]
public class UNameIt
{
    [DataMember( Name = "id" )]
    public long Id { get; private set; }

    [DataMember( Name = "name" )]
    public string Name { get; private set; }

    [DataMember( Name = "foo" )]
    public Foo Foo { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

这是反序列化失败的返回数据:

{
     "id":123456,
     "name":"John Doe",
     "foo":"bar"
}
Run Code Online (Sandbox Code Playgroud)

最后,抛出异常:

反序列化Service.Foo类型的对象时出错.值'bar'无法解析为'Int64'类型.

我不想切换到使用XmlSerializer,因为在它的许多其他缺点中,它不会让我在属性上拥有私有的setter.

如何使WCF(或者,DataContractSerializer)将我的枚举视为字符串值?

编辑:这似乎是不可能的,行为是它的设计方式.谢谢微软,不给我们选择,不得不诉诸黑客.按照somori建议的方式这样做似乎是获得带有JSON和WCF的字符串枚举的唯一方法.

.net c# wcf enums datacontractserializer

20
推荐指数
1
解决办法
1万
查看次数

通过WCF传递匿名类型的实例

我有一个WCF服务方法,它期望一个对象,然后使用反射检索其属性.

在客户端,我创建了一个匿名类型对象

var obj = new {FirstName="John", LastName="Doe"}
Run Code Online (Sandbox Code Playgroud)

并将其传递给方法.我得到一个例外:

Type '<>f__AnonymousType0`2[System.String,System.String]' cannot be serialized. 
Consider marking it with the DataContractAttribute attribute, and marking all 
of its members you want serialized with the DataMemberAttribute attribute.  
See the Microsoft .NET Framework documentation for other supported types.
Run Code Online (Sandbox Code Playgroud)

我无法使用序列化属性标记类型或其成员,因为实际上没有明确声明的类型或属性.有没有办法克服这个问题?

wcf anonymous-types datacontract datacontractserializer

20
推荐指数
2
解决办法
7704
查看次数

DataContractSerializer - 更改命名空间并反序列化绑定到旧命名空间的文件

我有一个序列化的数据类DataContractSerializer.该类使用[DataContract]没有显式Namespace声明的属性.因此,生成的xml文件中的命名空间是基于类的命名空间生成的.

该课程基本上如下:

namespace XYZ
{
   [DataContract]
   public class Data
   {
      [DataMember(Order = 1)]
      public string Prop1 { get; set; }

      [DataMember(Order = 2)]
      public int Prop2 { get; set; }
   }
}
Run Code Online (Sandbox Code Playgroud)

...以及生成的xml:

<?xml version="1.0" encoding="utf-8"?>
<Data xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/XYZ">
   <Prop1>StringValue</Prop1>
   <Prop2>11</Prop2>
</Data>
Run Code Online (Sandbox Code Playgroud)

现在我想通过将[DataContract]属性更改为更改类的名称空间(实际上将其删除)[DataContract(Namespace = "")].但是,一旦我执行此操作,之前使用原始命名空间序列化的文件不再反序列化.我收到以下异常:

Error in line 1 position XXX. Expecting element 'Data' from namespace ''.. Encountered 'Element' with name 'Data', namespace 'http://schemas.datacontract.org/2004/07/XYZ'.

这很有道理.我更改了命名空间.我很好.但是,似乎必须有一种方法可以告诉它DataContractSerializer继续并反序列化该数据,即使名称空间不匹配.

.net c# datacontractserializer

20
推荐指数
1
解决办法
1万
查看次数

Linq to Xml VS XmlSerializer VS DataContractSerializer

在我看来web method,我得到了一些第三方C#实体类的对象.实体类只不过是DataContract.这个实体类非常复杂,具有各种类型的属性,一些属性也是集合.当然,这些链接类型也是DataContracts.

我想将该DataContract实体序列化为XML,作为我的Web服务的业务逻辑的一部分.我不能DataContractSerializer直接使用(在我在web方法中收到的对象),因为XML模式完全不同. 因此,DataContractSerializer生成的XML不会针对模式进行验证.

我无法总结出我应该遵循的方法来实施.我可以想到以下实施方法:

  1. LINQ to XML - 这看起来不错,但我需要为每种类型的对象手动创建XML树(即类实例的元素或XML表示).由于有许多实体类并且它们彼此链接,我认为手动编写XML元素太多了.此外,当实体类引入一些新属性时,我将不得不继续修改XML树.不仅如此,我生成XML树的代码看起来有点笨拙(至少在外观上)并且将来很难被其他开发人员维护/更改; 他/她将不得不仔细研究它以了解如何生成XML.

  2. XmlSerializer - 我可以编写自己的实体类来表示我想要的XML结构.现在,我需要将传入对象的详细信息复制到我自己的类的对象中.所以这是额外的工作(对于.NET,当代码执行时也是如此!).然后我可以XmlSerializer在我的对象上使用生成XML.在这种情况下,我将不得不创建实体类,每当第三方实体被修改时,我只需要在我的类中添加新属性.(使用XmlElement或XmlAttibute属性).但人们推荐DataContractSerializer这个,所以我不想最终确定这个,除非我清楚所有方面.

  3. DataContractSerializer - 再次在这里,我将不得不编写自己的实体类,因为我无法控制第三方DataContracts.我需要将传入对象的细节复制到我自己的类的对象中.所以这是额外的工作.但是,由于DataContractSerializer不支持Xml属性,因此我必须IXmlSerializableWriteXml方法中实现并生成所需的Xml .DataContractSerializer比XmlSerializer更快,但如果第三方实体发生变化,我将不得不处理更改(在WriteXml中).

问题:

  • 考虑到性能,在这种情况下哪种方法最好?
  • 你能建议一些更好的方法吗?
  • 当传入的实体类可能发生变化时,是否DataContractSerializer值得考虑(因为它具有更好的性能XmlSerilaizer)?
  • LINQ应该真的用于序列化吗?或者除了查询之外的其他内容真的有用吗?
  • 在这种情况下,XmlSerializer可以优于LINQ吗?如果是,为什么?

serialization xml-serialization .net-4.0 linq-to-xml datacontractserializer

20
推荐指数
2
解决办法
6473
查看次数

DataContractJsonSerializer跳过具有空值的节点

DataContractJsonSerializer用来将我的自定义对象序列化为JSON.但我想跳过其值为的数据成员null.如果DataMembernull该节点不应该在JSON字符串.

我怎样才能做到这一点?给我一个简单code snippet的工作.

c# serialization datacontractserializer datacontractjsonserializer

20
推荐指数
1
解决办法
1万
查看次数

在DataContract中设置默认值?

如何为DataMember设置默认值,例如下面显示的值:

我想默认设置ScanDevice ="XeroxScan"

    [DataMember]
    public string ScanDevice { get; set; }
Run Code Online (Sandbox Code Playgroud)

c# wcf datacontractserializer

19
推荐指数
2
解决办法
1万
查看次数

如何在数据协定中未设置Data成员字段时,如何不返回null

我的WCF服务有一个奇怪的问题,它以JSON格式返回数据.我想根据客户发送的请求返回有关"客户"的信息.

客户可以请求他们需要的客户的哪些信息领域以及仅发送有关客户的信息的服务需求.

例如:如果客户端要求客户列表并说他们想要每个客户的名字,姓氏,城市,那么服务器应该发送一个带有每个字段名称和相应值的json响应

就像是...

[
  {"firstname":"john","lastname":"Goodman","city" :"NY"},
  {"firstname":"brad","lastname":"newman","city" :"LA"}
]
Run Code Online (Sandbox Code Playgroud)

如果客户端仅询问具有ID和城市字段的客户列表,则响应应如下所示

[
  {"id" :"1234","city" :"NY"},
  {"id":"1235","city" :"LA"}
]
Run Code Online (Sandbox Code Playgroud)

我最初的设计是实现一个"客户"类,然后将每个可能的"字段"作为该类的一个字段.然后在我的服务方法中,我获取客户端指定的字段列表,并仅使用这些属性集实例化客户对象.

我的运营合同是这样的

[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, UriTemplate = "Customers?fields={value}")]
List<Customer> GetCustomers(string value);
Run Code Online (Sandbox Code Playgroud)

但问题是我用"DataContract"装饰类,每个Field为"DataMember"....如果没有设置某些属性,它们在发送到客户端时仍然会被反序列化为NULL.我不希望这种情况发生.

此外,客户的可能字段列表很长,所以课程变得非常大.我宁愿将这些字段存储为我的服务中的枚举集合而不是类的字段.

然后我想到让我的操作返回a IDictionary<string,object>然后迭代地将每个字段和值添加到此集合中.这不起作用,因为,当字典被序列化时,它显示{"Key:dfas", "Value:34"}等等而不是我想要的

所以我有点卡住了.解决这个问题的最佳方法是什么?

我可以这样标记[DataContract]如果[DataMember]没有设置属性,即null,那么它们不应该被序列化并发送给客户端吗?

wcf serialization json datacontractserializer

18
推荐指数
1
解决办法
1万
查看次数