Some more JsonPatch refactoring for non-generics

- Add Apply to non-generic Operation (used by non-generic JsonPatchDocument)
- Add non-generic JsonPatchDocument
This commit is contained in:
KevinDockx 2015-07-10 11:41:44 +02:00 committed by Ryan Nowak
parent baee4a0661
commit bbc059a689
10 changed files with 461 additions and 71 deletions

View File

@ -0,0 +1,76 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNet.JsonPatch.Exceptions;
using Microsoft.AspNet.JsonPatch.Operations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
namespace Microsoft.AspNet.JsonPatch.Converters
{
public class JsonPatchDocumentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
if (objectType != typeof(JsonPatchDocument))
{
throw new ArgumentException(Resources.FormatParameterMustMatchType("objectType", "JsonPatchDocument"), "objectType");
}
try
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
// load jObject
var jObject = JArray.Load(reader);
// Create target object for Json => list of operations
var targetOperations = new List<Operation>();
// Create a new reader for this jObject, and set all properties
// to match the original reader.
var jObjectReader = jObject.CreateReader();
jObjectReader.Culture = reader.Culture;
jObjectReader.DateParseHandling = reader.DateParseHandling;
jObjectReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
jObjectReader.FloatParseHandling = reader.FloatParseHandling;
// Populate the object properties
serializer.Populate(jObjectReader, targetOperations);
// container target: the JsonPatchDocument.
var container = new JsonPatchDocument(targetOperations, new DefaultContractResolver());
return container;
}
catch (Exception ex)
{
throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex);
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is IJsonPatchDocument)
{
var jsonPatchDoc = (IJsonPatchDocument)value;
var lst = jsonPatchDoc.GetOperations();
// write out the operations, no envelope
serializer.Serialize(writer, lst);
}
}
}
}

View File

@ -12,13 +12,8 @@ using Newtonsoft.Json.Serialization;
namespace Microsoft.AspNet.JsonPatch.Converters
{
public class TypedJsonPatchDocumentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public class TypedJsonPatchDocumentConverter : JsonPatchDocumentConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
@ -63,17 +58,5 @@ namespace Microsoft.AspNet.JsonPatch.Converters
throw new JsonPatchException(Resources.FormatInvalidJsonPatchDocument(objectType.Name), ex);
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is IJsonPatchDocument)
{
var jsonPatchDoc = (IJsonPatchDocument)value;
var lst = jsonPatchDoc.GetOperations();
// write out the operations, no envelope
serializer.Serialize(writer, lst);
}
}
}
}

View File

@ -0,0 +1,31 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.JsonPatch.Exceptions;
namespace Microsoft.AspNet.JsonPatch.Helpers
{
internal static class PathHelpers
{
internal static string NormalizePath(string path)
{
// check for most common path errors on create. This is not
// absolutely necessary, but it allows us to already catch mistakes
// on creation of the patch document rather than on execute.
if (path.Contains(".") || path.Contains("//") || path.Contains(" ") || path.Contains("\\"))
{
throw new JsonPatchException(Resources.FormatInvalidValueForPath(path), null);
}
if (!(path.StartsWith("/")))
{
return "/" + path;
}
else
{
return path;
}
}
}
}

View File

@ -11,6 +11,6 @@ namespace Microsoft.AspNet.JsonPatch
{
IContractResolver ContractResolver { get; set; }
List<Operation> GetOperations();
IList<Operation> GetOperations();
}
}

View File

@ -0,0 +1,159 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNet.JsonPatch.Adapters;
using Microsoft.AspNet.JsonPatch.Converters;
using Microsoft.AspNet.JsonPatch.Exceptions;
using Microsoft.AspNet.JsonPatch.Helpers;
using Microsoft.AspNet.JsonPatch.Operations;
using Microsoft.Framework.Internal;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Microsoft.AspNet.JsonPatch
{
// Implementation details: the purpose of this type of patch document is to allow creation of such
// documents for cases where there's no class/DTO to work on. Typical use case: backend not built in
// .NET or architecture doesn't contain a shared DTO layer.
[JsonConverter(typeof(JsonPatchDocumentConverter))]
public class JsonPatchDocument : IJsonPatchDocument
{
public List<Operation> Operations { get; private set; }
[JsonIgnore]
public IContractResolver ContractResolver { get; set; }
public JsonPatchDocument()
{
Operations = new List<Operation>();
ContractResolver = new DefaultContractResolver();
}
public JsonPatchDocument([NotNull] List<Operation> operations, [NotNull] IContractResolver contractResolver)
{
Operations = operations;
ContractResolver = contractResolver;
}
/// <summary>
/// Add operation. Will result in, for example,
/// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }
/// </summary>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument Add([NotNull] string path, object value)
{
Operations.Add(new Operation("add", PathHelpers.NormalizePath(path), null, value));
return this;
}
/// <summary>
/// Remove value at target location. Will result in, for example,
/// { "op": "remove", "path": "/a/b/c" }
/// </summary>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument Remove([NotNull] string path)
{
Operations.Add(new Operation("remove", PathHelpers.NormalizePath(path), null, null));
return this;
}
/// <summary>
/// Replace value. Will result in, for example,
/// { "op": "replace", "path": "/a/b/c", "value": 42 }
/// </summary>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument Replace([NotNull] string path, object value)
{
Operations.Add(new Operation("replace", PathHelpers.NormalizePath(path), null, value));
return this;
}
/// <summary>
/// Removes value at specified location and add it to the target location. Will result in, for example:
/// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }
/// </summary>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument Move([NotNull] string from, [NotNull] string path)
{
Operations.Add(new Operation("move", PathHelpers.NormalizePath(path), PathHelpers.NormalizePath(from)));
return this;
}
/// <summary>
/// Copy the value at specified location to the target location. Willr esult in, for example:
/// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" }
/// </summary>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument Copy([NotNull] string from, [NotNull] string path)
{
Operations.Add(new Operation("copy", PathHelpers.NormalizePath(path), PathHelpers.NormalizePath(from)));
return this;
}
/// <summary>
/// Apply this JsonPatchDocument
/// </summary>
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
public void ApplyTo([NotNull] object objectToApplyTo)
{
ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null));
}
/// <summary>
/// Apply this JsonPatchDocument
/// </summary>
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
/// <param name="logErrorAction">Action to log errors</param>
public void ApplyTo([NotNull] object objectToApplyTo, Action<JsonPatchError> logErrorAction)
{
ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction));
}
/// <summary>
/// Apply this JsonPatchDocument
/// </summary>
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
/// <param name="adapter">IObjectAdapter instance to use when applying</param>
public void ApplyTo([NotNull] object objectToApplyTo, [NotNull] IObjectAdapter adapter)
{
// apply each operation in order
foreach (var op in Operations)
{
op.Apply(objectToApplyTo, adapter);
}
}
IList<Operation> IJsonPatchDocument.GetOperations()
{
var allOps = new List<Operation>();
if (Operations != null)
{
foreach (var op in Operations)
{
var untypedOp = new Operation();
untypedOp.op = op.op;
untypedOp.value = op.value;
untypedOp.path = op.path;
untypedOp.from = op.from;
allOps.Add(untypedOp);
}
}
return allOps;
}
}
}

View File

@ -44,7 +44,7 @@ namespace Microsoft.AspNet.JsonPatch
/// { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }
/// </summary>
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">path</param>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Add<TProp>([NotNull] Expression<Func<TModel, TProp>> path, TProp value)
@ -62,7 +62,7 @@ namespace Microsoft.AspNet.JsonPatch
/// Add value to list at given position
/// </summary>
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">path</param>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <param name="position">position</param>
/// <returns></returns>
@ -84,7 +84,7 @@ namespace Microsoft.AspNet.JsonPatch
/// At value at end of list
/// </summary>
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">path</param>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Add<TProp>([NotNull] Expression<Func<TModel, IList<TProp>>> path, TProp value)
@ -102,8 +102,7 @@ namespace Microsoft.AspNet.JsonPatch
/// Remove value at target location. Will result in, for example,
/// { "op": "remove", "path": "/a/b/c" }
/// </summary>
/// <param name="remove"></param>
/// <param name="path"></param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Remove<TProp>([NotNull] Expression<Func<TModel, TProp>> path)
{
@ -149,8 +148,8 @@ namespace Microsoft.AspNet.JsonPatch
/// Replace value. Will result in, for example,
/// { "op": "replace", "path": "/a/b/c", "value": 42 }
/// </summary>
/// <param name="path"></param>
/// <param name="value"></param>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Replace<TProp>([NotNull] Expression<Func<TModel, TProp>> path, TProp value)
{
@ -168,6 +167,7 @@ namespace Microsoft.AspNet.JsonPatch
/// </summary>
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <param name="position">position</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Replace<TProp>([NotNull] Expression<Func<TModel, IList<TProp>>> path,
@ -187,6 +187,7 @@ namespace Microsoft.AspNet.JsonPatch
/// </summary>
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">target location</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Replace<TProp>([NotNull] Expression<Func<TModel, IList<TProp>>> path, TProp value)
{
@ -203,8 +204,8 @@ namespace Microsoft.AspNet.JsonPatch
/// Removes value at specified location and add it to the target location. Will result in, for example:
/// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }
/// </summary>
/// <param name="from"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Move<TProp>(
[NotNull] Expression<Func<TModel, TProp>> from,
@ -222,9 +223,9 @@ namespace Microsoft.AspNet.JsonPatch
/// Move from a position in a list to a new location
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="positionFrom">position</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Move<TProp>(
[NotNull] Expression<Func<TModel, IList<TProp>>> from,
@ -243,9 +244,9 @@ namespace Microsoft.AspNet.JsonPatch
/// Move from a property to a location in a list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <param name="positionTo">position</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Move<TProp>(
[NotNull] Expression<Func<TModel, TProp>> from,
@ -264,9 +265,10 @@ namespace Microsoft.AspNet.JsonPatch
/// Move from a position in a list to another location in a list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="positionFrom">position (source)</param>
/// <param name="path">target location</param>
/// <param name="positionTo">position (target)</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Move<TProp>(
[NotNull] Expression<Func<TModel, IList<TProp>>> from,
@ -286,9 +288,9 @@ namespace Microsoft.AspNet.JsonPatch
/// Move from a position in a list to the end of another list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="positionFrom">position</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Move<TProp>(
[NotNull] Expression<Func<TModel, IList<TProp>>> from,
@ -307,9 +309,8 @@ namespace Microsoft.AspNet.JsonPatch
/// Move to the end of a list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Move<TProp>(
[NotNull] Expression<Func<TModel, TProp>> from,
@ -327,8 +328,8 @@ namespace Microsoft.AspNet.JsonPatch
/// Copy the value at specified location to the target location. Willr esult in, for example:
/// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" }
/// </summary>
/// <param name="from"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Copy<TProp>(
[NotNull] Expression<Func<TModel, TProp>> from,
@ -346,9 +347,9 @@ namespace Microsoft.AspNet.JsonPatch
/// Copy from a position in a list to a new location
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="positionFrom">position</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Copy<TProp>(
[NotNull] Expression<Func<TModel, IList<TProp>>> from,
@ -367,9 +368,9 @@ namespace Microsoft.AspNet.JsonPatch
/// Copy from a property to a location in a list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <param name="positionTo">position</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Copy<TProp>(
[NotNull] Expression<Func<TModel, TProp>> from,
@ -388,9 +389,10 @@ namespace Microsoft.AspNet.JsonPatch
/// Copy from a position in a list to a new location in a list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="positionFrom">position (source)</param>
/// <param name="path">target location</param>
/// <param name="positionTo">position (target)</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Copy<TProp>(
[NotNull] Expression<Func<TModel, IList<TProp>>> from,
@ -410,9 +412,9 @@ namespace Microsoft.AspNet.JsonPatch
/// Copy from a position in a list to the end of another list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="positionFrom">position</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Copy<TProp>(
[NotNull] Expression<Func<TModel, IList<TProp>>> from,
@ -431,9 +433,8 @@ namespace Microsoft.AspNet.JsonPatch
/// Copy to the end of a list
/// </summary>
/// <typeparam name="TProp"></typeparam>
/// <param name="from"></param>
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <param name="from">source location</param>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<TModel> Copy<TProp>(
[NotNull] Expression<Func<TModel, TProp>> from,
@ -447,17 +448,31 @@ namespace Microsoft.AspNet.JsonPatch
return this;
}
public void ApplyTo(TModel objectToApplyTo)
/// <summary>
/// Apply this JsonPatchDocument
/// </summary>
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
public void ApplyTo([NotNull] TModel objectToApplyTo)
{
ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction: null));
}
public void ApplyTo(TModel objectToApplyTo, Action<JsonPatchError> logErrorAction)
/// <summary>
/// Apply this JsonPatchDocument
/// </summary>
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
/// <param name="logErrorAction">Action to log errors</param>
public void ApplyTo([NotNull] TModel objectToApplyTo, Action<JsonPatchError> logErrorAction)
{
ApplyTo(objectToApplyTo, new ObjectAdapter(ContractResolver, logErrorAction));
}
public void ApplyTo(TModel objectToApplyTo, IObjectAdapter adapter)
/// <summary>
/// Apply this JsonPatchDocument
/// </summary>
/// <param name="objectToApplyTo">Object to apply the JsonPatchDocument to</param>
/// <param name="adapter">IObjectAdapter instance to use when applying</param>
public void ApplyTo([NotNull] TModel objectToApplyTo, [NotNull] IObjectAdapter adapter)
{
// apply each operation in order
foreach (var op in Operations)
@ -466,7 +481,7 @@ namespace Microsoft.AspNet.JsonPatch
}
}
public List<Operation> GetOperations()
IList<Operation> IJsonPatchDocument.GetOperations()
{
var allOps = new List<Operation>();

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.JsonPatch.Adapters;
using Microsoft.Framework.Internal;
using Newtonsoft.Json;
@ -28,5 +30,37 @@ namespace Microsoft.AspNet.JsonPatch.Operations
}
public void Apply([NotNull] object objectToApplyTo, [NotNull] IObjectAdapter adapter)
{
switch (OperationType)
{
case OperationType.Add:
adapter.Add(this, objectToApplyTo);
break;
case OperationType.Remove:
adapter.Remove(this, objectToApplyTo);
break;
case OperationType.Replace:
adapter.Replace(this, objectToApplyTo);
break;
case OperationType.Move:
adapter.Move(this, objectToApplyTo);
break;
case OperationType.Copy:
adapter.Copy(this, objectToApplyTo);
break;
case OperationType.Test:
throw new NotSupportedException(Resources.TestOperationNotSupported);
default:
break;
}
}
public bool ShouldSerializevalue()
{
return (OperationType == OperationType.Add
|| OperationType == OperationType.Replace
|| OperationType == OperationType.Test);
}
}
}

View File

@ -52,11 +52,5 @@ namespace Microsoft.AspNet.JsonPatch.Operations
}
}
public bool ShouldSerializevalue()
{
return (OperationType == OperationType.Add
|| OperationType == OperationType.Replace
|| OperationType == OperationType.Test);
}
}
}

View File

@ -122,6 +122,89 @@ namespace Microsoft.AspNet.JsonPatch
return GetString("TestOperationNotSupported");
}
/// <summary>
/// objectType must be of type JsonPatchDocument.
/// </summary>
internal static string ParameterMustMatchType
{
get { return GetString("ParameterMustMatchType"); }
}
/// <summary>
/// objectType must be of type JsonPatchDocument.
/// </summary>
internal static string FormatParameterMustMatchType(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ParameterMustMatchType"), p0, p1);
}
/// <summary>
/// The property at '{0}' could not be read.
/// </summary>
internal static string CannotReadProperty
{
get { return GetString("CannotReadProperty"); }
}
/// <summary>
/// The property at '{0}' could not be read.
/// </summary>
internal static string FormatCannotReadProperty(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("CannotReadProperty"), p0);
}
/// <summary>
/// The provided string '{0}' is an invalid path.
/// </summary>
internal static string InvalidValueForPath
{
get { return GetString("InvalidValueForPath"); }
}
/// <summary>
/// The provided string '{0}' is an invalid path.
/// </summary>
internal static string FormatInvalidValueForPath(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidValueForPath"), p0);
}
/// <summary>
/// The property at path '{0}' could not be removed.
/// </summary>
internal static string PropertyCannotBeRemoved
{
get { return GetString("PropertyCannotBeRemoved"); }
}
/// <summary>
/// The property at path '{0}' could not be removed.
/// </summary>
internal static string FormatPropertyCannotBeRemoved(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("PropertyCannotBeRemoved"), p0);
}
/// <summary>
/// The property at path '{0}' could not be added.
/// </summary>
internal static string PropertyCannotBeAdded
{
get { return GetString("PropertyCannotBeAdded"); }
}
/// <summary>
/// The property at path '{0}' could not be added.
/// </summary>
internal static string FormatPropertyCannotBeAdded(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("PropertyCannotBeAdded"), p0);
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CannotReadProperty" xml:space="preserve">
<value>The property at '{0}' could not be read.</value>
</data>
<data name="CannotUpdateProperty" xml:space="preserve">
<value>The property at path '{0}' could not be updated.</value>
</data>
@ -129,9 +132,21 @@
<data name="InvalidPathForArrayProperty" xml:space="preserve">
<value>For operation '{0}', the provided path is invalid for array property at path '{1}'.</value>
</data>
<data name="InvalidValueForPath" xml:space="preserve">
<value>The provided string '{0}' is an invalid path.</value>
</data>
<data name="InvalidValueForProperty" xml:space="preserve">
<value>The value '{0}' is invalid for property at path '{1}'.</value>
</data>
<data name="ParameterMustMatchType" xml:space="preserve">
<value>'{0}' must be of type '{1}'.</value>
</data>
<data name="PropertyCannotBeAdded" xml:space="preserve">
<value>The property at path '{0}' could not be added.</value>
</data>
<data name="PropertyCannotBeRemoved" xml:space="preserve">
<value>The property at path '{0}' could not be removed.</value>
</data>
<data name="PropertyDoesNotExist" xml:space="preserve">
<value>Property does not exist at path '{0}'.</value>
</data>