I'm writing a web application that will mainly use AngularJS for its modularity and testability and ASP.NET MVC server side technologies for model validation.
The idea is to load PartialViews in ng-views in order to asynchronously load only specific logic parts. So the question is: how to better pass server-side objects to AngularJS controllers? A silly hack that comes to mind is to print things in the PartialView such as:
window.myValue = 42;
and then get it back from the controller with the $window service injected:
$scope.myValue = $window.myValue
This is not feasible, though, as ng-view loadings strip out every <script> tag before inserting the partial content into the DOM.
I have noticed that there is the ng-init directive, should I rely on that one alone? Generally speaking, what are the best practices for making these two parts work with each other?
Thanks.
If you are unable to use a REST service (best option) you can easily do exactly what you suggest in your question but perhaps in more modular way. You can encode your view's model and place it in a global variable and then have a service that pulls this out:
Here is an example:
<body ng-controller="MainCtrl">
<div>ID: {{data.id}}</div>
<div>Name: {{data.name}}</div>
<script type='text/javascript'>
// mystuff = #Html.Raw(Json.Encode(Model)); Encode the model to json
mystuff = { id: 1, name: 'the name'};
</script>
</body>
app.controller('MainCtrl', function($scope, DataService) {
$scope.data = DataService.getData('mystuff');
});
app.factory('DataService', function($window) {
var service = {}
service.getData = function(data) {
if ($window[data] !== undefined)
return $window[data];
else
return undefined;
}
return service;
});
Demo: http://plnkr.co/edit/jqm2uT3kbDm2U30MCf48?p=preview
You'd might want to create a standardized model that you use in all of your pages. This is a bit hacky and a REST service is your best option as others have stated.
I ended up using the ng-init directive.
Luckily, I got to restructure the Web application and go for a single page, client-side, application based on Web services only.
Related
I am asp.net Web Forms developer and i know the basics of Asp.net MVC. Developers talk about advantages of MVC but I haven't come across a clear or compelling description for using MVC over Asp.NET.
This is not duplicate question and i have gone through almost all
similar question but did not get clear description more in relation
with real life example. I do appreciate and expect the explanation of
each and every question mentioned below with real life example please
don't mark it as duplicate.
I know that you can not replace Asp.NET Web Forms with Asp.NET MVC still we have following advantages in MVC:
Separation of concerns (SoC): We can achieve it in asp.net also by adding BAL component in fact in MVC we do have to isolate business logic from controller action methods.Is SoC only applicable for Model-View-Controller separation in MVC? then what about business logic. Please provide real life example which will consider both Web Forms and MVC.
Enable full control over the rendered HTML: Web Forms also provide control over Html isn't it? Its considered that html rendering in Web Forms is more abstracted then what does html helper methods do in MVC. Anybody please explain it with example considering both Web Forms and MVC as i am getting more confused over this point.
Enable Test Driven Development (TDD): If you have separated your Business logic into BAL then you have achieved TDD? Is there any scenario where MVC would be accurate choice over webforms? Please provide example for same
No ViewState and PostBack events: We can manage viewstate in Web Forms which comes with cost of efforts, since in MVC we can maintain state by using Viewbag,Tempdata as web is stateless there is some mechanism that MVC maintains its state as hidden fields for Web Forms then how MVC Improves performance and page size in terms of statefullness? Example by considering Web Forms and MVC appreciated
Easy integration with jQuery: "Asp.NET Web Forms generate its custom id for controls" this is the only consideration for ease of integration of JavaScript frameworks? if yes then we can use ClientIDMode in asp.net control in Web Forms
1. Separation of concerns
SoC in MVC is not about separation business logic from UI. More importantly, it gives Controller main functions:
to fill View Model from Domain Model;
to handle View activity;
to show views depending on Domain logic.
View is responsible only for data representation in MVC.
It makes testing very simple as Controller operates pure View Model classes, opposed to WebForms which operates events and Form.
In WebForms View handles all UI activity and it basically makes decisions about scenario flow.
Here I'd like to mention that terms of View Model and Domain Model are different. Domain Model is a term describing all the services, Business logic and DAL hidden from Controller with some facade. And View Model is a class that encapsulates data required by View. It may be shared by Domain Model in simple cases. Why two classes?
Here are similar code snippets of ASP.NET MVC and WebForms doing the same things: 1) get data 2) handle data submission. In both cases I assume that IDomainModel is injected.
MVC:
public class SomeController : Controller
{
// injected
public IDomainModel Domain { get; set; }
public ViewResult Edit()
{
var record = Domain.GetRecord(1);
var dictionary = Domain.GetSomeDictionary();
var model = new SomeViewModel(record, dictionary);
return View(model);
}
[HttpPost]
public ActionResult Edit(SomeViewModel model)
{
if (ModelState.IsValid)
// save
return RedirectToAction("Result");
else
return View(model);
}
}
WebForms:
public partial class SomePage : System.Web.UI.Page
{
// injected
public IDomainModel Domain { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
var record = Domain.GetRecord(1);
var dictionary = Domain.GetSomeDictionary();
RecordId.Text = record.Id.ToString();
RecordName.Text = record.Name;
RecordDescription.Text = record.Description;
DicValue.DataSource = dictionary;
DicValue.DataValueField = "Id";
DicValue.DataTextField = "Value";
DicValue.SelectedValue = record.DictionaryEntryId.ToString();
DicValue.DataBind();
}
protected void btnSave_Click(object sender, EventArgs e)
{
var record = new RecordModel
{
Id = Int32.Parse(this.RecordId.Text),
Name = this.RecordName.Text,
Description = this.RecordDescription.Text,
DictionaryEntryId = Int32.Parse(this.DicValue.Text)
};
// save
}
}
Testing MVC controller Edit GET is incredibly simple:
[TestMethod]
public void EditGetTest()
{
SomeController target = new SomeController();
var record = new RecordModel { Id = 1, Name = "name1", Description = "desc1", DictionaryEntryId = 1 };
var dictionary = new List<SomeDictionaryEntry>
{
new SomeDictionaryEntry { Id = 1, Value = "test" }
};
target.Domain = new SimpleMVCApp.Models.Fakes.StubIDomainModel()
{
GetRecordInt32 = (id) => { return record; },
GetSomeDictionary = () => { return dictionary; }
};
var result = target.Edit();
var actualModel = (SomeViewModel)result.Model;
Assert.AreEqual(1, actualModel.Id);
Assert.AreEqual("name1", actualModel.Name);
Assert.AreEqual("desc1", actualModel.Description);
Assert.AreEqual(1, actualModel.DictionaryEntryId);
}
To test WebForms events we need to make a lot of changes and assumptions: we need to make the methods public, we need to initialize Form and its controls. It results in heavy hard-read tests which are impossible for 3) TDD.
2. Enable full control over the rendered HTML
I think this statement is a little bit exaggeration. Only HTML can give full control over rendered HTML. As for HtmlHelpers, DisplayTemplates and EditorTemplates, though the team made major improvements over 6 versions of the framework, it's still sometimes annoying to transform additionalViewData into html attributes.
For example, to pass some html attributes to an input you can't use #Html.EditorFor, you'll have to use #Html.TextBoxFor.
In the same time in ASP.NET you can specify any attributes on any elements and they will just render.
MVC:
Wrong:
#Html.EditorFor(m => m.Name, new { MySuperCustomAttribute = "Hello" })
Correct:
#Html.TextBoxFor(m => m.Name, new { MySuperCustomAttribute = "Hello" })
ASP.NET:
<asp:TextBox runat="server" ID="RecordName" MySuperCustomAttribute="hello"></asp:TextBox>
3. Enable Test Driven Development (TDD)
I think this statement is about testing of Controller vs Code-Behind. I covered this in 1.
4. No ViewState and PostBack events
ViewBag and ViewData are weak-typed facilities to pass data between Controller and Views. They are rendered as elements, nothing similar to ViewState. For example, in my View I initialize ViewBag.Title = "EditView"; which allows me to use this string on the Layout Page: <title>#ViewBag.Title - My ASP.NET MVC Application</title>. On the page it looks just like this <title>EditView - My ASP.NET MVC Application</title>
As to TempData, Session and Application, they are stored on server side. It's not rendered to page at all.
5. Easy integration with JQuery
I don't see how integration with JQuery becomes easier for MVC. Here is how we integrate JQuery into WebForms:
<script src="Scripts/jquery-1.8.2.min.js"></script>
<script>
$(document).ready(function () {
$('#DicValue').change(function () {
$('#ChosenValue').text($('#DicValue option:selected').val());
});
});
</script>
And here is almost the same snippet for ASP.NET MVC:
#section scripts{
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script>
$(document).ready(function () {
$('#DictionaryEntryId').change(function () {
$('#ChosenValue').text($('#DictionaryEntryId option:selected').val());
});
});
</script>
}
There is another point to mention about JQuery here: as ASP.NET MVC is pretty Opinionated framework, it becomes somewhat restrictive for extensive JS usage. It was originally designed for Scaffold Templates based development, and it is best with it. JQuery is good for ajax requests and for some minor logic in ASP.NET MVC, but when you start using it extensively, you end up with two controllers for every view: a C# one and a JS one. Hello, Unit Testing! Also JQuery(UI) is very good with its rich set of UI controls.
ASP.NET is designed with Postbacks in mind and they dictate you the basic application model. However, there are also different UI Toolkits for ASP.NET to make an application more dynamic and there is still some place for JQuery.
Wow, that was a long answer. Hope it'll help.
Ok.
I am developing applications in both frameworks i.e. Webforms and MVC, will be explaining things based on my experience.
Discipline is the most important thing that needs to be followed with any Architecture you are working on.
If you follow MVC correct and as per standards life would be super simple.
Lets go point by point.
Separation of concerns (SoC):
MVC provide Clean, organized and granular solution at various levels e.g.
There are multiple helper classes which hooks and does help in late bindings, you can mock controller using various plugins.
Easy to develop Helper classes.
Enable full control over the rendered HTML
Basically in MVC we have HTML in its native format, so you have more control over it and how it matters is it speeds up Page Load when you have lot of controls and data that are coming on the page.
And it matters when we are going with Web form architecture.
Enable Test Driven Development (TDD):
With discipline you can do it in both Architecture
No ViewState and PostBack events:
Viewstate puts extra load on page and in web forms when you see source of a page having lots of controls, grid etc, you will see huge viewstate.
If there is no viewstate life is just simple.
ViewData is at client side whereas others are at server side.
Easy integration with Jquery:
Indeed, MVC3, 4 have super better support for JQuery. There are lot of Predefined JQueries that are already introduced in templates.
Other than above points some additional points
Bundling
Refreshed and modernized default project templates
Better support of Mobile applications
Fast development
Code reusability
Least coupling within Layers
Good support to Ajax
Have a look at few links
http://www.codeproject.com/Articles/683730/New-Features-in-ASP-NET-MVC
http://www.asp.net/mvc/tutorials/hands-on-labs/whats-new-in-aspnet-mvc-4
Difference between ASP.NET MVC 3 and 4?
Here is the official answer from Microsoft for this question: http://www.asp.net/get-started/websites
I'd add to the top answers (which are generally correct) than MVC (and Web Pages) are both open source, so you have an easy access to the source code, bug database and can even PR bug fixes or features back (which we have taken in abundance).
At the end of the day it's a personal choice, and also depends on the experience you and your team has and if you have legacy code you want to reuse.
The MVC framework does not replace the Web Forms model; you can use either framework for Web applications. (If you have existing Web Forms-based applications, these continue to work exactly as they always have.)
Before you decide to use the MVC framework or the Web Forms model for a specific Web site, weigh the advantages of each approach.
Advantages of an MVC-Based Web Application
The ASP.NET MVC framework offers the following advantages:
It makes it easier to manage complexity by dividing an application into the model, the view, and the controller.
It does not use view state or server-based forms. This makes the MVC framework ideal for developers who want full control over the behavior of an application.
It uses a Front Controller pattern that processes Web application requests through a single controller. This enables you to design an application that supports a rich routing infrastructure.
It provides better support for test-driven development (TDD).
It works well for Web applications that are supported by large teams of developers and for Web designers who need a high degree of control over the application behavior.
Advantages of a Web Forms-Based Web Application
The Web Forms-based framework offers the following advantages:
It supports an event model that preserves state over HTTP, which benefits line-of-business Web application development. The Web Forms-based application provides dozens of events that are supported in hundreds of server controls.
It uses a Page Controller pattern that adds functionality to individual pages.
It uses view state on server-based forms, which can make managing state information easier.
It works well for small teams of Web developers and designers who want to take advantage of the large number of components available for rapid application development.
In general, it is less complex for application development, because the components (the Page class, controls, and so on) are tightly integrated and usually require less code than the MVC model.
Source http://msdn.microsoft.com/en-us/library/dd381412(v=vs.108).aspx
When, if ever, is it appropriate to render an angular partial view using Razor?
I've generally tried to stay away from mixing server side rendering with client-side rendering when using Angular but I have found it convenient to sometimes:
Set variables/data that is known server-side
An example might be a client API key that you might want to use client-side without making an additional call to a backend for that information.
Here is an example of a template:
<div config="{ soundcloudApiKey: '#soundcloudApiKey' }">
</div>
Where #soundcloudApiKey is presumably available in a model server-side and config is a directive that brings data from the markup into your Angular code in case you want to use it elsewhere:
myModule.directive('config', function() {
return {
link: function(scope, elm, attrs) {
// you can save config to a service and use it elsewhere
var config = scope.$eval(attrs.config);
console.log(config.soundcloudApiKey);
}
};
});
Note: there is likely a cleaner way to get to this type of configuration data like via a login process or an explicit call for config settings but I've used this type of thing in the past and it works just fine!
I'm starting MVC and I understand the difference between models and ViewModels, thanks to this post:
http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp.net-mvc-applications
However I showed this to my colleague and am now under the impression that this is an alternative to using knockout to bind views to models. Can someone explain this? Does knockout binding do the same thing as defining a ViewModel class with properties?
Thank you!
In convention you can use Knockout view-model is as client-side and MVC view-model is as server-side.
Your question : How do you decide which to use ?
Answer : You can use both as parallel.That means for your single cshtml page can have a knockout view-model is as below.It contains both properties and functions as a unit.This view-model for the behavior what you need for the client side functionality.
//This is a simple Viewmodel
//JavaScript that defines the data and behavior of your UI
function AppViewModel() {
var self = this;
self.firstName = ko.observable();
self.lastName = ko.observable();
self.fullName = ko.computed(function () {
return self.firstName() + " " + self.lastName();
});
self.capitalizeLastName = function () {
var currentVal = self.lastName();//Read the current value
self.lastName(currentVal.toUpperCase());//Write back a modified value
};
}
But for show server side behaviors you can use more complex (or more properties) with the MVC view-model.That is for bring data from database and show those data in your view.
Conclusion: So you can use both view-models simultaneously when working with MVC.
Important Note : But if you need to use single view-model for both scenarios then you can do that thing also.For that you have to use KnockoutJS Mapping plugin.
It can be used like below.
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script type="text/javascript">
$(function() {
var viewModel = ko.mapping.fromJS(#Html.Raw(Model.ToJson()));
ko.applyBindings(viewModel);
});
</script>
You can get more details about this from Loading KnockoutJS View Models from ASP.Net MVC, for faster page loads
If you need to know more about Knockout check learn.knockoutjs
I hope this will help to you.
Knockout view models are client side and MVC is server side, that is the big difference.
Knockout allows you to create single page applications, and encapsulates logic on the client side.
ViewModels in MVC only works server side for rendering the page and handle postbacks.
Xharze answer is valid, but...
If you need to add view related logic to your Business entities that can not be done Client side then you need to have server side View models. If not they become redundant.
There is still a difference to classic MVC, these server side models will not be used to render server side content, they will be exposed to the client side KO engine using REST
My title sums this up pretty well. My first though it to provide a few data formats, one being HTML, which I can provide and consume using the Razor view engine and MVC3 controller actions respectively. Then, maybe provide other data formats through custom view engines. I have never really worked in this area before except for very basic web services, very long ago. What are my options here? What is this Web API I see linked to MVC4?
NOTE: My main HTML app need not operate directly off the API. I would like to write the API first, driven by the requirements of a skeleton HTML client, with a very rudimentary UI, and once the API is bedded down, then write a fully featured UI client using the same services as the API but bypassing the actual data parsing and presentation API components.
I had this very same thought as soon as the first talk of the Web API was around. In short, the Web API is a new product from the MS .NET Web Stack that builds on top of WCF, OData and MVC to provide a uniform means of creating a RESTful Web API. Plenty of resources on that, so go have a Google.
Now onto the question..
The problem is that you can of course make the Web API return HTML, JSON, XML, etc - but the missing piece here is the Views/templating provided by the Razor/ASPX/insertviewenginehere. That's not really the job of an "API".
You could of course write client-side code to call into your Web API and perform the templating/UI client-side with the mass amount of plugins available.
I'm pretty sure the Web API isn't capable of returning templated HTML in the same way an ASP.NET MVC web application can.
So if you want to "re-use" certain portions of your application (repository, domain, etc), it would probably be best to wrap the calls in a facade/service layer of sorts and make both your Web API and seperate ASP.NET MVC web application call into that to reduce code.
All you should end up with is an ASP.NET MVC web application which calls into your domain and builds templated HTML, and an ASP.NET Web API application which calls into your domain and returns various resources (JSON, XML, etc).
If you have a well structured application then this form of abstraction shouldn't be a problem.
I'd suggest developing your application in such a way that you use a single controller to return the initial application assets (html, javascript, etc) to the browser. Create your API / logic in WebAPI endpoint services and access those services via JavaScript. Essentially creating a single page application. Using MVC 4 our controller can return different Views depending on the device (phone, desktop, tablet), but using the same JavaScript all of your clients will be able to access the service.
Good libraries to look into include KnockoutJS, SammyJS , or BackBoneJS
If you do have a requirement to return HTML using the WebAPI e.g. to allow users to
click around and explore your API using the same URL then you can use routing\an html message handler.
public class HtmlMessageHandler : DelegatingHandler
{
private List<string> contentTypes = new List<string> { "text/html", "application/html", "application/xhtml+xml" };
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Method == HttpMethod.Get && request.Headers.Accept.Any(h => contentTypes.Contains(h.ToString())))
{
var response = new HttpResponseMessage(HttpStatusCode.Redirect);
var htmlUri = new Uri(String.Format("{0}/html", request.RequestUri.AbsoluteUri));
response.Headers.Location = htmlUri;
return Task.Factory.StartNew<HttpResponseMessage>(() => response);
}
else
{
return base.SendAsync(request, cancellationToken);
}
}
}
For a full example check out:-
https://github.com/arble/WebApiContrib.MessageHandlers.Html
I've played with this idea before. I exposed an API through MVC3 as JSONResult methods on different controllers. I implemented custom security for the API using controller action filters. Then built a very AJAX heavy HTML front-end which consumed the JSON services. It worked quite well and had great performance, as all data transferred for the web app was through AJAX.
Frederik Normen has a good post on Using Razor together with ASP.NET Web API:
http://weblogs.asp.net/fredriknormen/archive/2012/06/28/using-razor-together-with-asp-net-web-api.aspx
One important constraint of a well designed REST service is utilizing "hypermedia as the engine of application state" (HATEOAS - http://en.wikipedia.org/wiki/HATEOAS).
It seems to me that HTML is an excellent choice to support as one of the media formats. This would allow developers and other users to browse and interact with your service without a specially built client. Which in turn would probably result in the faster development of a client to your service. (When it comes to developing actual HTML clients it would make more sense to use a json or xml.) It would also force a development team into a better designed rest service as you will be forced to structure your representations in such a way that facilitates an end users navigation using a browser.
I think it would be smart for any development team to consider taking a similar approach to Frederik's example and create a media type formatter that generates an HTML UI for a rest service based on reflecting on the return type and using conventions (or something similar - given the reflection I would make sure the html media format was only used for exploration by developers. Maybe you only make it accessible in certain environments.).
I'm pretty sure I'll end up doing something like this (if someone hasn't already or if there is not some other feature in the web api that does this. I'm a little new to Web API). Maybe it'll be my first NuGet package. :) If so I'll post back here when it's done.
Creating Html is a job for an Mvc Controller not for Web Api, so if you need something that is able to return both jSon and Html generated with some view engine the best option is a standard Mvc Controller Action methosd. Content Negotiation, that is the format to return, can be achieved with an Action Fiter. I have an action filter that enable the the controller to receive "hints" from the client on the format to return. The client can ask to return a view with a specific name, or jSon. The hint is sent either in the query string or in an hidden field (in case the request comes from a form submit). The code is below:
public class AcceptViewHintAttribute : ActionFilterAttribute
{
private JsonRequestBehavior jsBehavior;
public AcceptViewHintAttribute(JsonRequestBehavior jsBehavior = JsonRequestBehavior.DenyGet)
{
this.jsBehavior = jsBehavior;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
string hint = filterContext.RequestContext.HttpContext.Request.Params["ViewHint"];
if (hint == null) hint = filterContext.RequestContext.RouteData.Values["ViewHint"] as string;
if (!string.IsNullOrWhiteSpace(hint) && hint.Length<=100 && new Regex(#"^\w+$").IsMatch(hint) )
{
ViewResultBase res = filterContext.Result as ViewResultBase;
if (res != null)
{
if (hint == "json")
{
JsonResult jr = new JsonResult();
jr.Data = res.ViewData.Model;
jr.JsonRequestBehavior = jsBehavior;
filterContext.Result = jr;
}
else
{
res.ViewName = hint;
}
}
}
base.OnActionExecuted(filterContext);
}
}
Now that it's been a little while through the Beta, MS just released the Release Candidate version of MVC4/VS2012/etc. Speaking to the navigation/help pages (mentioned by some other posters), they've added a new IApiExplorer class. I was able to put together a self-documenting help page that picks up all of my ApiControllers automatically and uses the comments I've already put inline to document them.
My recommendation, architecture-wise, as others have said as well, would be to abstract your application into something like "MVCS" (Model, View, Controller, Services), which you may know as something else. What I did was separate my models into a separate class library, then separated my services into another library. From there, I use dependency injection with Ninject/Ninject MVC3 to hook my implementations up as needed, and simply use the interfaces to grab the data I need. Once I have my data (which is of course represented by my models), I do whatever is needed to adjust it for presentation, and send it back to the client.
Coming from MVC3, I have one project that I ported to MVC4, which uses the "traditional" Razor markup and such, and a new project that will be a single page AJAX application using Backbone + Marionette and some other things sprinkled in. So far, the experience has been really great, it's super easy to use. I found some good tutorials on Backbone + Marionette here, although they can be a bit convoluted, and require a bit of digging through documentation to put it all together, it's easy once you get the hang of it:
Basic intro to Backbone.js: http://arturadib.com/hello-backbonejs/docs/1.html
Use cases for Marionette views (I found this useful when deciding how to create views for my complex models): https://github.com/derickbailey/backbone.marionette/wiki/Use-cases-for-the-different-views
I'm diving into ASP.NET MVC and I'm coming from a Ruby on Rails background. I'm trying to understand how ASP MVC handles AJAX functionality and, after reading some of the tutorials on the ASP website, it appears they implement AJAX functionality very differently. One of the ways that RoR handles AJAX functionality is by returning ruby-embedded javascript code that is executed as soon as it is received by the browser. This makes implementing AJAX really simple and quite fun. Can ASP.NET MVC return a javascript response?
just user
return JavaScript(script)
You would have to execute the java script manually on the View
To be more specific you can make the controller action return type JavaScriptResult
What you are talking about is called javascript generators in the RoR world and there's no equivalent in the ASP.NET MVC world. Here's a blog post that illustrates the basics of implementing a Rails-like RJS for ASP.NET MVC (the blog post uses prototypejs but could be easily adapted to work with jquery).
Here's another approach using jquery:
public ActionResult Foo()
{
return Json(new { prop1 = "value1", prop2 = "value2" });
}
and to consume:
$.getJSON('/home/foo', function(result) {
// TODO: use javascript and work with the result here,
// the same way you would work in a RJS like template
// but using plain javascript
if (result.prop1 === 'value1') {
alert(result.prop2);
}
});
Also worth taking a look at is JsonResult which extends ActionResult. I usually use this when making AJAX requests for data of some sort.