1
// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.Framework
18 using System
.Collections
.Generic
;
19 using System
.Reflection
;
25 [AttributeUsage(AttributeTargets
.ReturnValue
, AllowMultiple
= false, Inherited
= false)]
26 public class JSONReturnBinderAttribute
: Attribute
, IReturnBinder
28 private string properties
;
31 /// Gets or sets the properties to be serialized.
33 /// <value>The properties.</value>
34 public string Properties
36 get { return properties; }
37 set { properties = value; }
41 /// Binds the specified parameters for the action.
43 /// <param name="context">The context.</param>
44 /// <param name="controller">The controller.</param>
45 /// <param name="controllerContext">The controller context.</param>
46 /// <param name="returnType">Type being returned.</param>
47 /// <param name="returnValue">The return value.</param>
48 /// <returns></returns>
49 public void Bind(IEngineContext context
, IController controller
, IControllerContext controllerContext
,
50 Type returnType
, object returnValue
)
52 // Cancel any view rendering
53 controllerContext
.SelectedViewName
= null;
55 IJSONSerializer serializer
= context
.Services
.JSONSerializer
;
58 context
.Response
.ContentType
= "application/json";
60 if (properties
== null || returnValue
== null)
62 // Serializes the return value (what if it's null?)
63 context
.Response
.Write(serializer
.Serialize(returnValue
));
67 Type normalized
= returnType
.IsArray
? returnType
.GetElementType() : returnType
;
69 context
.Response
.Write(serializer
.Serialize(returnValue
,
70 new PropertyConverter(normalized
, properties
)));
74 class PropertyConverter
: IJSONConverter
76 private readonly Type targetType
;
77 private List
<PropertyInfo
> properties
= new List
<PropertyInfo
>();
79 public PropertyConverter(Type targetType
, string propertyNames
)
81 this.targetType
= targetType
;
83 foreach(string propertyName
in propertyNames
.Split(','))
85 PropertyInfo prop
= targetType
.GetProperty(propertyName
);
89 throw new MonoRailException("Failed to JSON serialize object. " +
90 "Property " + propertyName
+ " could not be found for type " + targetType
.FullName
);
97 public void Write(IJSONWriter writer
, object value)
99 writer
.WriteStartObject();
101 foreach(PropertyInfo info
in properties
)
103 object propVal
= info
.GetValue(value, null);
105 writer
.WritePropertyName(info
.Name
);
106 writer
.WriteValue(propVal
);
109 writer
.WriteEndObject();
112 public bool CanHandle(Type type
)
114 return type
== targetType
;