Ответ 1
Свойство FooSpecified
используется для управления необходимостью сериализации свойства Foo
. Если вы всегда хотите сериализовать свойство, просто удалите свойство FooSpecified
.
Я использую xml-сериализацию в моем проекте для сериализации и десериализации объектов на основе xml-схемы. Я использовал инструмент xsd для создания классов для использования при сериализации/десериализации объектов.
Когда я перехожу к сериализации объекта перед отправкой, я вынужден установить для свойства * Specified значение true, чтобы заставить сериализатор сериализовать все пропозиции, которые не относятся к типу string
.
Есть ли способ заставить сериализацию всех свойств без необходимости устанавливать свойство * Specified в значение true?
Свойство FooSpecified
используется для управления необходимостью сериализации свойства Foo
. Если вы всегда хотите сериализовать свойство, просто удалите свойство FooSpecified
.
Я знаю, что это старый вопрос, но ни один из других ответов (за исключением, возможно, предложения использования Xsd2Code) действительно создает идеальное решение, когда вы генерируете код как часть своей сборки, а ваш .xsd может несколько раз меняться в течение одного цикла выпуска.
Легкий способ получить то, что я действительно хотел, и все еще использовать xsd.exe, было запустить сгенерированный файл через простой постпроцессор. Код для постпроцессора выглядит следующим образом:
namespace XsdAutoSpecify
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length != 1)
{
throw new ArgumentException("Specify a file name");
}
string fileName = args[0];
Regex regex = new Regex(".*private bool (?<fieldName>.*)Specified;");
IList<string> result = new List<string>();
IDictionary<string, string> edits = new Dictionary<string, string>();
foreach (string line in File.ReadLines(fileName))
{
result.Add(line);
if (line.Contains("public partial class"))
{
// Don't pollute other classes which may contain like-named fields
edits.Clear();
}
else if (regex.IsMatch(line))
{
// We found a "private bool fooSpecified;" line. Add
// an entry to our edit dictionary.
string fieldName = regex.Match(line).Groups["fieldName"].Value;
string lineToAppend = string.Format("this.{0} = value;", fieldName);
string newLine = string.Format(" this.{0}Specified = true;", fieldName);
edits[lineToAppend] = newLine;
}
else if (edits.ContainsKey(line.Trim()))
{
// Use our edit dictionary to add an autospecifier to the foo setter, as follows:
// set {
// this.fooField = value;
// this.fooFieldSpecified = true;
// }
result.Add(edits[line.Trim()]);
}
}
// Overwrite the result
File.WriteAllLines(fileName, result);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Environment.Exit(-1);
}
}
}
}
В результате создается код, похожий на следующий:
[System.Xml.Serialization.XmlAttributeAttribute()]
public barEnum foo {
get {
return this.fooField;
}
set {
this.fooField = value;
this.fooFieldSpecified = true;
}
}
Вы можете добавить значение по умолчанию к своей схеме, а затем использовать DefaultValueAttribute.
Например, в вашей схеме может быть следующее:
<xs:element name="color" type="xs:string" default="red"/>
И затем следующее свойство для сериализации:
[DefaultValue(red)]
public string color { get; set; }
Это должно заставить свойство цвета всегда сериализоваться как "красное", если оно явно не установлено на что-то еще.
Мы обнаружили, что ответ на этот вопрос состоит в том, чтобы убедиться, что все элементы схемы определены как типы данных string
. Это позволит убедиться, что сериализатор сериализует все поля без использования коррелированного * указанного свойства.