예제 #1
0
        private static SDataParameters GetServiceParameters(ISDataClient client, Expression bodyExpr, string path)
        {
            Guard.ArgumentNotNull(client, "client");

            var callExpr = bodyExpr as MethodCallExpression;

            if (callExpr == null)
            {
                throw new SDataClientException("Expression must be a method call");
            }

            var attr         = callExpr.Method.GetCustomAttribute <SDataServiceOperationAttribute>();
            var namingScheme = client.NamingScheme ?? NamingScheme.Default;
            var request      = new SDataResource();
            var instance     = callExpr.Object != null?Expression.Lambda(callExpr.Object).Compile().DynamicInvoke() : null;

            if (path == null)
            {
                path = SDataPathAttribute.GetPath(instance != null ? instance.GetType() : callExpr.Method.DeclaringType);
            }

            if (instance != null)
            {
                if (attr == null || attr.PassInstanceBy == InstancePassingConvention.Selector ||
                    (attr.PassInstanceBy == InstancePassingConvention.Default && string.IsNullOrEmpty(attr.InstancePropertyName)))
                {
                    if (path == null)
                    {
                        throw new SDataClientException("Path must be specified when passing instance context by selector");
                    }
                    var key = ContentHelper.GetProtocolValue <string>(instance, SDataProtocolProperty.Key);
                    if (string.IsNullOrEmpty(key))
                    {
                        throw new SDataClientException("Unable to extract resource key from instance");
                    }
                    path += string.Format("({0})", SDataUri.FormatConstant(key));
                }
                else if (attr.PassInstanceBy == InstancePassingConvention.Default)
                {
                    var key = ContentHelper.GetProtocolValue <string>(instance, SDataProtocolProperty.Key);
                    request[attr.InstancePropertyName] = !string.IsNullOrEmpty(key) ? key : instance;
                }
                else
                {
                    if (string.IsNullOrEmpty(attr.InstancePropertyName))
                    {
                        throw new SDataClientException("Instance property name must be specified when passing instance context by key property or object property");
                    }

                    if (attr.PassInstanceBy == InstancePassingConvention.KeyProperty)
                    {
                        var key = ContentHelper.GetProtocolValue <string>(instance, SDataProtocolProperty.Key);
                        if (string.IsNullOrEmpty(key))
                        {
                            throw new SDataClientException("Unable to extract resource key from instance");
                        }
                        request[attr.InstancePropertyName] = key;
                    }
                    else if (attr.PassInstanceBy == InstancePassingConvention.ObjectProperty)
                    {
                        request[attr.InstancePropertyName] = instance;
                    }
                }
            }

            if (path != null)
            {
                path += "/";
            }
            path += "$service/" + namingScheme.GetName(callExpr.Method);

            foreach (var pair in callExpr.Method.GetParameters().Zip(callExpr.Arguments, (param, arg) => new { param, arg }))
            {
                request[namingScheme.GetName(pair.param)] = Expression.Lambda(pair.arg).Compile().DynamicInvoke();
            }

            var xmlLocalName = attr != null ? attr.XmlLocalName : null;
            var xmlNamespace = attr != null ? attr.XmlNamespace : null;
            var content      = new SDataResource(xmlLocalName, xmlNamespace)
            {
                { "request", request }
            };

            return(new SDataParameters
            {
                Method = HttpMethod.Post,
                Path = path,
                Content = content
            });
        }
예제 #2
0
 private static string GetPath <T>(string path)
 {
     return(path ?? SDataPathAttribute.GetPath(typeof(T)));
 }