oising / wcfds-toolkit Goto Github PK
View Code? Open in Web Editor NEWWCF Data Services Toolkit NG
Home Page: https://nuget.org/packages/Nivot.WCFDataServicesToolkit/
WCF Data Services Toolkit NG
Home Page: https://nuget.org/packages/Nivot.WCFDataServicesToolkit/
When querying with the "$inlinecount=allpages" option, ODataQueryProvider attempts to add the same key twice to the HttpContext.Current.Items collection.
ODataQueryProvider.cs, line 112 should be changed from:
HttpContext.Current.Items.Add("ODataQueryOperation.Current", operation);
to:
HttpContext.Current.Items["ODataQueryOperation.Current"] = operation;
Hi again. I notice that following limitations / issues in the current version of the Toolkit:
(1) AddReferenceToCollection do not store anywhere the 'propertyName' argument, and for my use-case this argument is mandatory, or else, I cannot know exactly in which sub-property exactly of an entity should be added the new entity. E.g. POST http://server/OData.svc/Users('foo')/$links/Products
If the Users entity have the same Type for /Products and for /SpecialProducts is impossible to know where to add the new entity in which collection.
My change was the following:
public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
{
this._currentOperation = "AddReferenceToCollection";
this._currentOperationProperty = propertyName;
this._currentEntity = targetResource;
this._currentRelatedEntity = resourceToBeAdded;
}
[...]
public void SaveChanges()
{
if (_currentOperation == null)
return;
var repository = RepositoryFor(_currentEntity.GetType().FullName);
if (repository == null)
return;
if (_currentOperation == "CreateResource" || _currentOperation == "ModifyResource")
ExecuteMethodIfExists(repository, "Save", _currentEntity);
if (_currentOperation == "DeleteResource")
ExecuteMethodIfExists(repository, "Remove", _currentEntity);
if (_currentOperation == "AddReferenceToCollection")
ExecuteMethodIfExists(repository, string.Format("Create{0}Relation", _currentOperationProperty), _currentEntity, _currentRelatedEntity);
if (_currentOperation == "RemoveReferenceFromCollection")
ExecuteMethodIfExists(repository, string.Format("Remove{0}Relation", _currentOperationProperty), _currentEntity, _currentRelatedEntity);
}
(2) RemoveReferenceFromCollection is not implemented. This do not work for the following example:
DELETE http://server/OData.svc/Users('foo')/$links/Products('xpto')
I adapted the Add implementation to this Remove method, and this was the result:
public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
{
this._currentOperation = "RemoveReferenceFromCollection";
this._currentOperationProperty = propertyName;
this._currentEntity = targetResource;
this._currentRelatedEntity = resourceToBeRemoved;
}
Hi, first of all, thank you a lot for this great toolkit.
Right now, i'm having a trouble using $expand property from the OData protocol when using an expand in a Object which have other property object which have a List<> of the first Object (loop of object references).
My model is something like:
public class Content
{
public string Id { get; set; }
public string Title { get; set; }
public Channel Channel { get; set; }
}
public class Channel
{
public string Id { get; set; }
public string Name { get; set; }
public IList<Content> Contents { get; set; }
}
And i invoke something like: "http://localhost/OData.svc/Contents?$expand=Channel&$select=Id,Channel"
I already identified the problem in the "Microsoft.Data.Services.Toolkit.QueryModel.TypeExtensions" class, and made the following changes.
public static IDictionary GetPropertyDetails(this IEnumerable properties, Type type)
{
var projectedProperties = new Dictionary();
var projectedTypes = new List() { type };
Action, Func> processProperties = null;
processProperties = delegate(IEnumerable propertyList, Func accessor)
{
if (accessor == null)
accessor = o => o;
foreach (var property in propertyList)
{
var local = property;
if (property.PropertyType.IsValueType || property.PropertyType == typeof(string))
{
var propertyDetails = new PropertyDetails
{
PropertyInfo = local,
PropertySetter = (target, value) => local.SetValue(accessor(target), Convert.ChangeType(value, local.PropertyType.TypeOrElementType()), null)
};
projectedProperties.Add(local.GetUnderlyingColumnName(), propertyDetails);
}
else if (property.PropertyType.IsArray)
{
var propertyDetails = new PropertyDetails
{
PropertyInfo = local,
PropertySetter = (target, value) => local.SetValue(accessor(target), value, null)
};
projectedProperties.Add(local.GetUnderlyingColumnName(), propertyDetails);
}
else
{
if (!projectedTypes.Contains(local.PropertyType))
{
projectedTypes.Add(local.PropertyType);
processProperties(local.PropertyType.GetProperties(BindingFlags.Public | BindingFlags.Instance), o => local.GetValue(accessor(o), null));
}
}
}
};
processProperties(properties, null);
return projectedProperties;
}
Basically I added a list of types already iterated to avoid a loop in recursion of the processProperties(...) method! That way, it works just fine. Otherwise, it occurs an Exception in the Dictionary repeated key, and if you do an if before to check if it contains that key, occurs a StackOverflow because of the loop recursion problem.
Do you confirm that this is a bug, or am I doing something wrong?
Hi, i'm having also another issue with the Batch feature of OData.
This feature let us make more than one OData request in a single HTTP POST request.
http://www.odata.org/documentation/odata-v2-documentation/batch-processing/
Basically, when I use the batch functionality with only one request in the POST body, it works. But when I use more than one request in the POST body, it occurs one exception of duplicate insert in the dictionary "HttpContext.Current.Items.Add("ODataQueryOperation.Current", operation)" that is present in class "Microsoft.Data.Services.Toolkit.QueryModel.ODataQueryProvider".
To solve this, I simple removed that line, because I noticed that is not used by nothing else.
Best regards,
Carlos Torrão
No readme.md and no wiki pages? :)
I would like to determine when a client has specified an "$expand" operation on my endpoint so that I can decided whether or not to load the data. By default, the ODataQueryOperation.Current.ContextParameters does not include querystring items that start with a "$".
Line 53 of ODataQueryProvider.cs should be changed from:
var queryStringDictionary = queryString.AllKeys.Where(p => !p.StartsWith("$")).ToDictionary(k => k, p => queryString[p]);
to
var queryStringDictionary = queryString.AllKeys.ToDictionary(k => k, p => queryString[p]);
so that we can inspect the context to determine whether the $expand operation was requested.
In fact, it would be nice to include $expand-specific properties in ODataQueryOperation itself, similar to how ProjectedProperties works.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.