Skip to content

Instantly share code, notes, and snippets.

@cbilson
Created February 13, 2009 21:27
Show Gist options
  • Save cbilson/64106 to your computer and use it in GitHub Desktop.
Save cbilson/64106 to your computer and use it in GitHub Desktop.
public class ClientController : BaseController {
private IClientManagementService _clientManagementService = null;
public ClientController(IClientManagementService clientManagementService) {
_clientManagementService = clientManagementService;
}
// this will work both for an HTTP GET (the returned value will got into the property
// bag for the view to use) or for a JSON response (just like JsonReturnBinder - in fact
// that's where I got most of this code :-)
[return: ViewModelReturnBinder]
public MasterListOfClientsViewModel List(int page) {
var results = _clientManagementService.GetClients(page);
var viewModel = new MasterListOfClientsViewModel {
Clients = results.Results,
PageNumber = page,
TotalPages = results.TotalPages
};
return viewModel;
}
}
public class MasterListOfClientsViewModel {
public MasterListOfClientsViewModel() {
Clients = new List<Client>();
}
public IList<Client> Clients { get; set; }
public int PageNumber { get; set; }
public int TotalPages { get; set; }
}
// Decorate an action and just return a view model. It will be in the property bag if it's a page
// GET, or just written to the response if it's an ajax request
public class ViewModelReturnBinderAttribute : Attribute, IReturnBinder {
public void Bind(
IEngineContext context,
IController controller,
IControllerContext controllerContext,
Type returnType,
object returnValue) {
var raw = GetRawValue(returnType, returnValue, context.Services.JSONSerializer);
// if this is an ajax request, cancel any view rendering
if (IsAjaxRequest(context)) {
controllerContext.SelectedViewName = null;
context.Response.ContentType = "application/json, text/javascript";
context.Response.Output.Write(raw);
} else {
controllerContext.PropertyBag.Add("_ViewModel", raw);
}
}
private bool IsAjaxRequest(IEngineContext context) {
if (context.Request.ContentType.Contains("application/json"))
return true;
if (context.Request.ContentType.Contains("text/javascript"))
return true;
return false;
}
/// <summary>
/// Converts target object to its JSON representation
/// </summary>
/// <param name="returnType">Type of the target object</param>
/// <param name="returnValue">The target object</param>
/// <param name="serializer">The JSON serializer</param>
/// <returns></returns>
private string GetRawValue(Type returnType, object returnValue, IJSONSerializer serializer)
{
if (returnValue == null)
return returnType.IsArray ? "[]" : "{}";
return serializer.Serialize(returnValue);
}
class PropertyConverter : IJSONConverter {
private readonly Type targetType;
private List<PropertyInfo> properties = new List<PropertyInfo>();
public PropertyConverter(Type targetType, string propertyNames) {
this.targetType = targetType;
foreach (string propertyName in propertyNames.Split(',')) {
PropertyInfo prop = targetType.GetProperty(propertyName);
if (prop == null) {
throw new MonoRailException("Failed to JSON serialize object. " +
"Property " + propertyName + " could not be found for type " + targetType.FullName);
}
properties.Add(prop);
}
}
public void Write(IJSONWriter writer, object value) {
writer.WriteStartObject();
foreach (PropertyInfo info in properties) {
object propVal = info.GetValue(value, null);
writer.WritePropertyName(info.Name);
writer.WriteValue(propVal);
}
writer.WriteEndObject();
}
public bool CanHandle(Type type) {
return type == targetType;
}
public object ReadJson(IJSONReader reader, Type objectType) {
throw new NotImplementedException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment