ASP.NET MVC ,Maintaining Model State between Ajax requests - asp.net-mvc

problem:
On first full page request, my controller invokes an applicationServices Layer (Web Service Proxy to my business tier) in order to populate a collection of current services that is stored in my own controller base class property. This is then to be displayed within a view.
Everything within the context of that controller has access to this "Services Collection". Now when i make further calls to the same action method via an AJAX Call, i obviously hitt a different instance of that controller meaning my services collection is empty.
So other than re-getting the whole collection again, where would i store this collection so it gets persisted between ajax requests? Should i persist it as a seperate DomainModel Object, Session object?....as ViewData is not working for me obv. Excuse my MVC ignorance :)
Any help would be greatly appreciated :)

The web is essentially stateless and MVC helps you to go down to the metal, that is, MVC does not try to make something stateful that isn't, which is mostly the path of ye olde ASP: Each request is a request of it's own and it shouldn't know anything about any other request that has been performed in the past.
I feel it is easiest to go down exactly that route, because it it tends to stay clean, fast and helps you in adhering to best practices such as separation of concerns.
AJAX takes this a step further: The idea of AJAX is that a simple 'delete' operation can be implemented as such, i.e. you only need to authorize and perform one very small query on the persistence layer. That's it. You don't even need to pass a modified page back to the user. A simple machine-readable success/error indication via JSON is sufficient.
If you start to pull lots of services around for small AJAX requests, you really lose most of what it's good for.
I'd also suggest you don't store a bunch of services in a base controller. Chances are that for most requests, you will only need a small subset of these. It's best practices to retrieve only those service you absolutely positively need.

Related

How is breeze.js handling security and avoiding exposing business logic

We are considering breeze js to build enterprise applications.
The awesomeness of breeze is that we can execute queries right from the client browser. This allows to constructs dynamic queries based on the users input without loading unnecessary data. I have found that using Breeze we can create business logic that reduces data traveling/transferring by 1/10 or even more when using a lazy loading strategy. using queries like these
Hooray breeze!!!
But what about Business Logic security,
For example, We could have a repository in which we could conceal, hide and obscure our business logic; and then use MVC Web API controllers to just make calls to those repository C# classes. so Breeze JavaScript talks to the WebAPi controller and the WebApi controller talks to the C# repository. The Controllers will always be kept very simple and easy to read, but the Repository may end up having lots of business logic for the company using the application. So if a hacker uses, for example, the Google Chrome developer's console to inspect the JavaScript code, all he/she will see are things like GetCustomers(), GetProductsForThisId(54). There is not much information that can be seen (or stolen) there. Because 90% of the Business Logic will live on the C# repository on the server .
How is breeze.js handling that ?
If we start moving the queries and business logic "from the controller's C# to the breeze JavaScript", we have to consider that our system is membership based. I think the more queries we expose to the client in JavaScript, the more vulnerable our software becomes, and the more we tell hackers how to hack our website and possibly steal information.
Security is a vital concern. It is wise to think carefully about the data and logic exposed on the client. How can we refine these sentiments into a concrete question suitable for an SO answer?
Nothing about Breeze should cause you to expose business logic to the JavaScript client. You can (and should) lock such logic safely inside your repositories and/or controller methods.
But I struggle to understand how client queries themselves are the kinds of business logic that need protecting. Where's the danger in a query for a customer whose name begins with 'A'?
You may rightly worry about a query for customers with net worth > $100,000. But the fault is not in the query. The fault would be in exposing such customer information to unauthorized users by any means, whether through a Breeze where clause appended to a query or a call to a service named GetCustomers().
The place to block unauthorized access to customers is on the server and you can do that as easily inside a Breeze controller action method returning IQueryable as you can in your GetCustomer() method. The burden falls on you in either case to impose the necessary security constraints on your controller and within the methods that you expose.
You write the controller. You write the repositories. You have access to the user's permissions. You are in complete control with an uncompromised ability to expose as much or as little as you wish.
FWIW, your Breeze EntityManager can call service methods that do not return IQueryable<Customer>. It can call Web Api controller methods such as IEnumerable<Customer> GetCustomers() or Product GetProductForId(int id). In my opinion you will lose the flexibility of Breeze's query facilities without gaining any security. But that's just my opinion. Breeze will support your choice, whatever it may be.
I'd be happy to try to answer a more specific "how to" question.
would like to add that you can restrict users that are not authorized from quering by using the attributes in webapi if you get 401 code back from the server just popup a login screen and redo the work needed after the user is logged in
so a user may try to get data about an order but he won't get it unless he is authorized to do so
You can to a lot of stuff using breeze.js
First of all check my answer regarding security here
How to handle authorization with Breeze JS?
Also although breeze.js can be used like a normal ORM on the client (which can be extremely helpful at times), you should keep your business logic in web api controllers and expose only the necessary stuff using OData queries.
If you need any data manipulation logic, then you should do it on the server using a specific method for that.
Only UI logic should be present on the client, also consider that there are several performance implications if you start performing multiple queries directly from the client. Either expand the entity graph to load more results or use more specialized methods that return object. Breeze will introspect the results and consume the entities happily without implications.

Is it a good practice to use an MVC application's own Web API for Ajax bindings?

I'm writting an application that has many Ajax widgets (Kendo-UI to be percise). It's starting to get messy to have all those Ajax responses without the standard controllers so I was starting to consider making each entities their own controller. If I'm taking the time to do this, I figured I might as well go foward and do those as WebAPIs since I was planning to do this in a not so close future, but hey, it would be done already...
So my question is: Is it a good practice to use an MVC application's own Web API as a Ajax Widget feeds or is there any reason to stick with standard Controllers?
I've seen some arguments about performance, but I don't think this applies to this situation. I believe it was more of a "Controller calling WebAPI" situation which has obvious performance hits. But since it's already a client side Ajax call, weither it goes into a standard MVC Controller or a WebAPI controller shouldn't change a thing, would it?
Edit
Additional information regarding the project:
I am using Entity Framework for the data access.
I have a repository pattern going on with UnitOfWork.
I am using proper a MVC structure (EF POCOs AutoMapped to DTO POCOs in the repository and fed into View Models by the controllers)
This is a MVC 4 project on .NET 4.0
There is a lot of database relationships (specially for the object I'm working with at the moment)
I don't know about "good practice", but it's certainly not "bad practice". I see no difference whether you do it in the app or a different one.
I think its a good thing but only if what you are doing in the API is kept as generic as possible to other applications and services can reuse the API.
Both the applications I have written and continue to maintain use pretty much the exact same stack as your app.
I have recently re-factored one of the applications to use the API for all the common things like lists that I'm binding to Kendo ComboBoxes etc. in my views. Its a fairly large application that re-uses a lot of the same lists such as states, priorities, complexities across various Entities and views so it makes sense to put those in the API.
I haven't gone as far as going the whole hog through. I draw the line with things like this:
public ActionResult GetAjaxProjectsList([DataSourceRequest]DataSourceRequest request)
{
return Json((DataSourceResult)GetProjectsList().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
That is very specific to how the Kendo Grid wants the data back. Nothing else I have connecting to this app will use this data in this format so I keep it in the controller.
In short... I use the API for common things within the same MVC app and things that I allow to be used by other applications or services, like Excel.

Using Repositories and service references in MVC controllers

I'm having some trouble with deciding on a solution for my mvc application.
Background.
We have an EF model which we perform operations on via WCF Services (not data services).
I have an MVC application which has a number of Repositories that talk directly to the Services and return WCF types back to a controller which is calling the repository method, a type called for example WCFUserEntity (it's not actually prefixed with WCF).
Inside the controller I plan to automap the WCFUserEntity to a ViewModel entity.
What is bugging me about this solution is that because i'm returning WCFUserEntity to the controller I have to have a reference to the WebService proxy in my controller which doesn't sit well with me, i'd like my controllers to know nothing of where the repository has got the data from. So another option for me is to do the automapping inside of the repository and return the ViewModel entity to the controller, i can't find much around which supports this idea though, so really what i'm looking for is validation of this 2nd solution or help with a 3rd.
thanks, Dom
You may want to consider a third option.
The use of ViewModelBuilders.
in your controller they would work like this:
var myViewModel = myViewModelBuilder.WithX().WithY().Build();
WithX and WithY would be methods that would add stuff to your viewmodel internally (within the builder, for example WithCountriesList() if you want to add a dropdown showing the countries in your view) and the Build method would return the internal viewmodel after adding all the bits with the WithXXX methods. This is so because most of the time you may want to add lists for dropdowns and things that are not part of your original model (your userEntity in this case).
This way, your controller doesn't know anything about how to build the viewmodel, your repository is also agnostic of viewmodels. All the work is done in the Builder. On the downside, you need to create a ViewModelBuilder for each ViewModel.
I hope this helps.
How I would approach this might require some architecture changes, but I would suggest you approach your WCF API to return ViewModels instead of entities.
For starters, think about bandwidth issues (which would be an issue if you are hosting the WCF in Azure or the cloud). If your ViewModel is only using a few specific properties, why waste the bandwidth returning the other data? In high traffic scenarios, this could cause a waste of traffic that could end up costing money. For example, if your view is only display a user and his questions, there's no reason to send his email, answers, point count, etc.. over the wire.
Another issue to think about is eager loading. By having the WCF service return a ViewModel, you know you have all the data (even when it pertains to related entities) required from the view in one trip to the WCF service. You do not need to get the WCFUserEntity and then ask WCF for WCFDocumentEntities that are related to that specific user.
Finally, if your WCF API is built around ViewModels then you have a MUCH clearer understanding of the business processes involved. You know that this specific request (and view in the system) will give you this specific information, and if you need different information for a different view then you know that it's a completely different business request that has different business requirements. Using stack overflow as an example, it makes it trivial to see that this business process is asking for the current user with his related questions, while this business process is requesting the current user with his related answers.
Using ViewModels in your data retrieval WCF API means that your frontend layers do not necessarily know where the data came from, it just knows that it called a business process and got the data it needs. As far as it knows the data layer connected to the database directly instead of WCF.
Edit:
After re-reading, this actually looks like your 3rd option. Most research on the net don't talk about this option, and I don't know why, but after having some similar frustrations you are having (plus others listed in this post) this is the way I have gone with my business layer. It makes more sense and is actually (imho) easier to manage.

Use MVC Custom Model Binder?

I have an MVC app I'm writing. There will be the need for multiple instances of the same page to be open, each accessing different records from a database, these record objects will also need to be passed through a flow of pages, before finally being updated.
What's the best, and most correct, way of acheiving this - should/can I create a custom model binder that links to an object via it's unique ID and then create each record-object in the session, updating them as I go through each one's page flow and then finally calling the update method? Or is there a better way of dealing with this?
Cheers
MH
Technically, that would be possible, but I don't think it is advisable. When you look at the signature of IModelBinder, you will have to jump through some hoops related to the ControllerContext if you want to be able to access the rest of your application's context (such as how to dehydrate objects based on IDs).
It's possible, but so clunky that you should consider whether it's the right approach. In my opinion, a ModelBinder's responsibility is to map HTTP request data to strongly typed objects. Nothing more and nothing less - it is strictly a mapper, and trying to make it do more would be breaking the Single Responsibility Principle.
It sounds to me like you need an Application Controller - basically, a class that orchestrates the Views and the state of the underlying Model. You can read more about the Application Controller design pattern in Patterns of Enterprise Application Architecture.
Since a web application is inherently stateless, you will need a place to store the intermediate state of the application. Whether you use sessions or a custom durable store to do that depends on the application's requirements and the general complexity of the intermediate data.

In MVC, what are the limitations on the Controller?

Should the Controller make direct assignments on the Model objects, or just tell the Model what needs to be done?
The controller has two traditional roles:
handling the input event from the UI (registered handler or callback)
notifying the model of an action--which may or may not result in a change on the model's state
It does not perform data validation, that is on the model, nor does it have any say in how information is presented.
It depends largely on the scope of your application. If it's relatively quick and dirty, then there's no sense in over-engineering, and sure, your controllers can talk to your model objects. On the other hand, if it needs to be more "enterprisey" for whatever reason, a good pattern to use in conjunction with MVC is the so-called "Business Delegate". This is where you can compose coarse-grained methods out of one or more methods on one or more model objects; for instance deleting an object and then returning a refreshed list without that object. This layer gives two advantages. For one, it decouples the controllers from whatever ORM system is being used for model objects. Furthermore, it is the layer that finally must constructively deal with any exceptions that may have occurred instead of re-throwing them.
I don't think a controller should be dealing with model objects.
I tend to think that controller is really part of the UI tier. I prefer to inject a service layer in-between the controller and the rest of the app. The web tier accepts HTTP requests, unmarshals parameters from request objects into objects that the service interface can deal with, and marshals the response to send back. All the work with transactions, units of work, and dealing with model and persistence objects is done by the service.
This approach is more service oriented. It separates the service from the user interface, leaving open the possibility that several clients can reuse the same service. It makes the layer that marshals requests to the service "thin", so it's easy to switch out SOAP services for REST or EJB or CORBA or whatever the next new thing will be.
The Model services don't have to know the existence of the controller, thus, controller can do the stuff what ever the view needs by utilising the model services.

Resources