diff --git a/src/redmine-net-api/Serialization/Xml/XmlRedmineSerializer.cs b/src/redmine-net-api/Serialization/Xml/XmlRedmineSerializer.cs index 179eaec0..74c26aea 100644 --- a/src/redmine-net-api/Serialization/Xml/XmlRedmineSerializer.cs +++ b/src/redmine-net-api/Serialization/Xml/XmlRedmineSerializer.cs @@ -27,7 +27,7 @@ namespace Redmine.Net.Api.Serialization internal sealed class XmlRedmineSerializer : IRedmineSerializer { - public XmlRedmineSerializer(): this(new XmlWriterSettings + public XmlRedmineSerializer() : this(new XmlWriterSettings { OmitXmlDeclaration = true }) { } @@ -126,6 +126,11 @@ public string Serialize(T entity) where T : class var limit = xmlReader.ReadAttributeAsInt(RedmineKeys.LIMIT); var result = xmlReader.ReadElementContentAsCollection(); + if (totalItems == 0 && result.Count > 0) + { + totalItems = result.Count; + } + return new PagedResults(result, totalItems, offset, limit); } } diff --git a/src/redmine-net-api/Types/IssueAllowedStatus.cs b/src/redmine-net-api/Types/IssueAllowedStatus.cs index 2df5b42a..35a1478c 100644 --- a/src/redmine-net-api/Types/IssueAllowedStatus.cs +++ b/src/redmine-net-api/Types/IssueAllowedStatus.cs @@ -15,7 +15,10 @@ limitations under the License. */ using System.Diagnostics; +using System.Xml; using System.Xml.Serialization; +using Newtonsoft.Json; +using Redmine.Net.Api.Extensions; namespace Redmine.Net.Api.Types { @@ -26,6 +29,43 @@ namespace Redmine.Net.Api.Types [XmlRoot(RedmineKeys.STATUS)] public sealed class IssueAllowedStatus : IdentifiableName { + /// + /// + /// + public bool? IsClosed { get; internal set; } + + /// + public override void ReadXml(XmlReader reader) + { + Id = reader.ReadAttributeAsInt(RedmineKeys.ID); + Name = reader.GetAttribute(RedmineKeys.NAME); + IsClosed = reader.ReadAttributeAsBoolean(RedmineKeys.IS_CLOSED); + reader.Read(); + } + + /// + public override void ReadJson(JsonReader reader) + { + while (reader.Read()) + { + if (reader.TokenType == JsonToken.EndObject) + { + return; + } + + if (reader.TokenType == JsonToken.PropertyName) + { + switch (reader.Value) + { + case RedmineKeys.ID: Id = reader.ReadAsInt(); break; + case RedmineKeys.NAME: Name = reader.ReadAsString(); break; + case RedmineKeys.IS_CLOSED: IsClosed = reader.ReadAsBoolean(); break; + default: reader.Read(); break; + } + } + } + } + private string DebuggerDisplay => $"[{nameof(IssueAllowedStatus)}: {ToString()}]"; } } \ No newline at end of file diff --git a/src/redmine-net-api/Types/TrackerCoreField.cs b/src/redmine-net-api/Types/TrackerCoreField.cs index 1777883f..5f8edf54 100644 --- a/src/redmine-net-api/Types/TrackerCoreField.cs +++ b/src/redmine-net-api/Types/TrackerCoreField.cs @@ -13,7 +13,7 @@ namespace Redmine.Net.Api.Types /// /// [DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")] - [XmlRoot(RedmineKeys.TRACKER)] + [XmlRoot(RedmineKeys.FIELD)] public sealed class TrackerCoreField: IXmlSerializable, IJsonSerializable, IEquatable { /// @@ -40,7 +40,6 @@ public XmlSchema GetSchema() /// /// /// - /// public void ReadXml(XmlReader reader) { reader.Read(); @@ -66,7 +65,6 @@ public void WriteJson(JsonWriter writer) { } /// /// /// - /// public void ReadJson(JsonReader reader) { while (reader.Read()) diff --git a/src/redmine-net-api/Types/WikiPage.cs b/src/redmine-net-api/Types/WikiPage.cs index bba1fcf7..e5acd51b 100644 --- a/src/redmine-net-api/Types/WikiPage.cs +++ b/src/redmine-net-api/Types/WikiPage.cs @@ -123,7 +123,16 @@ public override void ReadXml(XmlReader reader) case RedmineKeys.TITLE: Title = reader.ReadElementContentAsString(); break; case RedmineKeys.UPDATED_ON: UpdatedOn = reader.ReadElementContentAsNullableDateTime(); break; case RedmineKeys.VERSION: Version = reader.ReadElementContentAsInt(); break; - case RedmineKeys.PARENT: ParentTitle = reader.GetAttribute(RedmineKeys.PARENT); break; + case RedmineKeys.PARENT: + { + if (reader.HasAttributes) + { + ParentTitle = reader.GetAttribute(RedmineKeys.TITLE); + reader.Read(); + } + + break; + } default: reader.Read(); break; } } @@ -206,14 +215,28 @@ public override bool Equals(WikiPage other) { if (other == null) return false; - return Id == other.Id - && Title == other.Title - && Text == other.Text - && Comments == other.Comments + return base.Equals(other) + && string.Equals(Title, other.Title, StringComparison.Ordinal) + && string.Equals(Text, other.Text, StringComparison.Ordinal) + && string.Equals(Comments, other.Comments, StringComparison.Ordinal) && Version == other.Version - && Author == other.Author - && CreatedOn == other.CreatedOn - && UpdatedOn == other.UpdatedOn; + && Equals(Author, other.Author) + && CreatedOn.Equals(other.CreatedOn) + && UpdatedOn.Equals(other.UpdatedOn) + && Equals(Attachments, other.Attachments); + } + + /// + /// + /// + /// + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals(obj as WikiPage); } /// @@ -236,6 +259,28 @@ public override int GetHashCode() return hashCode; } } + + /// + /// + /// + /// + /// + /// + public static bool operator ==(WikiPage left, WikiPage right) + { + return Equals(left, right); + } + + /// + /// + /// + /// + /// + /// + public static bool operator !=(WikiPage left, WikiPage right) + { + return !Equals(left, right); + } #endregion ///