upshot.metadata and DbDataController generic controllerhttp://forums.asp.net/t/1772721.aspx/1?upshot+metadata+and+DbDataController+generic+controllerSat, 31 Mar 2012 09:41:16 -040017727214845971http://forums.asp.net/p/1772721/4845971.aspx/1?upshot+metadata+and+DbDataController+generic+controllerupshot.metadata and DbDataController generic controller <p>I am trying to understand what goes on the SPA in new Web API stuff but I see some nasty stuff so far. On the other hand, I see myself nowhere to be able to judge what you guys have been done so far and that gets me to a big confusion.</p> <p>Here is my issue:</p> <p>When I look at the source code of the BigShelf sample, I see a big chuck of javascript code embeded inside my html as below:</p> <pre class="prettyprint">upshot.metadata({&quot;Book:#BigShelf.Models&quot;:{&quot;key&quot;:[&quot;Id&quot;],&quot;fields&quot;:{&quot;AddedDate&quot;:{&quot;type&quot;:&quot;DateTime:#System&quot;},&quot;ASIN&quot;:{&quot;type&quot;:&quot;String:#System&quot;},&quot;Author&quot;:{&quot;type&quot;:&quot;String:#System&quot;},&quot;CategoryId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;CategoryName&quot;:{&quot;type&quot;:&quot;CategoryName:#BigShelf.Models&quot;,&quot;association&quot;:{&quot;name&quot;:&quot;CategoryName_Book&quot;,&quot;thisKey&quot;:[&quot;CategoryId&quot;],&quot;otherKey&quot;:[&quot;Id&quot;],&quot;isForeignKey&quot;:true}},&quot;Description&quot;:{&quot;type&quot;:&quot;String:#System&quot;},&quot;FlaggedBooks&quot;:{&quot;type&quot;:&quot;FlaggedBook:#BigShelf.Models&quot;,&quot;array&quot;:true,&quot;association&quot;:{&quot;name&quot;:&quot;Book_FlaggedBook&quot;,&quot;thisKey&quot;:[&quot;Id&quot;],&quot;otherKey&quot;:[&quot;BookId&quot;],&quot;isForeignKey&quot;:false}},&quot;Id&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;PublishDate&quot;:{&quot;type&quot;:&quot;DateTime:#System&quot;},&quot;Title&quot;:{&quot;type&quot;:&quot;String:#System&quot;}},&quot;rules&quot;:{},&quot;messages&quot;:{}},&quot;CategoryName:#BigShelf.Models&quot;:{&quot;key&quot;:[&quot;Id&quot;],&quot;fields&quot;:{&quot;Books&quot;:{&quot;type&quot;:&quot;Book:#BigShelf.Models&quot;,&quot;array&quot;:true,&quot;association&quot;:{&quot;name&quot;:&quot;CategoryName_Book&quot;,&quot;thisKey&quot;:[&quot;Id&quot;],&quot;otherKey&quot;:[&quot;CategoryId&quot;],&quot;isForeignKey&quot;:false}},&quot;Categories&quot;:{&quot;type&quot;:&quot;Category:#BigShelf.Models&quot;,&quot;array&quot;:true,&quot;association&quot;:{&quot;name&quot;:&quot;CategoryName_Category&quot;,&quot;thisKey&quot;:[&quot;Id&quot;],&quot;otherKey&quot;:[&quot;CategoryId&quot;],&quot;isForeignKey&quot;:false}},&quot;Id&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;Name&quot;:{&quot;type&quot;:&quot;String:#System&quot;}},&quot;rules&quot;:{},&quot;messages&quot;:{}},&quot;Category:#BigShelf.Models&quot;:{&quot;key&quot;:[&quot;Id&quot;],&quot;fields&quot;:{&quot;CategoryId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;CategoryName&quot;:{&quot;type&quot;:&quot;CategoryName:#BigShelf.Models&quot;,&quot;association&quot;:{&quot;name&quot;:&quot;CategoryName_Category&quot;,&quot;thisKey&quot;:[&quot;CategoryId&quot;],&quot;otherKey&quot;:[&quot;Id&quot;],&quot;isForeignKey&quot;:true}},&quot;Id&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;Profile&quot;:{&quot;type&quot;:&quot;Profile:#BigShelf.Models&quot;,&quot;association&quot;:{&quot;name&quot;:&quot;Profile_Category&quot;,&quot;thisKey&quot;:[&quot;ProfileId&quot;],&quot;otherKey&quot;:[&quot;Id&quot;],&quot;isForeignKey&quot;:true}},&quot;ProfileId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;}},&quot;rules&quot;:{},&quot;messages&quot;:{}},&quot;Profile:#BigShelf.Models&quot;:{&quot;key&quot;:[&quot;Id&quot;],&quot;fields&quot;:{&quot;AspNetUserGuid&quot;:{&quot;type&quot;:&quot;String:#System&quot;},&quot;Categories&quot;:{&quot;type&quot;:&quot;Category:#BigShelf.Models&quot;,&quot;array&quot;:true,&quot;association&quot;:{&quot;name&quot;:&quot;Profile_Category&quot;,&quot;thisKey&quot;:[&quot;Id&quot;],&quot;otherKey&quot;:[&quot;ProfileId&quot;],&quot;isForeignKey&quot;:false}},&quot;EmailAddress&quot;:{&quot;type&quot;:&quot;String:#System&quot;},&quot;FlaggedBooks&quot;:{&quot;type&quot;:&quot;FlaggedBook:#BigShelf.Models&quot;,&quot;array&quot;:true,&quot;association&quot;:{&quot;name&quot;:&quot;Profile_FlaggedBook&quot;,&quot;thisKey&quot;:[&quot;Id&quot;],&quot;otherKey&quot;:[&quot;ProfileId&quot;],&quot;isForeignKey&quot;:false}},&quot;Friends&quot;:{&quot;type&quot;:&quot;Friend:#BigShelf.Models&quot;,&quot;array&quot;:true,&quot;association&quot;:{&quot;name&quot;:&quot;Profile_Friend&quot;,&quot;thisKey&quot;:[&quot;Id&quot;],&quot;otherKey&quot;:[&quot;ProfileId&quot;],&quot;isForeignKey&quot;:false}},&quot;Id&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;Name&quot;:{&quot;type&quot;:&quot;String:#System&quot;}},&quot;rules&quot;:{&quot;EmailAddress&quot;:{&quot;required&quot;:true,&quot;email&quot;:true},&quot;Name&quot;:{&quot;required&quot;:true}},&quot;messages&quot;:{}},&quot;FlaggedBook:#BigShelf.Models&quot;:{&quot;key&quot;:[&quot;Id&quot;],&quot;fields&quot;:{&quot;BookId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;Id&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;IsFlaggedToRead&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;ProfileId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;Rating&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;}},&quot;rules&quot;:{},&quot;messages&quot;:{}},&quot;Friend:#BigShelf.Models&quot;:{&quot;key&quot;:[&quot;Id&quot;],&quot;fields&quot;:{&quot;FriendId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;FriendProfile&quot;:{&quot;type&quot;:&quot;Profile:#BigShelf.Models&quot;,&quot;association&quot;:{&quot;name&quot;:&quot;Profile_Friend1&quot;,&quot;thisKey&quot;:[&quot;FriendId&quot;],&quot;otherKey&quot;:[&quot;Id&quot;],&quot;isForeignKey&quot;:true}},&quot;Id&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;},&quot;ProfileId&quot;:{&quot;type&quot;:&quot;Int32:#System&quot;}},&quot;rules&quot;:{},&quot;messages&quot;:{}}});</pre> <p>And the actual code which produces that is as below:</p> <pre class="prettyprint">upshot.metadata(@(Html.Metadata&lt;BigShelf.Controllers.BigShelfController&gt;()));</pre> <p>What you have done here is very shocking for me. Then I saw this below line of code at the same page:</p> <pre class="prettyprint">@{ ViewBag.Title = "Big Shelf - Read books, share books."; var profile = (Profile)ViewBag.UserProfile; var friendsJson = new JavaScriptSerializer().Serialize(profile.Friends.Select(f =&gt; new { f.FriendId, f.FriendProfile.Name })); }</pre> <p>Which makes me write this forum post. I am really confused. I feel like writing web forms, classic asp and mvc all together here. How come you put this as sample in an ASP.NET MVC application?</p> <p>In the long run, this approach, which is creating javascript code with html helper, will definately suck!&nbsp;I do not want to generate javascript code with htmlhelpers. This is no different than web forms in my point of view.&nbsp;</p> <p>On the other hand, the apicontroller class starts with below code which makes me wonder as well:</p> <pre class="prettyprint"> public class BigShelfController : DbDataController&lt;BigShelfEntities&gt;</pre> <p>Using the DbContext class directly which is very unlikely for me in a real world application. What is the alternative here? we have repository classes and DI implementations.</p> <p>Only thing which is good among those in that SPA sample is knockout which adds more value. It really seperates the concerns.</p> <p>I am not sure how others think here but these are early previews and still under development AFAIK. uphot.js looks promissing but as soon as you start generating miracle code (like gridview on asp.net web forms), it complicates my application.</p> <p>I would be more than happy if you can give me a feedback here.&nbsp;</p> 2012-02-22T21:42:31-05:004846014http://forums.asp.net/p/1772721/4846014.aspx/1?Re+upshot+metadata+and+DbDataController+generic+controllerRe: upshot.metadata and DbDataController generic controller <p>It is a fair question. Before I answer the question, let me ask a&nbsp;question in return first to get a baseline. Lets say you are given the task of creating a new LOB application which has 10 views in it. The user can hit those 10 views in some order (either random or in&nbsp;order, take your pick). The user makes a change on each view, some of the views share the same data, some don't, but the changes to one of the views should be reflected on the others. At&nbsp;the end of the 10 views the user can then go back to the views and make additional changes, and then can&nbsp;choose to either persist their changes to the database or cancel their changes. Would you consider this easy to do, hard to do, or something that just shouldn't be done?</p> <p>(EDIT I don't want that question to sound like a trap. Personally, I need to do that kind of thing all the time and I don't think it is easy. If you don't think it should be done then SPA is not for you. If think it is easy, then we need to discuss that before we could discuss SPA. If you think it is hard, well SPA makes it easy. I am working on a more comprehensive answer to why SPA exists but I will not have it completed until the weekend so I am just trying to get a targeted answer for you.)</p> 2012-02-22T23:41:26-05:004846538http://forums.asp.net/p/1772721/4846538.aspx/1?Re+upshot+metadata+and+DbDataController+generic+controllerRe: upshot.metadata and DbDataController generic controller <p>@ColinBlair</p> <p>Hi, Thanks for the answer.&nbsp;</p> <p>I should specify what I meant clearly. My point of view is not to tell you guys to make this a simpler approach. <em><strong>In fact, the way I suggested requires more code to be hand-writtern by developer</strong></em>.</p> <p>What I am suggesting here (considering these are the early bits and very likely to change), make this approach cleaner and seperate the conserns a little bit more.</p> <p>With this approach, you are turning ASP.NET MVC into web forms application. Maybe lots of people will like it but I am also sure that lots of poeple think the way I think and hate this.&nbsp;</p> <p>As far as I remember well, I also saw this BigShelf example in a conference (by watching it online) and it was the project of RIA services with different approach of course.&nbsp;As a result, I am not judging you and I am nowhere to do that. Please make this clear. What I am telling is that people who like the things to be clear won't like this approach.</p> <p>Some of things I consider important:</p> <ol> <li>The metadata which provided to upshot is very dirty. </li><li>Please do not post samples publicly which you do things like serialization in the view. It is not ASP.NET MVC I got used to. You guys has been screaming for long time to&nbsp;emphasize the seperation of concern. </li><li>Please tell how do we suppose to unit test out controller which are implemented like the way I posted above.&nbsp; </li><li>How about our repository classes which integrates with Entity Framework DbContext? </li></ol> &lt;div&gt;The good parts:&lt;/div&gt; &lt;div&gt; <ol> <li>Certainly knockout.js. The way it works so much suite for an ASP.NET MVC application. It really seperate the concerns. It has been around long time but I didn't realize how much I can benefit from it. </li></ol> &lt;/div&gt; <p>I hope I am more clear now.</p> 2012-02-23T07:01:29-05:004847148http://forums.asp.net/p/1772721/4847148.aspx/1?Re+upshot+metadata+and+DbDataController+generic+controllerRe: upshot.metadata and DbDataController generic controller <p>Wow, and I thought that the Silverlight.net forums were buggy. Sorry, I will have to reply later. I already spent half an hour composing a reply and when I posted it the entire post was replaced with one quote from you so I am editing it to add some actual content.</p> <p>I will leave three things:</p> <p>1) <a href="http://blogs.msdn.com/b/kylemc/archive/2011/08/18/unit-testing-a-wcf-ria-domainservice-part-1-the-idomainservicefactory.aspx"> http://blogs.msdn.com/b/kylemc/archive/2011/08/18/unit-testing-a-wcf-ria-domainservice-part-1-the-idomainservicefactory.aspx</a></p> <p>That shows how we used a repository with the DomainService. DataController is a refactoring of the DomainService so hopefully you will get the general idea of how it works.</p> <p>2) If you haven't watched it yet, here is Steve Sanderson's talk on SPA <a href="http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2159"> http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2159</a></p> <p>3) SPA is far from turning ASP.NET MVC into Web Forms.&nbsp;It is closer to turning ASP.NET MVC into a plugin-less version of Silverlight that uses HTML/JS instead of XAML/C#. You may or may not be interested in such a thing, but I know that I am.</p> <p>Oh, also since people here in ASP.net land may not know me, I am a Connected Systems Development MVC who spends all of his free time helping people with RIA Services and, now, SPA, not a Microsoft employee.</p> 2012-02-23T11:19:06-05:004847181http://forums.asp.net/p/1772721/4847181.aspx/1?Re+upshot+metadata+and+DbDataController+generic+controllerRe: upshot.metadata and DbDataController generic controller <p>Thanks again. Not the answer to my question but definately helpful.</p> <p>BTW, I wathced the video on techdays. I have no issue on how it works. I am more concerned about the abstraction you have put which ASP.NET MVC is not used to.</p> <p>And I might find out the reason why I didn't like the approach:</p> <p><em>&quot;&nbsp;SPA is far from turning ASP.NET MVC into Web Forms.&nbsp;It is closer to turning ASP.NET MVC into a plugin-less version of Silverlight that uses HTML/JS instead of XAML/C#.&quot;</em></p> <p><i><br> </i></p> 2012-02-23T11:36:18-05:004897298http://forums.asp.net/p/1772721/4897298.aspx/1?Re+upshot+metadata+and+DbDataController+generic+controllerRe: upshot.metadata and DbDataController generic controller <p>The upshot library is completely optional. &nbsp;It is just abstracting out the underlying data management AJAX calls and simplifying synchronization of your model between the server side code and your client side Javascript. &nbsp;You are free to use Knockout with a bunch of AJAX calls if you don't like the way upshot library works.</p> <p></p> 2012-03-24T15:05:21-04:004909478http://forums.asp.net/p/1772721/4909478.aspx/1?Re+upshot+metadata+and+DbDataController+generic+controllerRe: upshot.metadata and DbDataController generic controller <p></p> <blockquote><span class="icon-blockquote"></span> <h4>tugberk_ugurlu_</h4> <em><strong>In fact, the way I suggested requires more code to be hand-writtern by developer</strong></em>.</blockquote> <p></p> <p>I had thoughts similar to yours when I started experimenting with upshot. However, I think it is not intended for use in complex layered applications. It supports three typer of DataProviders: One for the DBDataController, One for oData, And one for Ria. Well,...all tthe above sources, are kind of databases exposed on the web. So the the arcchitecture upshot is built for is:</p> <p>1) A data layer exposed on the web</p> <p>2) A presentation layer based on knokcout js. Separation of concerns between data and graphical stuffs is put in place by knockout bindings that connect client models to the graphical stuffs</p> <p>3) The pipeline that connects the data layer to the graphical stuffs is generated quite automatically to allow rapid prototypimg, and to lower the barrier to enter the new technology so it can be used also by not very experienced developers.</p> <p>This means : substantially no Business layer, and limited possibility of customization.</p> <p>While this implies that this techonolgy cannot be used for complex layered applications, it means also that this technology allows the implementation of simple application with a few mouse clicks, with a simplicity that is comparable to the one of webforms...HOWEVER in this case the application is WELL LAYERED (there is no business layer, but the remaining layers are separated acceptably).</p> <p>That's all !&nbsp;</p> <p>I think this technology may contribute to increase the quantity of people that use Mvc. Developers may start implementing simple applications in a quite automatic way..and then the may start to do more complex things.</p> <p>Summing up, it is not a bad idea...also if probably it is not targetted to &nbsp;complex layered applications that needs a &quot;robust&quot; business layer, and more &quot;customization&quot;.</p> <p>That said, since I personally need &nbsp;a tool that might simplify the job of exchanging data with the server ALSO FOR MORE COMPLEX LAYERED APPLICATION, I implemented a set of tools that do the hard job of interacting with the server, while leaving more room to code hand-written by the devloper, by:</p> <ol> <li>helping in building queries to send to an ApiController,(ANY Api controller, not only a DbDataController) </li><li>Computing the change set to send to the server after a collection of data has been modified by the user </li><li>Dispatching the errors returned by the server in the right places in the UI </li></ol> <p>I just finished testing and I need just to pack everything,...so I will release everything in a few days. see here for more information:&nbsp;<a href="http://mvccontrolstoolkit.codeplex.com/">http://mvccontrolstoolkit.codeplex.com/</a></p> 2012-03-31T09:41:16-04:00