Showing posts with label Monorail. Show all posts
Showing posts with label Monorail. Show all posts

Wednesday, November 12, 2008

How to display an image retrieved from DB in Monorail

Assume that I am developing a Castle Monorail Web application.

If I want to display an image retrieved from the database on a web page I can use a view template which looks similar to this one

<div>
  <table class="form">
    <tbody>
      <tr>
        <td>Title:</td>
        <td>${Form.TextField("model.Photo.Title")}</td>
      </tr>
      <tr>
        <td>Comment:</td>
        <td>${Form.TextArea("model.Photo.Comment")}</td>
      </tr>
      <tr>
        <td><button id="selectImage">Select</button></td>
        <td><img src="${UrlHelper.For({@action:@getPhoto})}?photoId=${model.Photo.Id}"/></td>
      </tr>
    </tbody>
  </table>
</div>

Note that I am using Brail as my view engine. I have an <img> element in the template. The src attribute of the <img> element points to the getPhoto method of the controller. The code in the controller which provides the photo is

public void GetPhoto(Guid employeePhotoId)
{
    var model = service.GetEmployeePhoto(employeePhotoId);
    Response.ContentType = "image/gif";
    Response.BinaryWrite(model.Photo.Image);
    CancelView();
}

Here the call to the service returns a model having a public field Photo. The class representing the photo has (among others) properties Title and Image, where Image is an array of bytes containing the photo itself (e.g. the content of a gif or jpg image).

Wednesday, July 2, 2008

HowTo use Castle Monorail and jQuery to exchange JSON data

Define a Controller as follows

[Layout("default")]
public class JsonController : SmartDispatcherController
{
    public void Index()
    { }
 
    /// <summary>"Manual" or "traditional" way to return 
    /// JSON formatted data</summary>
    public void GetStates(string countryCode)
    {
        State[] states = FetchAllByCountry(countryCode);
 
        string js = Context.Services
                       .JSONSerializer
                       .Serialize(states);
 
        Response.ContentType = "application/json";
        RenderText(js);
    }
 
    /// <summary>
    /// Return JSON formatted data by using an attribute
    /// One can even filter the list of fields that should
    /// be serialized
    /// </summary>
    /// <returns>the JSON formatted list of states</returns>
    [return: JSONReturnBinder(Properties = "Id,Name")]
    public State[] GetStates_Ex(string countryCode)
    {
        return FetchAllByCountry(countryCode);
    }
 
    private static State[] FetchAllByCountry(string countryCode)
    {...}
}

The State entity is defined as

public class State
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

The JSON output generated by the method GetStates is similar to this

[{"Id":1,"Name":"ZH","Description":"Zürich"},
 {"Id":2,"Name":"TG","Description":"Thurgau"},
 {"Id":3,"Name":"SG","Description":"St. Gallen"}]

and the output from GetStates_Ex is similar to this

[{"Id":1,"Name":"ZH"},
 {"Id":2,"Name":"TG"},
 {"Id":3,"Name":"SG"}]

Note that in the latter case the field Description is not included as expected!

In the index.brail template (I'm using the brail view engine) use the following java script block

<script>
    jQuery(document).ready(function(){
        jQuery("#traditional").click(function(){
            jQuery.getJSON("${UrlHelper.For({@action:@GetStates})}",
                function(data){
                    jQuery.each(data, function(i,item){
                        jQuery("<div/>").text(item.Name)
                            .appendTo("#states");
                    });
                });
        });
        
        jQuery("#withAttr").click(function(){
            jQuery.getJSON("${UrlHelper.For({@action:@GetStates_Ex})}",
                function(data){
                    jQuery.each(data, function(i,item){
                        jQuery("<div/>").text(item.Name)
                            .appendTo("#states");
                    });
                });
        });
    });
</script>

and the following HTML

<button id="traditional" >Traditional</button>&nbsp;
<button id="withAttr" >with Attribute</button>&nbsp;
<br />
<div id="states"></div>

Clicking on either the first or the second button will make an Ajax call to the controller and return a JSON serialized list of states. When returning from the call the names of the states are displayed in the div with id="states".