PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/_posts/archived/2009-04-22-scripted-db-views.aspx.markdown

https://gitlab.com/Blueprint-Marketing/haacked.com
Markdown | 152 lines | 127 code | 25 blank | 0 comment | 0 complexity | 57e65d68401db52ae2523d56dcc8d2cb MD5 | raw file
  1. ---
  2. layout: post
  3. title: "Scripting ASP.NET MVC Views Stored In The Database"
  4. date: 2009-04-22 -0800
  5. comments: true
  6. disqus_identifier: 18612
  7. categories: [code,asp.net mvc,dlr]
  8. ---
  9. Say youre building a web application and you want, against your better
  10. judgment perhaps, to allow end users to easily customize the look and
  11. feel a common scenario within a blog engine or any hosted application.
  12. With ASP.NET, view code tends to be some complex declarative markup
  13. stuck in a file on disk which gets compiled by ASP.NET into an assembly.
  14. Most system administrators would first pluck out their own toenail
  15. rather than allow an end user permission to modify such files.
  16. Its possible to store such files in the database and use a
  17. `VirtualPathProvider` to load them, but that requires your application
  18. (and thus their views) to run in full trust. Is there a way you could
  19. safely store such views in the database in an application running in
  20. medium trust where the code in the view is approachable?
  21. [![](http://haacked.com/images/haacked_com/WindowsLiveWriter/HostingASP.NETMVCViewsInTheDatabase_134EA/fun-scripting_thumb.jpg)](http://haacked.com/images/haacked_com/WindowsLiveWriter/HostingASP.NETMVCViewsInTheDatabase_134EA/fun-scripting_2.jpg)
  22. At the ALT.NET conference a little while back, [Jimmy
  23. Schementi](http://blog.jimmy.schementi.com/ "Jimmy Schementi") and [John
  24. Lam](http://www.iunknown.com/ "John Lam") [gave a
  25. talk](http://haacked.com/archive/2009/03/01/altnetseattle-day-three.aspx "ALT.NET Seattle Day 3")
  26. about the pattern of hosting a scripting language within a larger
  27. application. For example, many modern 3-D Games have their high
  28. performance core engine written in C++ and Assembly. However, these
  29. games often use a scripting language, such as
  30. [Lua](http://www.lua.org/ "Lua programming language"), to write the
  31. scripts for the behaviors of characters and objects.
  32. An example that might be more familiar to more people is the use of VBA
  33. to write macros for Excel. In both of these cases, the larger
  34. application hosts a scripting environment that allow end users to
  35. customize the application using a simpler lighter weight language than
  36. the one the core app is written in.
  37. A long while back, I wrote a blog post about [defining ASP.NET MVC Views
  38. in
  39. IronRuby](http://haacked.com/archive/2008/04/22/defining-asp.net-mvc-routes-and-views-in-ironruby.aspx "Defining Views in IronRuby")
  40. followed by a full [IronRuby ASP.NET MVC
  41. stack](http://haacked.com/archive/2009/02/17/aspnetmvc-ironruby-with-filters.aspx "IronRuby ASP.NET MVC").
  42. While there was some passionate interest by a few, in general, I was met
  43. with the thunderous sound of crickets. Why the huge lack of interest?
  44. Probably because I didnt really sell the benefit and the explain the
  45. pain it solves. Im sure many of you were asking, *Why bother? Whats in
  46. it for me?*
  47. After thinking about it some more, I realized that my prototypes
  48. appeared to suggest that if you want to take advantage of IronRuby, you
  49. would need to make some sort of wholesale switch to a new foreign
  50. language, not something to be undertaken lightly.
  51. This is why I really like Jimmy and Johns recent efforts to focus on
  52. showing the benefits of hosting the DLR for scripting scenarios like the
  53. ones mentioned above. It makes total sense to me when I look at it in
  54. this perspective. The way I see it, most developers spend a huge bulk of
  55. their time in a single core language, typically their language of
  56. choice. For me, I spend the bulk of my time writing C\# code.
  57. However, I dont think twice about the fact that I also write tons of
  58. JavaScript when I do web development, and Ill write the occasional VB
  59. code when I need a new Macro for Visual Studio or Excel. I also write
  60. SQL when I need to. Im happy to pick up and use a new language when it
  61. will enable me to do the job at hand more efficiently and naturally than
  62. C\# does. I imagine many developers feel this way. The occasional use of
  63. a scripting languages is fine when it gets the job done and I can still
  64. spend most of my time in my favorite language.
  65. So I started thinking about how that might work in a web application.
  66. What if you could write all your business logic and controller logic in
  67. your language of choice, but have your views written in a light weight
  68. scripting language. If my web application were to host a scripting
  69. engine, I could actually store the code in any medium I want, such as
  70. the database. Having them in the database makes it very easy for end
  71. users to modify it since it wouldnt require file upload permissions
  72. into the web root.
  73. This is where hosting the DLR is a nice fit. I put together a proof of
  74. concept for these ideas. This is just a prototype intended to show how
  75. such a workflow might work. In this prototype, you go about creating
  76. your models and controllers the way you normally would.
  77. For example, heres a controller that returns some structured data to
  78. the view in the form of an anonymous type.
  79. ```csharp
  80. public ActionResult FunWithScripting()
  81. {
  82. var someData = new {
  83. salutation = "Are you having fun with scripting yet?",
  84. theDate = DateTime.Now,
  85. numbers = new int[] { 1, 2, 3, 4 }
  86. };
  87. return View(someData);
  88. }
  89. ```
  90. Once you write your controller, but before you create your view, you
  91. compile the app and then go visit the URL.![View does not exist
  92. view](http://haacked.com/images/haacked_com/WindowsLiveWriter/HostingASP.NETMVCViewsInTheDatabase_134EA/view-does-not-exist_11.png "View does not exist view")
  93. We havent created the view yet, so lets follow the instructions and
  94. login. Afterwards, we this:
  95. ![view
  96. editor](http://haacked.com/images/haacked_com/WindowsLiveWriter/HostingASP.NETMVCViewsInTheDatabase_134EA/view-editor_3.png "view editor")
  97. Since the view doesnt exist, I hooked in and provided a temporary view
  98. for the controller action which contains a view editor. Notice that at
  99. the bottom of the screen, you can see the current property names and
  100. values being passed to the view. For example, theres an enumeration of
  101. integers as one property, so I was able to use the Ruby `each` method to
  102. print them out in the view.
  103. The sweet little browser based source code editor is named [Edit Area
  104. created by Christophe
  105. Dolivet](http://www.cdolivet.com/index.php?page=editArea&sess=d7189c4b90423ed1b1aff26ec520caba "Edit Area").
  106. Unfortunately, at the time I write this, it doesnt yet have support for
  107. ERB style syntax highlighting schemes. Thats why the \<% and %\> arent
  108. highlighted in yellow.
  109. When I click *Create View*, I get taken back to the request for the same
  110. action, but now I can see the view I just created (click to enlarge).
  111. [![Fun with scripting
  112. view](http://haacked.com/images/haacked_com/WindowsLiveWriter/HostingASP.NETMVCViewsInTheDatabase_134EA/fun-with-scripting-view_thumb.png "Fun with scripting view")](http://haacked.com/images/haacked_com/WindowsLiveWriter/HostingASP.NETMVCViewsInTheDatabase_134EA/fun-with-scripting-view_2.png)
  113. In the future, I should be able to host C\# views in this way. Mono
  114. already has a tool for dynamically compiling C\# code passed in as a
  115. string which I could try and incorporate.
  116. Im seriously thinking of making this the approach for building skins in
  117. a future version of Subtext. That would make skin installation drop dead
  118. simple and not require any file directory access. Let me know if you
  119. make use of this technique in your applications.
  120. If you try and run this prototype, please note that there are some
  121. quirky caching issues with editing existing views in the prototype.
  122. Itll seem like your view is not being edited, but its a result of how
  123. views are being cached. It might take a bit of time before your edits
  124. show up. Im sure there are other bugs Im still in the process of
  125. fixing. But for the most part, the general principle is sound.
  126. You can **[download the prototype
  127. here](http://code.haacked.com/mvc-1.0/IronRubyViews.zip "IronRuby Views in Db")**.