Removed Test operation code and changed T to TModel

This commit is contained in:
Kirthi Krishnamraju 2015-04-20 12:50:02 -07:00
parent bf712263fc
commit 3042a62ba9
9 changed files with 259 additions and 271 deletions

View File

@ -8,14 +8,13 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// <summary>
/// Defines the operations that can be performed on a JSON patch document.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IObjectAdapter<T> where T : class
/// <typeparam name="TModel">The type of the model.</typeparam>
public interface IObjectAdapter<TModel> where TModel : class
{
void Add(Operation<T> operation, T objectToApplyTo);
void Copy(Operation<T> operation, T objectToApplyTo);
void Move(Operation<T> operation, T objectToApplyTo);
void Remove(Operation<T> operation, T objectToApplyTo);
void Replace(Operation<T> operation, T objectToApplyTo);
void Test(Operation<T> operation, T objectToApplyTo);
void Add(Operation<TModel> operation, TModel objectToApplyTo);
void Copy(Operation<TModel> operation, TModel objectToApplyTo);
void Move(Operation<TModel> operation, TModel objectToApplyTo);
void Remove(Operation<TModel> operation, TModel objectToApplyTo);
void Replace(Operation<TModel> operation, TModel objectToApplyTo);
}
}

View File

@ -15,14 +15,14 @@ using Newtonsoft.Json.Serialization;
namespace Microsoft.AspNet.JsonPatch.Adapters
{
/// <inheritdoc />
public class ObjectAdapter<T> : IObjectAdapter<T> where T : class
public class ObjectAdapter<TModel> : IObjectAdapter<TModel> where TModel : class
{
/// <summary>
/// Initializes a new instance of <see cref="ObjectAdapter{T}"/>.
/// Initializes a new instance of <see cref="ObjectAdapter{TModel}"/>.
/// </summary>
/// <param name="contractResolver">The <see cref="IContractResolver"/>.</param>
/// <param name="logErrorAction">The <see cref="Action"/> for logging <see cref="JsonPatchError{T}"/>.</param>
public ObjectAdapter(IContractResolver contractResolver, Action<JsonPatchError<T>> logErrorAction)
/// <param name="logErrorAction">The <see cref="Action"/> for logging <see cref="JsonPatchError{TModel}"/>.</param>
public ObjectAdapter(IContractResolver contractResolver, Action<JsonPatchError<TModel>> logErrorAction)
{
ContractResolver = contractResolver;
LogErrorAction = logErrorAction;
@ -34,9 +34,9 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
public IContractResolver ContractResolver { get; }
/// <summary>
/// Action for logging <see cref="JsonPatchError{T}"/>.
/// Action for logging <see cref="JsonPatchError{TModel}"/>.
/// </summary>
public Action<JsonPatchError<T>> LogErrorAction { get; }
public Action<JsonPatchError<TModel>> LogErrorAction { get; }
/// <summary>
/// The "add" operation performs one of the following functions,
@ -96,9 +96,9 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
///
/// because "a" does not exist.
/// </summary>
/// <param name="operation">The add operation</param>
/// <param name="objectApplyTo">Object to apply the operation to</param>
public void Add(Operation<T> operation, T objectToApplyTo)
/// <param name="operation">The add operation.</param>
/// <param name="objectApplyTo">Object to apply the operation to.</param>
public void Add(Operation<TModel> operation, TModel objectToApplyTo)
{
Add(operation.path, operation.value, objectToApplyTo, operation);
}
@ -107,7 +107,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// Add is used by various operations (eg: add, copy, ...), yet through different operations;
/// This method allows code reuse yet reporting the correct operation on error
/// </summary>
private void Add(string path, object value, T objectToApplyTo, Operation<T> operationToReport)
private void Add(string path, object value, TModel objectToApplyTo, Operation<TModel> operationToReport)
{
// add, in this implementation, does not just "add" properties - that's
// technically impossible; It can however be used to add items to arrays,
@ -178,7 +178,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operationToReport,
Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
@ -189,7 +189,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operationToReport,
Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
@ -236,9 +236,9 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// The "from" location MUST NOT be a proper prefix of the "path"
/// location; i.e., a location cannot be moved into one of its children.
/// </summary>
/// <param name="operation">The move operation</param>
/// <param name="objectApplyTo">Object to apply the operation to</param>
public void Move(Operation<T> operation, T objectToApplyTo)
/// <param name="operation">The move operation.</param>
/// <param name="objectApplyTo">Object to apply the operation to.</param>
public void Move(Operation<TModel> operation, TModel objectToApplyTo)
{
// get value at from location
object valueAtFromLocation = null;
@ -275,7 +275,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
if (array.Count <= positionAsInteger)
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatInvalidIndexForArrayProperty(operation.op, operation.from)));
@ -287,7 +287,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatInvalidPathForArrayProperty(operation.op, operation.from)));
@ -321,9 +321,9 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// If removing an element from an array, any elements above the
/// specified index are shifted one position to the left.
/// </summary>
/// <param name="operation">The remove operation</param>
/// <param name="objectApplyTo">Object to apply the operation to</param>
public void Remove(Operation<T> operation, T objectToApplyTo)
/// <param name="operation">The remove operation.</param>
/// <param name="objectApplyTo">Object to apply the operation to.</param>
public void Remove(Operation<TModel> operation, TModel objectToApplyTo)
{
Remove(operation.path, objectToApplyTo, operation);
}
@ -332,7 +332,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// Remove is used by various operations (eg: remove, move, ...), yet through different operations;
/// This method allows code reuse yet reporting the correct operation on error
/// </summary>
private void Remove(string path, T objectToApplyTo, Operation<T> operationToReport)
private void Remove(string path, TModel objectToApplyTo, Operation<TModel> operationToReport)
{
var removeFromList = false;
var positionAsInteger = -1;
@ -388,7 +388,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operationToReport,
Resources.FormatInvalidIndexForArrayProperty(operationToReport.op, path)));
@ -399,7 +399,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operationToReport,
Resources.FormatInvalidPathForArrayProperty(operationToReport.op, path)));
@ -423,133 +423,6 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
}
/// <summary>
/// The "test" operation tests that a value at the target location is
/// equal to a specified value.
///
/// The operation object MUST contain a "value" member that conveys the
/// value to be compared to the target location's value.
///
/// The target location MUST be equal to the "value" value for the
/// operation to be considered successful.
///
/// Here, "equal" means that the value at the target location and the
/// value conveyed by "value" are of the same JSON type, and that they
/// are considered equal by the following rules for that type:
///
/// o strings: are considered equal if they contain the same number of
/// Unicode characters and their code points are byte-by-byte equal.
///
/// o numbers: are considered equal if their values are numerically
/// equal.
///
/// o arrays: are considered equal if they contain the same number of
/// values, and if each value can be considered equal to the value at
/// the corresponding position in the other array, using this list of
/// type-specific rules.
///
/// o objects: are considered equal if they contain the same number of
/// members, and if each member can be considered equal to a member in
/// the other object, by comparing their keys (as strings) and their
/// values (using this list of type-specific rules).
///
/// o literals (false, true, and null): are considered equal if they are
/// the same.
///
/// Note that the comparison that is done is a logical comparison; e.g.,
/// whitespace between the member values of an array is not significant.
///
/// Also, note that ordering of the serialization of object members is
/// not significant.
///
/// Note that we divert from the rules here - we use .NET's comparison,
/// not the one above. In a future version, a "strict" setting might
/// be added (configurable), that takes into account above rules.
///
/// For example:
///
/// { "op": "test", "path": "/a/b/c", "value": "foo" }
/// </summary>
/// <param name="operation">The test operation</param>
/// <param name="objectApplyTo">Object to apply the operation to</param>
public void Test(Operation<T> operation, T objectToApplyTo)
{
// get value at path location
object valueAtPathLocation = null;
var positionInPathAsInteger = -1;
var actualPathProperty = operation.path;
positionInPathAsInteger = GetNumericEnd(operation.path);
if (positionInPathAsInteger > -1)
{
actualPathProperty = operation.path.Substring(0,
operation.path.IndexOf('/' + positionInPathAsInteger.ToString()));
}
var patchProperty = FindPropertyAndParent(objectToApplyTo, actualPathProperty);
// does property at path exist?
if (!CheckIfPropertyExists(patchProperty, objectToApplyTo, operation, operation.path))
{
return;
}
// get the property path
Type typeOfFinalPropertyAtPathLocation = null;
// is the path an array (but not a string (= char[]))? In this case,
// the path must end with "/position" or "/-", which we already determined before.
if (positionInPathAsInteger > -1)
{
if (IsNonStringArray(patchProperty.Property.PropertyType))
{
// now, get the generic type of the IList<> from Property type.
typeOfFinalPropertyAtPathLocation = GetIListType(patchProperty.Property.PropertyType);
// get value (it can be cast, we just checked that)
var array = (IList)patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
if (array.Count <= positionInPathAsInteger)
{
LogError(new JsonPatchError<T>(
objectToApplyTo,
operation,
Resources.FormatInvalidIndexForArrayProperty(operation.op, operation.path)));
return;
}
valueAtPathLocation = array[positionInPathAsInteger];
}
else
{
LogError(new JsonPatchError<T>(
objectToApplyTo,
operation,
Resources.FormatInvalidPathForArrayProperty(operation.op, operation.path)));
return;
}
}
else
{
// no list, just get the value
valueAtPathLocation = patchProperty.Property.ValueProvider.GetValue(patchProperty.Parent);
typeOfFinalPropertyAtPathLocation = patchProperty.Property.PropertyType;
}
var conversionResultTuple = ConvertToActualType(typeOfFinalPropertyAtPathLocation, operation.value);
// Is conversion successful
if (!CheckIfPropertyCanBeSet(conversionResultTuple, objectToApplyTo, operation, operation.path))
{
return;
}
//Compare
}
/// <summary>
/// The "replace" operation replaces the value at the target location
/// with a new value. The operation object MUST contain a "value" member
@ -568,9 +441,9 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// Note: even though it's the same functionally, we do not call remove + add
/// for performance reasons (multiple checks of same requirements).
/// </summary>
/// <param name="operation">The replace operation</param>
/// <param name="objectApplyTo">Object to apply the operation to</param>
public void Replace(Operation<T> operation, T objectToApplyTo)
/// <param name="operation">The replace operation.</param>
/// <param name="objectApplyTo">Object to apply the operation to.</param>
public void Replace(Operation<TModel> operation, TModel objectToApplyTo)
{
Remove(operation.path, objectToApplyTo, operation);
Add(operation.path, operation.value, objectToApplyTo, operation);
@ -596,9 +469,9 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
/// Note: even though it's the same functionally, we do not call add with
/// the value specified in from for performance reasons (multiple checks of same requirements).
/// </summary>
/// <param name="operation">The copy operation</param>
/// <param name="objectApplyTo">Object to apply the operation to</param>
public void Copy(Operation<T> operation, T objectToApplyTo)
/// <param name="operation">The copy operation.</param>
/// <param name="objectApplyTo">Object to apply the operation to.</param>
public void Copy(Operation<TModel> operation, TModel objectToApplyTo)
{
// get value at from location
object valueAtFromLocation = null;
@ -636,7 +509,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
if (array.Count <= positionAsInteger)
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatInvalidIndexForArrayProperty(operation.op, operation.from)));
@ -648,7 +521,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatInvalidPathForArrayProperty(operation.op, operation.from)));
@ -669,13 +542,13 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
private bool CheckIfPropertyExists(
JsonPatchProperty patchProperty,
T objectToApplyTo,
Operation<T> operation,
TModel objectToApplyTo,
Operation<TModel> operation,
string propertyPath)
{
if (patchProperty == null)
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatPropertyDoesNotExist(propertyPath)));
@ -685,7 +558,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
if (patchProperty.Property.Ignored)
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatCannotUpdateProperty(propertyPath)));
@ -708,13 +581,13 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
private bool CheckIfPropertyCanBeSet(
ConversionResult result,
T objectToApplyTo,
Operation<T> operation,
TModel objectToApplyTo,
Operation<TModel> operation,
string path)
{
if (!result.CanBeConverted)
{
LogError(new JsonPatchError<T>(
LogError(new JsonPatchError<TModel>(
objectToApplyTo,
operation,
Resources.FormatInvalidValueForProperty(result.ConvertedInstance, path)));
@ -725,7 +598,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
return true;
}
private void LogError(JsonPatchError<T> jsonPatchError)
private void LogError(JsonPatchError<TModel> jsonPatchError)
{
if (LogErrorAction != null)
{
@ -733,7 +606,7 @@ namespace Microsoft.AspNet.JsonPatch.Adapters
}
else
{
throw new JsonPatchException<T>(jsonPatchError);
throw new JsonPatchException<TModel>(jsonPatchError);
}
}

View File

@ -6,10 +6,10 @@ using Microsoft.AspNet.JsonPatch.Operations;
namespace Microsoft.AspNet.JsonPatch.Exceptions
{
public class JsonPatchException<T> : JsonPatchException where T : class
public class JsonPatchException<TModel> : JsonPatchException where TModel : class
{
public Operation<T> FailedOperation { get; private set; }
public new T AffectedObject { get; private set; }
public Operation<TModel> FailedOperation { get; private set; }
public new TModel AffectedObject { get; private set; }
private string _message = "";
public override string Message
@ -26,14 +26,14 @@ namespace Microsoft.AspNet.JsonPatch.Exceptions
}
public JsonPatchException(JsonPatchError<T> jsonPatchError)
public JsonPatchException(JsonPatchError<TModel> jsonPatchError)
{
FailedOperation = jsonPatchError.Operation;
_message = jsonPatchError.ErrorMessage;
AffectedObject = jsonPatchError.AffectedObject;
}
public JsonPatchException(JsonPatchError<T> jsonPatchError, Exception innerException)
public JsonPatchException(JsonPatchError<TModel> jsonPatchError, Exception innerException)
: this(jsonPatchError)
{
InnerException = innerException;

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNet.JsonPatch.Helpers
{
internal static class ExpressionHelpers
{
public static string GetPath<T, TProp>(Expression<Func<T, TProp>> expr) where T : class
public static string GetPath<TModel, TProp>(Expression<Func<TModel, TProp>> expr) where TModel : class
{
return "/" + GetPath(expr.Body, true);
}

View File

@ -18,21 +18,21 @@ namespace Microsoft.AspNet.JsonPatch
// including type data in the JsonPatchDocument serialized as JSON (to allow for correct deserialization) - that's
// not according to RFC 6902, and would thus break cross-platform compatibility.
[JsonConverter(typeof(TypedJsonPatchDocumentConverter))]
public class JsonPatchDocument<T> : IJsonPatchDocument where T : class
public class JsonPatchDocument<TModel> : IJsonPatchDocument where TModel : class
{
public List<Operation<T>> Operations { get; private set; }
public List<Operation<TModel>> Operations { get; private set; }
[JsonIgnore]
public IContractResolver ContractResolver { get; set; }
public JsonPatchDocument()
{
Operations = new List<Operation<T>>();
Operations = new List<Operation<TModel>>();
ContractResolver = new DefaultContractResolver();
}
// Create from list of operations
public JsonPatchDocument(List<Operation<T>> operations, IContractResolver contractResolver)
public JsonPatchDocument(List<Operation<TModel>> operations, IContractResolver contractResolver)
{
Operations = operations;
ContractResolver = contractResolver;
@ -46,13 +46,14 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="path">path</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument<T> Add<TProp>(Expression<Func<T, TProp>> path, TProp value)
public JsonPatchDocument<TModel> Add<TProp>(Expression<Func<TModel, TProp>> path, TProp value)
{
Operations.Add(new Operation<T>(
Operations.Add(new Operation<TModel>(
"add",
ExpressionHelpers.GetPath<T, TProp>(path).ToLower(),
ExpressionHelpers.GetPath(path).ToLower(),
from: null,
value: value));
return this;
}
@ -64,12 +65,18 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="value">value</param>
/// <param name="position">position</param>
/// <returns></returns>
public JsonPatchDocument<T> Add<TProp>(Expression<Func<T, IList<TProp>>> path, TProp value, int position)
public JsonPatchDocument<TModel> Add<TProp>(
Expression<Func<TModel,
IList<TProp>>> path,
TProp value,
int position)
{
Operations.Add(new Operation<T>(
Operations.Add(new Operation<TModel>(
"add",
ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/" + position,
null, value));
ExpressionHelpers.GetPath(path).ToLower() + "/" + position,
from: null,
value: value));
return this;
}
@ -80,9 +87,14 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="path">path</param>
/// <param name="value">value</param>
/// <returns></returns>
public JsonPatchDocument<T> Add<TProp>(Expression<Func<T, IList<TProp>>> path, TProp value)
public JsonPatchDocument<TModel> Add<TProp>(Expression<Func<TModel, IList<TProp>>> path, TProp value)
{
Operations.Add(new Operation<T>("add", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/-", null, value));
Operations.Add(new Operation<TModel>(
"add",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
from: null,
value: value));
return this;
}
@ -93,9 +105,10 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="remove"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Remove<TProp>(Expression<Func<T, TProp>> path)
public JsonPatchDocument<TModel> Remove<TProp>(Expression<Func<TModel, TProp>> path)
{
Operations.Add(new Operation<T>("remove", ExpressionHelpers.GetPath<T, TProp>(path).ToLower(), null));
Operations.Add(new Operation<TModel>("remove", ExpressionHelpers.GetPath(path).ToLower(), from: null));
return this;
}
@ -106,9 +119,13 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="path">target location</param>
/// <param name="position">position</param>
/// <returns></returns>
public JsonPatchDocument<T> Remove<TProp>(Expression<Func<T, IList<TProp>>> path, int position)
public JsonPatchDocument<TModel> Remove<TProp>(Expression<Func<TModel, IList<TProp>>> path, int position)
{
Operations.Add(new Operation<T>("remove", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/" + position, null));
Operations.Add(new Operation<TModel>(
"remove",
ExpressionHelpers.GetPath(path).ToLower() + "/" + position,
from: null));
return this;
}
@ -118,9 +135,13 @@ namespace Microsoft.AspNet.JsonPatch
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<T> Remove<TProp>(Expression<Func<T, IList<TProp>>> path)
public JsonPatchDocument<TModel> Remove<TProp>(Expression<Func<TModel, IList<TProp>>> path)
{
Operations.Add(new Operation<T>("remove", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/-", null));
Operations.Add(new Operation<TModel>(
"remove",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
from: null));
return this;
}
@ -131,9 +152,14 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="path"></param>
/// <param name="value"></param>
/// <returns></returns>
public JsonPatchDocument<T> Replace<TProp>(Expression<Func<T, TProp>> path, TProp value)
public JsonPatchDocument<TModel> Replace<TProp>(Expression<Func<TModel, TProp>> path, TProp value)
{
Operations.Add(new Operation<T>("replace", ExpressionHelpers.GetPath<T, TProp>(path).ToLower(), null, value));
Operations.Add(new Operation<TModel>(
"replace",
ExpressionHelpers.GetPath(path).ToLower(),
from: null,
value: value));
return this;
}
@ -144,9 +170,16 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="path">target location</param>
/// <param name="position">position</param>
/// <returns></returns>
public JsonPatchDocument<T> Replace<TProp>(Expression<Func<T, IList<TProp>>> path, TProp value, int position)
public JsonPatchDocument<TModel> Replace<TProp>(
Expression<Func<TModel, IList<TProp>>> path,
TProp value, int position)
{
Operations.Add(new Operation<T>("replace", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/" + position, null, value));
Operations.Add(new Operation<TModel>(
"replace",
ExpressionHelpers.GetPath(path).ToLower() + "/" + position,
from: null,
value: value));
return this;
}
@ -156,9 +189,14 @@ namespace Microsoft.AspNet.JsonPatch
/// <typeparam name="TProp">value type</typeparam>
/// <param name="path">target location</param>
/// <returns></returns>
public JsonPatchDocument<T> Replace<TProp>(Expression<Func<T, IList<TProp>>> path, TProp value)
public JsonPatchDocument<TModel> Replace<TProp>(Expression<Func<TModel, IList<TProp>>> path, TProp value)
{
Operations.Add(new Operation<T>("replace", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/-", null, value));
Operations.Add(new Operation<TModel>(
"replace",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
from: null,
value: value));
return this;
}
@ -169,10 +207,15 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="from"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Move<TProp>(Expression<Func<T, TProp>> from, Expression<Func<T, TProp>> path)
public JsonPatchDocument<TModel> Move<TProp>(
Expression<Func<TModel, TProp>> from,
Expression<Func<TModel, TProp>> path)
{
Operations.Add(new Operation<T>("move", ExpressionHelpers.GetPath<T, TProp>(path).ToLower()
, ExpressionHelpers.GetPath<T, TProp>(from).ToLower()));
Operations.Add(new Operation<TModel>(
"move",
ExpressionHelpers.GetPath(path).ToLower(),
ExpressionHelpers.GetPath(from).ToLower()));
return this;
}
@ -184,10 +227,16 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Move<TProp>(Expression<Func<T, IList<TProp>>> from, int positionFrom, Expression<Func<T, TProp>> path)
public JsonPatchDocument<TModel> Move<TProp>(
Expression<Func<TModel, IList<TProp>>> from,
int positionFrom,
Expression<Func<TModel, TProp>> path)
{
Operations.Add(new Operation<T>("move", ExpressionHelpers.GetPath<T, TProp>(path).ToLower()
, ExpressionHelpers.GetPath<T, IList<TProp>>(from).ToLower() + "/" + positionFrom));
Operations.Add(new Operation<TModel>(
"move",
ExpressionHelpers.GetPath(path).ToLower(),
ExpressionHelpers.GetPath(from).ToLower() + "/" + positionFrom));
return this;
}
@ -199,12 +248,16 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Move<TProp>(Expression<Func<T, TProp>> from,
Expression<Func<T, IList<TProp>>> path, int positionTo)
public JsonPatchDocument<TModel> Move<TProp>(
Expression<Func<TModel, TProp>> from,
Expression<Func<TModel, IList<TProp>>> path,
int positionTo)
{
Operations.Add(new Operation<T>("move", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower()
+ "/" + positionTo
, ExpressionHelpers.GetPath<T, TProp>(from).ToLower()));
Operations.Add(new Operation<TModel>(
"move",
ExpressionHelpers.GetPath(path).ToLower() + "/" + positionTo,
ExpressionHelpers.GetPath(from).ToLower()));
return this;
}
@ -216,12 +269,17 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Move<TProp>(Expression<Func<T, IList<TProp>>> from, int positionFrom,
Expression<Func<T, IList<TProp>>> path, int positionTo)
public JsonPatchDocument<TModel> Move<TProp>(
Expression<Func<TModel, IList<TProp>>> from,
int positionFrom,
Expression<Func<TModel, IList<TProp>>> path,
int positionTo)
{
Operations.Add(new Operation<T>("move", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower()
+ "/" + positionTo
, ExpressionHelpers.GetPath<T, IList<TProp>>(from).ToLower() + "/" + positionFrom));
Operations.Add(new Operation<TModel>(
"move",
ExpressionHelpers.GetPath(path).ToLower() + "/" + positionTo,
ExpressionHelpers.GetPath(from).ToLower() + "/" + positionFrom));
return this;
}
@ -233,12 +291,16 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Move<TProp>(Expression<Func<T, IList<TProp>>> from, int positionFrom,
Expression<Func<T, IList<TProp>>> path)
public JsonPatchDocument<TModel> Move<TProp>(
Expression<Func<TModel, IList<TProp>>> from,
int positionFrom,
Expression<Func<TModel, IList<TProp>>> path)
{
Operations.Add(new Operation<T>("move", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower()
+ "/-"
, ExpressionHelpers.GetPath<T, IList<TProp>>(from).ToLower() + "/" + positionFrom));
Operations.Add(new Operation<TModel>(
"move",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
ExpressionHelpers.GetPath(from).ToLower() + "/" + positionFrom));
return this;
}
@ -250,10 +312,15 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Move<TProp>(Expression<Func<T, TProp>> from, Expression<Func<T, IList<TProp>>> path)
public JsonPatchDocument<TModel> Move<TProp>(
Expression<Func<TModel, TProp>> from,
Expression<Func<TModel, IList<TProp>>> path)
{
Operations.Add(new Operation<T>("move", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/-"
, ExpressionHelpers.GetPath<T, TProp>(from).ToLower()));
Operations.Add(new Operation<TModel>(
"move",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
ExpressionHelpers.GetPath(from).ToLower()));
return this;
}
@ -264,10 +331,15 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="from"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Copy<TProp>(Expression<Func<T, TProp>> from, Expression<Func<T, TProp>> path)
public JsonPatchDocument<TModel> Copy<TProp>(
Expression<Func<TModel, TProp>> from,
Expression<Func<TModel, TProp>> path)
{
Operations.Add(new Operation<T>("copy", ExpressionHelpers.GetPath<T, TProp>(path).ToLower()
, ExpressionHelpers.GetPath<T, TProp>(from).ToLower()));
Operations.Add(new Operation<TModel>(
"copy",
ExpressionHelpers.GetPath(path).ToLower()
, ExpressionHelpers.GetPath(from).ToLower()));
return this;
}
@ -279,10 +351,16 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Copy<TProp>(Expression<Func<T, IList<TProp>>> from, int positionFrom, Expression<Func<T, TProp>> path)
public JsonPatchDocument<TModel> Copy<TProp>(
Expression<Func<TModel, IList<TProp>>> from,
int positionFrom,
Expression<Func<TModel, TProp>> path)
{
Operations.Add(new Operation<T>("copy", ExpressionHelpers.GetPath<T, TProp>(path).ToLower()
, ExpressionHelpers.GetPath<T, IList<TProp>>(from).ToLower() + "/" + positionFrom));
Operations.Add(new Operation<TModel>(
"copy",
ExpressionHelpers.GetPath(path).ToLower(),
ExpressionHelpers.GetPath(from).ToLower() + "/" + positionFrom));
return this;
}
@ -294,12 +372,16 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Copy<TProp>(Expression<Func<T, TProp>> from,
Expression<Func<T, IList<TProp>>> path, int positionTo)
public JsonPatchDocument<TModel> Copy<TProp>(
Expression<Func<TModel, TProp>> from,
Expression<Func<TModel, IList<TProp>>> path,
int positionTo)
{
Operations.Add(new Operation<T>("copy", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower()
+ "/" + positionTo
, ExpressionHelpers.GetPath<T, TProp>(from).ToLower()));
Operations.Add(new Operation<TModel>(
"copy",
ExpressionHelpers.GetPath(path).ToLower() + "/" + positionTo,
ExpressionHelpers.GetPath(from).ToLower()));
return this;
}
@ -311,12 +393,17 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Copy<TProp>(Expression<Func<T, IList<TProp>>> from, int positionFrom,
Expression<Func<T, IList<TProp>>> path, int positionTo)
public JsonPatchDocument<TModel> Copy<TProp>(
Expression<Func<TModel, IList<TProp>>> from,
int positionFrom,
Expression<Func<TModel, IList<TProp>>> path,
int positionTo)
{
Operations.Add(new Operation<T>("copy", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower()
+ "/" + positionTo
, ExpressionHelpers.GetPath<T, IList<TProp>>(from).ToLower() + "/" + positionFrom));
Operations.Add(new Operation<TModel>(
"copy",
ExpressionHelpers.GetPath(path).ToLower() + "/" + positionTo,
ExpressionHelpers.GetPath(from).ToLower() + "/" + positionFrom));
return this;
}
@ -328,12 +415,17 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Copy<TProp>(Expression<Func<T, IList<TProp>>> from, int positionFrom,
Expression<Func<T, IList<TProp>>> path)
public JsonPatchDocument<TModel> Copy<TProp>(
Expression<Func<TModel,
IList<TProp>>> from,
int positionFrom,
Expression<Func<TModel, IList<TProp>>> path)
{
Operations.Add(new Operation<T>("copy", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower()
+ "/-"
, ExpressionHelpers.GetPath<T, IList<TProp>>(from).ToLower() + "/" + positionFrom));
Operations.Add(new Operation<TModel>(
"copy",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
ExpressionHelpers.GetPath(from).ToLower() + "/" + positionFrom));
return this;
}
@ -345,24 +437,29 @@ namespace Microsoft.AspNet.JsonPatch
/// <param name="positionFrom"></param>
/// <param name="path"></param>
/// <returns></returns>
public JsonPatchDocument<T> Copy<TProp>(Expression<Func<T, TProp>> from, Expression<Func<T, IList<TProp>>> path)
public JsonPatchDocument<TModel> Copy<TProp>(
Expression<Func<TModel, TProp>> from,
Expression<Func<TModel, IList<TProp>>> path)
{
Operations.Add(new Operation<T>("copy", ExpressionHelpers.GetPath<T, IList<TProp>>(path).ToLower() + "/-"
, ExpressionHelpers.GetPath<T, TProp>(from).ToLower()));
Operations.Add(new Operation<TModel>(
"copy",
ExpressionHelpers.GetPath(path).ToLower() + "/-",
ExpressionHelpers.GetPath(from).ToLower()));
return this;
}
public void ApplyTo(T objectToApplyTo)
public void ApplyTo(TModel objectToApplyTo)
{
ApplyTo(objectToApplyTo, new ObjectAdapter<T>(ContractResolver, logErrorAction: null));
ApplyTo(objectToApplyTo, new ObjectAdapter<TModel>(ContractResolver, logErrorAction: null));
}
public void ApplyTo(T objectToApplyTo, Action<JsonPatchError<T>> logErrorAction)
public void ApplyTo(TModel objectToApplyTo, Action<JsonPatchError<TModel>> logErrorAction)
{
ApplyTo(objectToApplyTo, new ObjectAdapter<T>(ContractResolver, logErrorAction));
ApplyTo(objectToApplyTo, new ObjectAdapter<TModel>(ContractResolver, logErrorAction));
}
public void ApplyTo(T objectToApplyTo, IObjectAdapter<T> adapter)
public void ApplyTo(TModel objectToApplyTo, IObjectAdapter<TModel> adapter)
{
// apply each operation in order
foreach (var op in Operations)

View File

@ -9,17 +9,17 @@ namespace Microsoft.AspNet.JsonPatch
/// <summary>
/// Captures error message and the related entity and the operation that caused it.
/// </summary>
public class JsonPatchError<T> where T : class
public class JsonPatchError<TModel> where TModel : class
{
/// <summary>
/// Initializes a new instance of <see cref="JsonPatchError{T}"/>.
/// Initializes a new instance of <see cref="JsonPatchError{TModel}"/>.
/// </summary>
/// <param name="affectedObject">The object that is affected by the error.</param>
/// <param name="operation">The <see cref="Operation{T}"/> that caused the error.</param>
/// <param name="operation">The <see cref="Operation{TModel}"/> that caused the error.</param>
/// <param name="errorMessage">The error message.</param>
public JsonPatchError(
[NotNull] T affectedObject,
[NotNull] Operation<T> operation,
[NotNull] TModel affectedObject,
[NotNull] Operation<TModel> operation,
[NotNull] string errorMessage)
{
AffectedObject = affectedObject;
@ -30,12 +30,12 @@ namespace Microsoft.AspNet.JsonPatch
/// <summary>
/// Gets the object that is affected by the error.
/// </summary>
public T AffectedObject { get; }
public TModel AffectedObject { get; }
/// <summary>
/// Gets the <see cref="Operation{T}"/> that caused the error.
/// Gets the <see cref="Operation{TModel}"/> that caused the error.
/// </summary>
public Operation<T> Operation { get; }
public Operation<TModel> Operation { get; }
/// <summary>
/// Gets the error message.

View File

@ -1,11 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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;
namespace Microsoft.AspNet.JsonPatch.Operations
{
public class Operation<T> : Operation where T : class
public class Operation<TModel> : Operation where TModel : class
{
public Operation()
{
@ -24,7 +25,7 @@ namespace Microsoft.AspNet.JsonPatch.Operations
}
public void Apply(T objectToApplyTo, IObjectAdapter<T> adapter)
public void Apply(TModel objectToApplyTo, IObjectAdapter<TModel> adapter)
{
switch (OperationType)
{
@ -44,8 +45,7 @@ namespace Microsoft.AspNet.JsonPatch.Operations
adapter.Copy(this, objectToApplyTo);
break;
case OperationType.Test:
adapter.Test(this, objectToApplyTo);
break;
throw new NotSupportedException(Resources.TestOperationNotSupported);
default:
break;
}

View File

@ -106,6 +106,22 @@ namespace Microsoft.AspNet.JsonPatch
return string.Format(CultureInfo.CurrentCulture, GetString("PropertyDoesNotExist"), p0);
}
/// <summary>
/// The test operation is not supported.
/// </summary>
internal static string TestOperationNotSupported
{
get { return GetString("TestOperationNotSupported"); }
}
/// <summary>
/// The test operation is not supported.
/// </summary>
internal static string FormatTestOperationNotSupported()
{
return GetString("TestOperationNotSupported");
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -135,4 +135,7 @@
<data name="PropertyDoesNotExist" xml:space="preserve">
<value>Property does not exist at path '{0}'.</value>
</data>
<data name="TestOperationNotSupported" xml:space="preserve">
<value>The test operation is not supported.</value>
</data>
</root>