Removed untyped contructor from ComponentRegistration and add a protected setter.
[castle.git] / MonoRail / Castle.MonoRail.Framework / Attributes / JSONReturnBinderAttribute.cs
blob404a5984f4e3bb2db494e8d41f51c104cb1cfa01
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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
17 using System;
18 using System.Collections.Generic;
19 using System.Reflection;
20 using Services;
22 /// <summary>
23 /// Pendent
24 /// </summary>
25 [AttributeUsage(AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = false)]
26 public class JSONReturnBinderAttribute : Attribute, IReturnBinder
28 private string properties;
30 /// <summary>
31 /// Gets or sets the properties to be serialized.
32 /// </summary>
33 /// <value>The properties.</value>
34 public string Properties
36 get { return properties; }
37 set { properties = value; }
40 /// <summary>
41 /// Binds the specified parameters for the action.
42 /// </summary>
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;
57 // Sets the mime type
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));
65 else
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);
87 if (prop == null)
89 throw new MonoRailException("Failed to JSON serialize object. " +
90 "Property " + propertyName + " could not be found for type " + targetType.FullName);
93 properties.Add(prop);
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;