diff --git a/.gitignore b/.gitignore
index b426c33..3f4ccbe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,4 @@ Tools/NuGet/mxtires.microdata.1.0.3.4.nupkg1/lib/net45/MXTires.Microdata.XML
Tools/NuGet/mxtires.microdata.1.0.3.4.nupkg1/lib/net461/MXTires.Microdata.XML
Tools/NuGet/mxtires.microdata.1.0.3.4.nupkg1/lib/net48/MXTires.Microdata.XML
Tools/NuGet/mxtires.microdata.1.0.3.4.nupkg1/package/services/metadata/core-properties/a5ad0c42a2cb49b9b6ac94c92fc9d3d1.psmdcp
+.vs/
diff --git a/Intangible/MemberProgramTier.cs b/Intangible/MemberProgramTier.cs
new file mode 100644
index 0000000..8e592f5
--- /dev/null
+++ b/Intangible/MemberProgramTier.cs
@@ -0,0 +1,43 @@
+#region License
+// Copyright (c) 2026 1010Tires.com
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using Newtonsoft.Json;
+
+namespace MXTires.Microdata.Intangible
+{
+ ///
+ /// A membership program tier, for example a club card tier, frequent flyer tier, etc.
+ ///
+ public class MemberProgramTier : Thing
+ {
+ ///
+ /// Text - A requirement for a user to join a membership tier, for example: a CreditCard if the tier requires sign up for a credit card,
+ /// A textual summary of the required threshold or expectations to meet the tier.
+ ///
+ /// The tier requirement.
+ [JsonProperty("tierRequirement")]
+ public string TierRequirement { get; set; }
+ }
+}
diff --git a/Intangible/Offer.cs b/Intangible/Offer.cs
index 1e2b21c..0db5705 100644
--- a/Intangible/Offer.cs
+++ b/Intangible/Offer.cs
@@ -40,7 +40,10 @@ public object PriceSpecification
get { return priceSpecification; }
set
{
- var validator = new TypeValidator(typeof(PriceSpecification), typeof(IList));
+ var validator = new TypeValidator(
+ "MXTires.Microdata.Intangible.StructuredValues.PriceSpecifications",
+ null,
+ new List() { typeof(PriceSpecification), typeof(IList) });
validator.Validate(value);
priceSpecification = value;
}
diff --git a/MXTires.Microdata.csproj b/MXTires.Microdata.csproj
index 391c6e0..27731b2 100644
--- a/MXTires.Microdata.csproj
+++ b/MXTires.Microdata.csproj
@@ -1,7 +1,7 @@
- net461;net472;net48;netcoreapp3.1;net5.0;net6.0
- 1.0.4.5
+ net461;net472;net48;net6.0;net8.0
+ 1.0.4.6
1010Tires.com Inc.
1010Tires.com Inc.
Copyright© 1010Tires.com Inc. 2023. All rights reserved.
@@ -13,8 +13,8 @@
true
MXTires.MicroData.snk
https://github.com/idenys/MXTires.Microdata
- 1.0.4.5
- 1.0.4.5
+ 1.0.4.6
+ 1.0.4.6
MXTires.Microdata
README.md
latest
@@ -38,7 +38,7 @@
-
+
diff --git a/PriceSpecification.cs b/PriceSpecification.cs
index 9d493c2..72e5781 100644
--- a/PriceSpecification.cs
+++ b/PriceSpecification.cs
@@ -23,6 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
+using MXTires.Microdata.Intangible;
using Newtonsoft.Json;
using System;
@@ -36,8 +37,22 @@ public class PriceSpecification : Thing
#region Properties
- //eligibleQuantity QuantitativeValue The interval and unit of measurement of ordering quantities for which the offer or price specification is valid. This allows e.g. specifying that a certain freight charge is valid only for a certain quantity.
- //eligibleTransactionVolume PriceSpecification The transaction volume, in a monetary unit, for which the offer or price specification is valid, e.g. for indicating a minimal purchasing volume, to express free shipping above a certain order volume, or to limit the acceptance of credit cards to purchases to a certain minimal amount.
+ ///
+ /// QuantitativeValue - The interval and unit of measurement of ordering quantities for which the offer or price specification is valid.
+ /// This allows e.g. specifying that a certain freight charge is valid only for a certain quantity.
+ ///
+ /// The eligible quantity.
+ [JsonProperty("eligibleQuantity")]
+ public QuantitativeValue EligibleQuantity { get; set; }
+
+ ///
+ /// PriceSpecification - The transaction volume, in a monetary unit, for which the offer or price specification is valid,
+ /// e.g. for indicating a minimal purchasing volume, to express free shipping above a certain order volume,
+ /// or to limit the acceptance of credit cards to purchases to a certain minimal amount.
+ ///
+ /// The eligible transaction volume.
+ [JsonProperty("eligibleTransactionVolume")]
+ public PriceSpecification EligibleTransactionVolume { get; set; }
///
/// Number The highest price if the price is a range.
///
@@ -62,7 +77,24 @@ public class PriceSpecification : Thing
/// Text. The currency (in 3-letter ISO 4217 format) of the price or a price component, when attached to PriceSpecification and its subtypes.
///
/// The price currency.
+ [JsonProperty("priceCurrency")]
public string PriceCurrency { get; set; }
+
+ ///
+ /// Number or QuantitativeValue - The number of membership points earned by the member.
+ /// If necessary, the unitText can be used to express the units the points are issued in. (E.g. stars, miles, etc.)
+ ///
+ /// The membership points earned.
+ [JsonProperty("membershipPointsEarned")]
+ public QuantitativeValue MembershipPointsEarned { get; set; }
+
+ ///
+ /// MemberProgramTier - The membership program tier an Offer (or a PriceSpecification, OfferShippingDetails,
+ /// or MerchantReturnPolicy under an Offer) is valid for.
+ ///
+ /// The eligible member tier.
+ [JsonProperty("eligibleMemberTier")]
+ public MemberProgramTier EligibleMemberTier { get; set; }
///
/// The date when the item becomes valid.
diff --git a/Products/Product.cs b/Products/Product.cs
index 5e5b19a..2321ea7 100644
--- a/Products/Product.cs
+++ b/Products/Product.cs
@@ -26,8 +26,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Web;
using MXTires.Microdata.Intangible;
using MXTires.Microdata.Intangible.Enumeration;
using Newtonsoft.Json.Converters;
diff --git a/Tests/MXTires.Microdata.Tests.csproj b/Tests/MXTires.Microdata.Tests.csproj
index 6133a94..fdfba4b 100644
--- a/Tests/MXTires.Microdata.Tests.csproj
+++ b/Tests/MXTires.Microdata.Tests.csproj
@@ -1,90 +1,22 @@
-
+
+
- Debug
- AnyCPU
- {E0A5D9F0-0521-4646-A2B7-C4A34B414F71}
- Library
- Properties
- MXTires.Microdata.Tests
- MXTires.Microdata.Tests
- v4.6.1
- 512
- {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
- $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
- False
- UnitTest
-
+ net48
+ false
+
+
+ true
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
+
+
-
- {f2a9b387-b954-4895-8ed7-ae95850b1bc1}
- MXTires.Microdata
-
+
-
-
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Tests/Properties/AssemblyInfo.cs b/Tests/Properties/AssemblyInfo.cs
deleted file mode 100644
index de3b693..0000000
--- a/Tests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MXTires.Microdata.Tests")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MXTires.Microdata.Tests")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("db146b1b-9f14-41bb-a7ea-d9efd4fad7b0")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Thing.cs b/Thing.cs
index 465c60f..8127969 100644
--- a/Thing.cs
+++ b/Thing.cs
@@ -25,11 +25,11 @@
using System;
using System.Collections.Generic;
+using MXTires.Microdata.CreativeWorks;
+using MXTires.Microdata.Intangible;
using MXTires.Microdata.Validators;
+using MXTires.Microdata.Intangible.StructuredValues;
using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
-using MXTires.Microdata.Intangible;
-using MXTires.Microdata.CreativeWorks;
namespace MXTires.Microdata
{
@@ -38,14 +38,38 @@ namespace MXTires.Microdata
///
public class Thing
{
-#pragma warning disable 0414
+ private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
+ {
+ NullValueHandling = NullValueHandling.Ignore
+ };
+
+ private static readonly TypeValidator ImageValidator =
+ new TypeValidator(new List { typeof(string), typeof(ImageObject), typeof(string[]), typeof(ImageObject[]) });
+
+ private static readonly TypeValidator MainEntityOfPageValidator =
+ new TypeValidator("MXTires.Microdata.CreativeWorks", null, new List { typeof(string), typeof(WebSite) });
+
+ private static readonly TypeValidator IdentifierValidator =
+ new TypeValidator("MXTires.Microdata.Intangible", null, new List { typeof(string), typeof(PropertyValue) });
+
+ private static readonly TypeValidator SubjectOfValidator =
+ new TypeValidator("MXTires.Microdata.CreativeWorks", null, new List { typeof(CreativeWork) });
+
+ private object context = "http://schema.org";
+ private object identifier;
+ private object image;
+ private object mainEntityOfPage;
+ private object subjectOf;
- object context = "http://schema.org";
///
/// Context
///
[JsonProperty("@context", Order = 1)]
- public virtual object Context { get { return context; } set { context = value; } }
+ public virtual object Context
+ {
+ get { return context; }
+ set { context = value; }
+ }
///
/// Property for External Extensions
@@ -56,7 +80,7 @@ public class Thing
/// Type tag
///
[JsonProperty("@type", Order = 2)]
- public virtual string Type { get { return this.GetType().Name; } }
+ public virtual string Type { get { return GetType().Name; } }
///
/// ID
@@ -70,33 +94,52 @@ public class Thing
/// 'typeof' attribute - for multiple types. Schema.org tools may have only weaker understanding of extra types, in particular those
/// defined externally.
///
- [JsonProperty("additionalType")]
+ [JsonProperty("additionalType", NullValueHandling = NullValueHandling.Ignore)]
public string AdditionalType { get; set; }
///
/// Text An alias for the item.
///
- [JsonProperty("alternateName")]
+ [JsonProperty("alternateName", NullValueHandling = NullValueHandling.Ignore)]
public string AlternateName { get; set; }
///
/// Text A short description of the item.
///
- [JsonProperty("description")]
+ [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public string Description { get; set; }
- object image;
///
- /// URL to an image of the item. This can be a URL or a fully described ImageObject.
+ /// Text - A sub property of description. A short description of the item used to disambiguate from other, similar items.
+ ///
+ [JsonProperty("disambiguatingDescription", NullValueHandling = NullValueHandling.Ignore)]
+ public string DisambiguatingDescription { get; set; }
+
+ ///
+ /// The identifier property represents any kind of identifier for any kind of Thing, such as ISBNs, GTIN codes, UUIDs etc.
+ /// Schema.org: PropertyValue | Text | URL
///
- [JsonProperty("image")]
+ [JsonProperty("identifier", NullValueHandling = NullValueHandling.Ignore)]
+ public object Identifier
+ {
+ get { return identifier; }
+ set
+ {
+ IdentifierValidator.Validate(value);
+ identifier = value;
+ }
+ }
+
+ ///
+ /// URL to an image of the item. This can be a URL or a fully described ImageObject.
+ ///
+ [JsonProperty("image", NullValueHandling = NullValueHandling.Ignore)]
public object Image
{
get { return image; }
set
{
- var validator = new TypeValidator(new List(){typeof(String), typeof(ImageObject), typeof(String[]), typeof(ImageObject[])});
- validator.Validate(value);
+ ImageValidator.Validate(value);
image = value;
}
}
@@ -104,30 +147,27 @@ public object Image
///
/// Text The name of the item.
///
- [JsonProperty("name")]
+ [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
///
/// Action - Indicates a potential Action, which describes an idealized action in which this thing would play an 'object' role.
///
- [JsonProperty("potentialAction")]
+
+ [JsonProperty("potentialAction", NullValueHandling = NullValueHandling.Ignore)]
public Microdata.Action PotentialAction { get; set; }
///
/// URL of a reference Web page that unambiguously indicates the item's identity. E.g. the URL of the item's Wikipedia page, Freebase page, or official website.
///
- [JsonProperty("sameAs")]
+ [JsonProperty("sameAs", NullValueHandling = NullValueHandling.Ignore)]
public IList SameAs { get; set; }
///
/// URL of the item.
///
- [JsonProperty("url")]
+ [JsonProperty("url", NullValueHandling = NullValueHandling.Ignore)]
public string Url { get; set; }
- #pragma warning restore 0414
-
- private object mainEntityOfPage;
-
///
/// URL or CreativeWork - Indicates a page (or other CreativeWork) for which this thing is the main entity being described.
/// Many (but not all) pages have a fairly clear primary topic, some entity or thing that the page describes. For example a restaurant's home page might be primarily about that Restaurant, or an event listing page might represent a single event. The mainEntity and mainEntityOfPage properties allow you to explicitly express the relationship between the page and the primary entity.
@@ -137,18 +177,32 @@ public object Image
/// about is similar to mainEntity, with two key differences. First, about can refer to multiple entities/topics, while mainEntity should be used for only the primary one. Second, some pages have a primary entity that itself describes some other entity. For example, one web page may display a news article about a particular person. Another page may display a product review for a particular product. In these cases, mainEntity for the pages should refer to the news article or review, respectively, while about would more properly refer to the person or product.
/// Inverse property: mainEntity.
///
- [JsonProperty("mainEntityOfPage")]
+ [JsonProperty("mainEntityOfPage", NullValueHandling = NullValueHandling.Ignore)]
public object MainEntityOfPage
{
get { return mainEntityOfPage; }
set
{
- var validator = new TypeValidator("MXTires.Microdata.CreativeWorks", null, new List(new Type[] { typeof(String), typeof(WebSite) }));
- validator.Validate(value);
+ MainEntityOfPageValidator.Validate(value);
mainEntityOfPage = value;
}
}
+ ///
+ /// A CreativeWork or Event about this Thing.
+ /// Schema.org: CreativeWork | Event
+ ///
+ [JsonProperty("subjectOf", NullValueHandling = NullValueHandling.Ignore)]
+ public object SubjectOf
+ {
+ get { return subjectOf; }
+ set
+ {
+ SubjectOfValidator.Validate(value);
+ subjectOf = value;
+ }
+ }
+
///
/// Returns Json string that represents current object.
/// JSON written by the serializer with an option of Formatting.None and NullValueHandling.Ignore. It makes the JSON result small, skipping all unnecessary
@@ -157,10 +211,7 @@ public object MainEntityOfPage
///
public string ToJson()
{
- string item = JsonConvert.SerializeObject(this, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
- item = item.Replace("Context", "@context");
- if (item.Equals("Type")) item = item.Replace("Type", "@type");
- return "";
+ return Serialize(Formatting.None, wrapInScriptTag: true);
}
///
@@ -170,10 +221,7 @@ public string ToJson()
///
public string ToIndentedJson()
{
- string item = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
- item = item.Replace("Context", "@context");
- if (item.Equals("Type")) item = item.Replace("Type", "@type");
- return "";
+ return Serialize(Formatting.Indented, wrapInScriptTag: true);
}
///
/// Returns Json string that represents current object.
@@ -183,29 +231,19 @@ public string ToIndentedJson()
///
public override string ToString()
{
- var item = JsonConvert.SerializeObject(this, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
- item = item.Replace("Context", "@context");
- if (item.Equals("Type")) item = item.Replace("Type", "@type");
- return item;
+ return Serialize(Formatting.None, wrapInScriptTag: false);
}
- //#region Delegate and Events
- /////
- ///// OnValidateEventHandler delegate to enable injection of custom validation routines
- /////
- //public delegate void OnValidateEventHandler(object sender, EventArgs e);
- //public delegate void OnValidatedEventHandler(object sender, EventArgs e);
-
- //public OnValidateEventHandler OnValidate;
- //public OnValidatedEventHandler OnValidated;
+ private string Serialize(Formatting formatting, bool wrapInScriptTag)
+ {
+ var json = JsonConvert.SerializeObject(this, formatting, SerializerSettings);
- //#endregion
- //#region Internal Fields
- /////
- ///// The Errors collection to keep the errors. Tthe validation method populates this.
- /////
- //public List Errors = new List();
+ if (!wrapInScriptTag)
+ {
+ return json;
+ }
- //#endregion
+ return "";
+ }
}
}
\ No newline at end of file