Musings<Biefeld>
- curiosities of development, life, the universe and everything -
Archive for the ‘Asp.net’ Category
Wednesday, September 21st, 2011

Found this solution rather simple when you want to serve images from your database.

public class ImageController
{
	readonly IImageQueries Queries;

	public ImageController(IImageQueries queries)
	{
		Queries = queries;
	}

	public FileResult Show(int id)
	{
		DateTime? dateCreated = Queries.GetDateCreatedById(id);

		//invalid image, return 404
		if (dateCreated == null)
		{
			HttpContext.Response.StatusCode = 404;

			return null;
		}
		else
		{
			string ifModifiedSince = HttpContext.Request.Headers["If-Modified-Since"];

			//check if image has been modified
			if (ifModifiedSince != null && dateCreated.Value <= DateTime.Parse(ifModifiedSince))
			{
				HttpContext.Response.StatusCode = 304;
				return null;
			}
			else
			{
				HttpContext.Response.Cache.SetLastModified(dateCreated.Value);

				dynamic image = Queries.GetById(id);

				return new FileContentResult(image.Bytes, image.MimeType);
			}
		}
	}
}
Friday, September 9th, 2011

Hello fellow techies on this roller coaster called life. It has been a while since my last post, I have been focusing on some other more important aspects of my life.

What I want to talk about in this post is the idea of a dynamic view page which removes the need for a View Model data transfer object. I have started to try this out on project that I am working on, for views that are essentially read only. All these views are concerned about is displaying data/information.  I do not yet know how useful this is but I thought it was novel and will be exploring it’s usefulness. Plus, the lazy side of me likes the idea of not creating data transfer objects if possible.

Two side effects of this approach are the loss of the strongly typed Model on your view, which is a non-issue for a page without inputs.  The second is the loss of intellisense (the very first time a member is used on a dynamic) when working with the Model in the view, which could be a minor loss in that you wont know something is wrong until you run it, but thats the way it goes.

To accomplish this you start off by creating a DynamicViewPage that inherits ViewPage.  Have some overrides and new up some properties and you should be set.

public class DynamicViewPage : ViewPage
{
	private ViewDataDictionary<dynamic> _viewData;

	public override void InitHelpers()
	{
		base.InitHelpers();
		Ajax = new AjaxHelper<dynamic>(ViewContext, this);
		Html = new HtmlHelper<dynamic>(ViewContext, this);
	}

	protected override void SetViewData(ViewDataDictionary viewData)
	{
		_viewData = new ViewDataDictionary<dynamic>(viewData);
		base.SetViewData(_viewData);
	}

	public new AjaxHelper<dynamic> Ajax { get; set; }

	public new HtmlHelper<dynamic> Html { get; set; }

	public new dynamic Model
	{
		get
		{
			return ViewData.Model;
		}
	}

	public new ViewDataDictionary<dynamic> ViewData
	{
		get
		{
			if (_viewData == null)
			{
				SetViewData(new ViewDataDictionary<dynamic>());
			}
			return _viewData;
		}
		set
		{
			SetViewData(value);
		}
	}
}

Now your view needs to inherit from DynamicViewPage.

Inherits="Web.Views.DynamicViewPage"

In your controller you can ask your persistence abstraction of choice for some data and return it to the view.

public ActionResult Index()
{
	IEnumerable<dynamic> foos = FooQueries.GetAll();
	return View(foos);
}

Where this can get interesting is when you have a linq provider that returns dynamic objects. Then essentially your domain model is king and you eliminate a lot of DTOs. That’s all I’ve got for now. I attached a sample application that demonstrates the dynamic view, enjoy!

Wednesday, September 17th, 2008

I recently needed a textbox that would fire a server event when the textbox’s onblur JavaScript event was fired.  It took a while of googling and asking coworkers questions to figure out how exactly to do it.  Couldn’t seem to find an example of exactly what I needed.

 

I started off by creating a class that inherited from textbox and implemented ICallBackEventHandler.  I soon realized that this was not going to work for what I needed.  The ICallBackEventHandler is best suited for a simple Ajax control that just needs to update its own content.  Problem is that I need a post back to happen in order to update other controls on the page.

 

So instead of implementing the ICallBackEventHandler interface I implemented the IPostBackEventHanlder interface.  This turned out to be a much simpler, cleaner way to do it.

When implementing the IPostBackEventHandler you must Implement the RaisePostBackEvent method:

public class BlurTextbox : TextBox, IPostBackEventHandler
{
    #region Implementation of IPostBackEventHandler

    /// <summary>
    /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
    /// </summary>
    /// <param name="eventArgument">A <see cref="T:System.String" /> that represents an optional event argument to be passed to the event handler. </param>
    public void RaisePostBackEvent(string eventArgument)
    {

    }

    #endregion
}

 

This method is what gets called by .net’s JavaScript when your control does a post back.

 

Now what we want to do is create the JavaScript function that will cause the post back will allow the RaisePostBackEvent method to handle the logic for that event.

 

I just created a method on the textbox that returns the script.  You can use the Page.ClientScript.GetPostBackEventReference(Control control, string argument) method but this is not necessary because all the it generates is __doPostBack(‘controlName’,'argument’), either way works.

 

If you want to be able to have multiple instances of the control on the same page you need to write it yourself, this is what I did:

private string GetScript()
{
    return "function OnBlurred(control, arg)\n{\n __doPostBack(control, arg);\n}";
}

There are two parameters needed, the control and the argument, the control string that the asp.net JavaScript call is expecting will need the textbox’s UniqueID for it to work properly. 

Next I created a server side event on the control called Blur:

public delegate void OnBlurDelegate(object sender, EventArgs e);

public event OnBlurDelegate Blur;

private void RaiseOnBlurEvent()
{
    if(Blur != null)
    {
        Blur(this, EventArgs.Empty);
    }
}

Now we can call the RaiseOnBlurEvent() method in the implemented RaisePostBackEvent() method like:

public void RaisePostBackEvent(string eventArgument)
{
    RaiseOnBlurEvent();
}

Lastly I overrode the OnInit event, called the base.  I check if that script is already registered, if it’s not I register it, otherwise move one.  Then registered the OnBlurred script we created, and added the JavaScript onblur event attribute to the textbox.  I pass in the UniqueID and empty quotes because I don’t need any arguments.

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    if (!Page.ClientScript.IsClientScriptBlockRegistered("OnBlurTextboxEvent"))
        Page.ClientScript.RegisterStartupScript(GetType(), "OnBlurTextboxEvent", GetScript(), true);
    Attributes.Add("onblur", "OnBlurred('" + UniqueID + "','')");
}

Now all that is left to do is use it on some web page and setup the server side handling.

Aspx:

<cc3:BlurTextbox ID="Test" runat="server" OnBlur="Test_OnBlur"></cc3:BlurTextbox>

Server Handling:

protected void Test_OnBlur(object sender, EventArgs e)
{
}

The whole thing is here.

Musings<Biefeld> is proudly powered by WordPress
Entries (RSS) and Comments (RSS).