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.
Here is my issue:
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:
What you have done here is very shocking for me. Then I saw this below line of code at the same page:
@{
ViewBag.Title = "Big Shelf - Read books, share books.";
var profile = (Profile)ViewBag.UserProfile;
var friendsJson = new JavaScriptSerializer().Serialize(profile.Friends.Select(f => new { f.FriendId, f.FriendProfile.Name }));
}
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?
In the long run, this approach, which is creating javascript code with html helper, will definately suck! I do not want to generate javascript code with htmlhelpers. This is no different than web forms in my point of view.
On the other hand, the apicontroller class starts with below code which makes me wonder as well:
public class BigShelfController : DbDataController<BigShelfEntities>
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.
Only thing which is good among those in that SPA sample is knockout which adds more value. It really seperates the concerns.
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.
I would be more than happy if you can give me a feedback here.
It is a fair question. Before I answer the question, let me ask a 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 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 the end of the 10 views the user can then go back to the
views and make additional changes, and then can 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?
(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.)
I should specify what I meant clearly. My point of view is not to tell you guys to make this a simpler approach.
In fact, the way I suggested requires more code to be hand-writtern by developer.
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.
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.
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. 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.
Some of things I consider important:
The metadata which provided to upshot is very dirty.
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 emphasize the seperation of concern.
Please tell how do we suppose to unit test out controller which are implemented like the way I posted above.
How about our repository classes which integrates with Entity Framework DbContext?
<div>The good parts:</div> <div>
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.
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.
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.
3) SPA is far from turning ASP.NET MVC into Web Forms. 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.
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.
Thanks again. Not the answer to my question but definately helpful.
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.
And I might find out the reason why I didn't like the approach:
" SPA is far from turning ASP.NET MVC into Web Forms. It is closer to turning ASP.NET MVC into a plugin-less version of Silverlight that uses HTML/JS instead of XAML/C#."
The upshot library is completely optional. 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. You are free to use Knockout with
a bunch of AJAX calls if you don't like the way upshot library works.
In fact, the way I suggested requires more code to be hand-writtern by developer.
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:
1) A data layer exposed on the web
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
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.
This means : substantially no Business layer, and limited possibility of customization.
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).
That's all !
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.
Summing up, it is not a bad idea...also if probably it is not targetted to complex layered applications that needs a "robust" business layer, and more "customization".
That said, since I personally need 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:
helping in building queries to send to an ApiController,(ANY Api controller, not only a DbDataController)
Computing the change set to send to the server after a collection of data has been modified by the user
Dispatching the errors returned by the server in the right places in the UI
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: http://mvccontrolstoolkit.codeplex.com/
tugberk_ugur...
Participant
1944 Points
1344 Posts
MVP
upshot.metadata and DbDataController generic controller
Feb 22, 2012 09:42 PM|LINK
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.
Here is my issue:
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:
upshot.metadata({"Book:#BigShelf.Models":{"key":["Id"],"fields":{"AddedDate":{"type":"DateTime:#System"},"ASIN":{"type":"String:#System"},"Author":{"type":"String:#System"},"CategoryId":{"type":"Int32:#System"},"CategoryName":{"type":"CategoryName:#BigShelf.Models","association":{"name":"CategoryName_Book","thisKey":["CategoryId"],"otherKey":["Id"],"isForeignKey":true}},"Description":{"type":"String:#System"},"FlaggedBooks":{"type":"FlaggedBook:#BigShelf.Models","array":true,"association":{"name":"Book_FlaggedBook","thisKey":["Id"],"otherKey":["BookId"],"isForeignKey":false}},"Id":{"type":"Int32:#System"},"PublishDate":{"type":"DateTime:#System"},"Title":{"type":"String:#System"}},"rules":{},"messages":{}},"CategoryName:#BigShelf.Models":{"key":["Id"],"fields":{"Books":{"type":"Book:#BigShelf.Models","array":true,"association":{"name":"CategoryName_Book","thisKey":["Id"],"otherKey":["CategoryId"],"isForeignKey":false}},"Categories":{"type":"Category:#BigShelf.Models","array":true,"association":{"name":"CategoryName_Category","thisKey":["Id"],"otherKey":["CategoryId"],"isForeignKey":false}},"Id":{"type":"Int32:#System"},"Name":{"type":"String:#System"}},"rules":{},"messages":{}},"Category:#BigShelf.Models":{"key":["Id"],"fields":{"CategoryId":{"type":"Int32:#System"},"CategoryName":{"type":"CategoryName:#BigShelf.Models","association":{"name":"CategoryName_Category","thisKey":["CategoryId"],"otherKey":["Id"],"isForeignKey":true}},"Id":{"type":"Int32:#System"},"Profile":{"type":"Profile:#BigShelf.Models","association":{"name":"Profile_Category","thisKey":["ProfileId"],"otherKey":["Id"],"isForeignKey":true}},"ProfileId":{"type":"Int32:#System"}},"rules":{},"messages":{}},"Profile:#BigShelf.Models":{"key":["Id"],"fields":{"AspNetUserGuid":{"type":"String:#System"},"Categories":{"type":"Category:#BigShelf.Models","array":true,"association":{"name":"Profile_Category","thisKey":["Id"],"otherKey":["ProfileId"],"isForeignKey":false}},"EmailAddress":{"type":"String:#System"},"FlaggedBooks":{"type":"FlaggedBook:#BigShelf.Models","array":true,"association":{"name":"Profile_FlaggedBook","thisKey":["Id"],"otherKey":["ProfileId"],"isForeignKey":false}},"Friends":{"type":"Friend:#BigShelf.Models","array":true,"association":{"name":"Profile_Friend","thisKey":["Id"],"otherKey":["ProfileId"],"isForeignKey":false}},"Id":{"type":"Int32:#System"},"Name":{"type":"String:#System"}},"rules":{"EmailAddress":{"required":true,"email":true},"Name":{"required":true}},"messages":{}},"FlaggedBook:#BigShelf.Models":{"key":["Id"],"fields":{"BookId":{"type":"Int32:#System"},"Id":{"type":"Int32:#System"},"IsFlaggedToRead":{"type":"Int32:#System"},"ProfileId":{"type":"Int32:#System"},"Rating":{"type":"Int32:#System"}},"rules":{},"messages":{}},"Friend:#BigShelf.Models":{"key":["Id"],"fields":{"FriendId":{"type":"Int32:#System"},"FriendProfile":{"type":"Profile:#BigShelf.Models","association":{"name":"Profile_Friend1","thisKey":["FriendId"],"otherKey":["Id"],"isForeignKey":true}},"Id":{"type":"Int32:#System"},"ProfileId":{"type":"Int32:#System"}},"rules":{},"messages":{}}});And the actual code which produces that is as below:
What you have done here is very shocking for me. Then I saw this below line of code at the same page:
@{ ViewBag.Title = "Big Shelf - Read books, share books."; var profile = (Profile)ViewBag.UserProfile; var friendsJson = new JavaScriptSerializer().Serialize(profile.Friends.Select(f => new { f.FriendId, f.FriendProfile.Name })); }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?
In the long run, this approach, which is creating javascript code with html helper, will definately suck! I do not want to generate javascript code with htmlhelpers. This is no different than web forms in my point of view.
On the other hand, the apicontroller class starts with below code which makes me wonder as well:
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.
Only thing which is good among those in that SPA sample is knockout which adds more value. It really seperates the concerns.
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.
I would be more than happy if you can give me a feedback here.
tweets as @tourismgeek
ColinBlair
Member
146 Points
36 Posts
Re: upshot.metadata and DbDataController generic controller
Feb 22, 2012 11:41 PM|LINK
It is a fair question. Before I answer the question, let me ask a 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 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 the end of the 10 views the user can then go back to the views and make additional changes, and then can 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?
(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.)
Upshot Blog
ColinBlair on Twitter
MVVM and RIA Services
tugberk_ugur...
Participant
1944 Points
1344 Posts
MVP
Re: upshot.metadata and DbDataController generic controller
Feb 23, 2012 07:01 AM|LINK
@ColinBlair
Hi, Thanks for the answer.
I should specify what I meant clearly. My point of view is not to tell you guys to make this a simpler approach. In fact, the way I suggested requires more code to be hand-writtern by developer.
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.
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.
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. 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.
Some of things I consider important:
- The metadata which provided to upshot is very dirty.
- 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 emphasize the seperation of concern.
- Please tell how do we suppose to unit test out controller which are implemented like the way I posted above.
- How about our repository classes which integrates with Entity Framework DbContext?
<div>The good parts:</div> <div>- 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.
</div>I hope I am more clear now.
tweets as @tourismgeek
ColinBlair
Member
146 Points
36 Posts
Re: upshot.metadata and DbDataController generic controller
Feb 23, 2012 11:19 AM|LINK
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.
I will leave three things:
1) http://blogs.msdn.com/b/kylemc/archive/2011/08/18/unit-testing-a-wcf-ria-domainservice-part-1-the-idomainservicefactory.aspx
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.
2) If you haven't watched it yet, here is Steve Sanderson's talk on SPA http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2159
3) SPA is far from turning ASP.NET MVC into Web Forms. 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.
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.
Upshot Blog
ColinBlair on Twitter
MVVM and RIA Services
tugberk_ugur...
Participant
1944 Points
1344 Posts
MVP
Re: upshot.metadata and DbDataController generic controller
Feb 23, 2012 11:36 AM|LINK
Thanks again. Not the answer to my question but definately helpful.
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.
And I might find out the reason why I didn't like the approach:
" SPA is far from turning ASP.NET MVC into Web Forms. It is closer to turning ASP.NET MVC into a plugin-less version of Silverlight that uses HTML/JS instead of XAML/C#."
tweets as @tourismgeek
jbrinkman
Star
9822 Points
1963 Posts
Re: upshot.metadata and DbDataController generic controller
Mar 24, 2012 03:05 PM|LINK
The upshot library is completely optional. 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. You are free to use Knockout with a bunch of AJAX calls if you don't like the way upshot library works.
francesco ab...
All-Star
20954 Points
3286 Posts
Re: upshot.metadata and DbDataController generic controller
Mar 31, 2012 09:41 AM|LINK
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:
1) A data layer exposed on the web
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
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.
This means : substantially no Business layer, and limited possibility of customization.
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).
That's all !
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.
Summing up, it is not a bad idea...also if probably it is not targetted to complex layered applications that needs a "robust" business layer, and more "customization".
That said, since I personally need 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:
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: http://mvccontrolstoolkit.codeplex.com/
Mvc Controls Toolkit | Data Moving Plug-in Videos