How to combine Web Api and MVC best in a single web app - asp.net-mvc-4

I am about to create a simple web app and I am wondering if I should use ASP.NET MVC 4 new feature Web API.
What's the best way to do this ?
I've done some researches and I found out there are two option :
Option 1
Make the Web Api my service layer and call it from the controller to read/write data, and render the view using view models and razor.
Option 2
Make the Web Api my service layer and call it directly from the view using Javascript.
I am not a big fan of Option 2 since I feel like I am neglecting the controller which will be used only for redirection between pages. Besides I prefer using razor rather than Javascript.
And If I choose Option 1 will I have to make an instance of one Web API in the controller? because this feels like I am doing something wrong.
What's the best option ? Is there any other options I haven't considered ?
And if you can give some references or books which can help me, I would appreciate it.
Thanks.

I usually have another layer (which can be a different project/assembly depending on the size and complexity of your application) for my business rules. You can call this business services, or whatever works on your case.
So both MVC controllers and API controllers use this layer; which keeps the application dry.
I personally prefer to only keep complex operations in my business layers, which means if I need to read something from my persistence layer to display in my views, I do it directly on the MVC controller. This is a matter of personal preference but I prefer to go the CQRS way.
So you MVC controllers are going to instantiate these business services (or they will be injected into your controllers if you are using IoC). For read operations you can choose to go straight to your persistance layer or use another read strategy.
The same will happen to your API controllers, they will use this "common" layer of services.
You don't need to instantiate your API Controllers on your MVC Controllers.
Consuming your Web Api controllers via AJAX is ok if you are developing a SPA or similar.
There is no a single way to structure your application, there are just different ways and every one has more or less pain attached.
If you are considering introducing tests in your applications (and you should :)); then you should structure it in a way it is easy to test each part of it.
Just my 2 cents.

The whole point of Web API is to be a stateless RESTful service. There would never be an instance of it if you're doing it right. I realize this question is old and you may personally have learned this, but the answer isn't as much for you as it is an answer to a frequently-asked question.
Note that when speaking of Web API, more often than not, people are talking about ApiControllers and not basic MVC "Controllers" that take routes and turn them into Views.
So in your project, you may have some "Controllers" which do some basic view logic, but no business logic. Don't confuse that with your Service Layer which is a wrapper for your Business Logic and Persistence access.
I, and many, am of the opinion that ApiControllers shouldn't be mixed with your MVC application. Keep in mind that MVC does not mix well with Web API. As Filip W says:
Many of the concepts used by Web API and MVC, even though similar at
first glance, are actually not compatible. For example, Web API
attributes are System.Web.Http.Filters.Filter and MVC attributes are
System.Web.Mvc.Filter - and they are not interchangeable.
Most flexible answer
So what you do is create a subdomain named api.YourWebsite.com, and build a new Web API ApiController project there. That Web API Project should do NOTHING more than instantiate and expose Business Logic via ApiControllers and Dependency Injection.
Alternative 1
Service-Oriented Architecture is all about reusability. If you want to keep your applications DRY, you should definitely fall into SOA. Though, every situation is different. If you will never ever use the same business logic in this website in any other application (desktop, android, tablet, ewPhones, etc), then you have an alternative method.
Create your Busines Logic Layer as a different Project, and access it directly from your web app. When your Javascript (Angular/Razor?) Controllers make a call, they can call into your ViewModels and/or Codebehind or something similar, which can instantiate Business Logic and directly access it. No need for services if everything is right there and won't be reused.
Alternative 2
Go ahead and put your Web API ApiControllers in the same project. But, be sure you separate them into different folders from your MVC "Controllers." Still, when your Javascript Controllers make a call, they will be making Routing calls to your website for stateless returns. Do not mix the stateless ApiControllers with your ViewModels and other MVC code.
The downside to this is a lack of SOC. Now you have Service-Layer and UI-Layer mixed, and your UI-Layer is forced to access your Business Logic Layer (DLL). What's wrong with that if Alternative 1 did it?
Well, what's wrong is that Alternative 1 was a small application with no room for growth. Anything else (The original plan, or Alternative 2 here) should have UI's that have no clue whatsoever that Business Logic (or Persistence) even exist. They should go about their doodies unawares of the backend world.

Related

What is a good architecture to add an API to an existing ASP.Net Core 2.2 MVC solution

When I started development of my current project I had no knowledge or prior experience of web development, ASP.Net (Core), C#, JS and so on.
With a lot of reading, excercising and testing I now have an ASP.Net Core 2.2 web application with multi-tenancy based on the database-per-tenant strategy hosted on Azure with Azure SQL as backend.
I have a solution with 2 projects:
the MVC web application that also has the .Net Core Identity from which I use the individual user accounts stored in ASPNet... tables (I did implement my custom UI, mainly so I could use the Localization middleware already used throughout the application)
a data layer that contains the db context's, the data models and the repository
Now I need at add an API.
The sole purpose of the API is cleary defined: give customers(tenants) the possibility to import and export data, most likely connected to other customer's application(s). This API will not be used by the UI. The API will not be hit with thousands of queries per second. It will be part of a business solution with 50 to 200 customers who will perform occassional import/export actions.
I have already implemented Identity and the authentication for the API should be done against the users setup in Identity but with a different authentication mechanism.
I have done a fair bit of searching and reading and found many tutorials/blogs on how to create a WebAPI with .Net Core but they all start from a new project and never go much more into depth. The once that really go in-depth are too complex for me ...
I have 3 questions unanswered at the moment although I know that there's probably more than 1 good answer to each of the questions but I think these are the likes of questions that many in my position, beyond the newbie/beginner but not yet a seasoned veteran, have and are searching for so I hope this post helps not just me but many others as well.
Question 1 - Architecture, where to create the API (project)?
There are 3 possibilities:
1 Add APIControllers to the MVC application (organize API-related classes in separate folders)
Benefits
quick and easy, everything else is already in place
deploys with the solution
Concerns
as it is part of the solution it becomes very monolithic, less flexible
Questions
can I implement a second authentication/authorization mechanism next to the implemented individual user accounts? (more detailed in the second question which is all about security)
2 Add a WebAPI project to the solution
Benefits
better separation but can still use/reference the resources of the other projects
probably gives benefits for scaling and tuning?
Questions
can I implement a second authentication/authorization mechanism next to the implemented individual user accounts leveraging the Identity of the MVC project? (more detailed in the second question which is all about security)
is this project separately published to Azure (or any cloud provider for that matter) using the www.example.com/api path (virtual directory) or is the solution published a whole?
3 Create a separate solution with the WebAPI project and include the data layer project
Benefits
full separation although sharing the use of the data layer project
completely independent with regards to deployment, scalability etc.
Concerns
maybe adds a layer of unnecessary complexity (the API will not handle thousands of requests per second)
Everything that is already configured/setup in the MVC project and that is required will need to be redone
Questions
can I include the data layer project in the solution (it is then part of 2 solutions) or should I reference it as a dll?
Question 2 - how to implement Authentication/Authorization that resides side-by-side with the Identity individual user account?
This is related only to the first 2 options of the architecture as in the third option the project would be on it's own.
The basic question is how to setup more than one authentication mechanism, one for UI users and another for API access.
First there is the choice of Authentication, most of tutorials blogs talk about JWT and Auth (OAuth?). I am not asking what the "best" solution is but which solution would be "preferred" by B2B customers who are the only ones that will use the API.
I am not sure how to redirect to the right authentication: when a request is sent to an API controller method with the Authorize attribute and the user hasn't been authenticated yet it needs to reply with an error.
Currently if a method with the Authorize attribute is executed by an unauthenticated user the user is redirected to the login page as configured in startup.cs:
public void ConfigureServices(IServiceCollection services)
{
...
services.PostConfigure<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme,
opt => {
opt.LoginPath = "/User/Login";
...
Do I need to configure this with something like the example I found below:
app.UseWhen(x => (x.Request.Path.StartsWithSegment("/api", StringComparison.OrdinalIgnoreCase)),
builder =>
{
builder.UseMiddleware<AuthenticationMiddleware>();
});
or is this configured in a different way?
In the case of creating the API as a separate project should I use the "Multiple startup projects" option? I guess this means that I need to create the whole startup.cs again?
Question 3 - if I want to offer my customers a REST API and an OData API, can I handle this through a single API or do I need to develop a second to support OData?
I know it is lengthy but I'm sure that others are looking for similar information and I'd appreciate any input.
Thanks

What pitfalls or consequences could there be when structuring a solution in 3 projects (.net core, vue.js and webapi)?

I want to make a quick, safe and nice application.
For many years I have been programming in PHP and regular ASP. But wanted to go on with .NET and vue.js.
So I have an idea, I wanted to create and plan to do it like this:
I was thinking of using hosting from an external service.
Then I would have three projects:
domain.com/index - Vue.js which will be a SPA, where the user can filter through a catalog, press like and send few api requests (mainly get-requests).
secure.domain.com - Here I will have a .net mvc project where I can use identity. This will make it simple to handle/register users. I will also give the correct session here for authenticated users. And it will affect domain.com/index, where they only are allowed to do some of the things if they are logged in
api.domain.com - This will be the webapi api. Only authenticated users will be allowed to send some of the requests.
I have used several weeks at looking into how to structure this.
But as I do not have much experience with this.
What pitfalls and bad consequences do you see in structuring it like this?
Are there any heads up you want to give me? Or any other recommendations?
I have been trying to melt all of this together in one project, but that has been difficult, because they operate in different ways. So now I have ended up with this, and look forward to
Size of project
It will be a relative small project.
People should be able to register/authenticate themselves (through facebook/google/server login).
Authenticated People should be able to add records(links) to a database. When adding this to the database they may also want to upload files, and choose some additional information.
All people should be able to filter through the catalog of records (5000+) ( Here I am using vue.js/vuex/axios). Here they should be able to comment too on links too.
Webapi will have 8 entities/tables and one view which will GET all the information. 3 tables should be able to have POST.
So it is more or less a catalog, where people should be able to add records and find new ones.
I was planning to use the identity from asp.net core 3.1. It is a "template" where I can easily add 3rd party logins. (https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-3.1&tabs=visual-studio)
Additional questions:
Can you tell me how request from SPA will be authenticated in your API? (Jwt or cookie)? Why would you like to have a separate identity service, also Why you would like to use asp.net identity (is it because of ease of setup)?
I have not been thinking about authenticating API requests. Was thinking to only have authenticated users who can send POST-requests. And the rest will be get requests. Limited only from the server. Should I have some additional authentication? Does JWT make web APIs safe enough for my use?
Was thinking of using .net identity because it is simple. And I don't want to use time on setting it up.
Since this is your first project of this type, I would recommend to keep it simple.
Just create one web site. Otherwise you might get issues with the cookies not working for subdomains and you will also get issues with CORS. That is, you will get all problems at the same to time (configuration issues, infrastructure issues and the pain from writing the application itself).
You can still have a clean separation by using sub folders (or Areas in MVC) and by using class libraries for the backend (API) business logic.
Once you have mastered the basics (i.e. writing the actual application) you can start looking at other means of separation etc.

Should we call Web API from MVC application in same solution?

I am working on a project in MVC that has mobile application so one thing is clear that we have to use Web API so it can used in mobile application.
After creating API when we started to develop Web site we are confused and had discussion on whether to use API or directly access to the Business object. And we ended up after having opinion form more experienced developer to consume Web API instead of using Business object directly.
I'm having confusion regarding to this solution structure.
1) Why we should use Web API and make HTTP request (which is time consuming) to get or put data instead of business object directly which is in same solution.
2) After having arguments they said what if client wants to host API and web on different cloud server and apply scaling only on API or may be he want to have different url for accessing API and Web (which is some what logical). So in that case should we call Web API from MVC application in same solution?
3) If we're hosting API and Web on different hosting so it means our Web will use WebClient and have HTTP call on each navigation. Is it right?
4) If we'll business object form both API and Web hosting on different server then if something change in BL will need to update build on both server.
5) Or we should create only one project for API and can add views or html pages to develop Web interface so in that way we can directly call API from ajax.
As per my knowledge #5 is the best solution or API is only for 3rd party access. If we have DB, EF, data layer and business layer in same solution then we should not use API to make HTTP calls and directly access business object. (correct me if I'm wrong)API is needed when mobile application or desktop or any one want to access application so we can have same repository and data layer.
In my scenario I've to create API as we also have mobile application, and in project API side we called business layer (separate project) and business layer communicate to data access layer (separate project). So my question is if we host our API and web to different servers then calling API which is a HTTP request may take longer rather than using method from business layer as we create the project and we've .dll of business layer. In API controller we just convert out put of our business to json format.
I've searched on internet but didn't get convincing answer. I've found a blog http://odetocode.com/blogs/scott/archive/2013/07/01/on-the-coexistence-of-asp-net-mvc-and-webapi.aspx discussing same point but again in that blog my question is why we need to consider scenario #3?
I think you have answered your own question in writing, but really this boils down entirely to what your requirements are, and perhaps more importantly, what the strategy for your application is.
First of all, using Web Api over accessing Business Objects directly (by which I think you mean through viewmodels etc) only makes sense if you are controlling access of data client side.
If you only have a requirement for consuming data from client side within a particular application, then hosting Web API within the same project makes sense. Sometimes, for instance when building a SPA or rich-client web app, then using Web Api within the same projhect is sufficient, as they are only intended to be consumed by that application.
Where you see a requirement for different versions of the same application (mobile, tablet, web etc), then moving the Web Api to a separate project makes sense, as each application can then access the same API. This Web Api would contain your data access and business logic layers within it. This allows complete separation of your projects then, and provides maximum reusability, and ensures consistency in data between different versions of your project. Obviously with this set up, your Web Api layer is seperate and can be tested/deployed/scaled separately.
So in summary, you need to consider your requirements and assess the technologies available to you to achieve them. Using the above I hope you understand where Web Api fits in and what it can provide.

SimpleMembership - anyone made it n-tier friendly?

"SimpleMembership", we're told, is the future of asp.net membership / role management.
The MVC4 "Internet Application" template implements Account management using SimpleMembership. However, the way it is implemented merges all the application tiers into 1.
It kind of shocked me that after all the work they've put into layering apps properly with MVC, we get this shoddy implementation of "the way forward" for Membership with no DI, use of WebMatrix DLLs and complete lack of SoC. Particularly the ActionFilterAttribute for SimpleMembershipInitialization - it inherits from an MVC attribute and makes calls to the EF DBContext directly.
I realise I'm being lazy, but has anyone done a "proper" template using SimpleMembership that means I can have proper separated tiers in my app, and not have EF DBContext references in my MVC app?
One of powerful concepts of SimpleMembership is that you can customize the user profile to fit your application needs, as discussed in this article. For example, you may want to add email confirmation to your registration process which will require storing the user's email address in the user profile. In the previous membership/role management for ASP.NET this was very ugly to implement and added properties were stored in a blob. Yuck!
So what does this have to do with your question on making SimpleMembership n-tier friendly? While I agree that what the template generates is not n-tier friendly I would also state that most real MVC applications of any complexity will require customizing SimpleMembership, and therefore will require making a tier or layer that is specific to the application requirements anyway. Stated another way, creating a reusable tier for SimpleMembership would only be useful in the most basic MVC apps.
Personally I have come to the conclusion that what is generated by the Internet template in regards to SimpleMembership will almost always be modified. As the first article I referenced points out the first part of customization is getting rid of the SimplemembershipInitialization attribute, which is just a lazy way of initializing SimpleMembership in the event the developer is not using forms authentication. And often you will want to move the DBContext used by SimpleMembership into the DBContext for the rest of your application. User profiles are often tightly integrated with the rest of the application domain.
And since we are on the subject of SoC and ASP.NET security, I would argue that ASP.NET was never very good at this. For forms authentication you use an Authorize attribute on your controllers and/or actions which takes a role as a parameter. This forces the application developer to think about security design while designing the application domain. You have to determine what roles the application will have up front, and heaven forbid they change later because now you have to go through all of those attributes and update them accordingly. I have started to use a custom authorize attribute that takes as parameters a resource name and an operation type (ex: read, write, execute...). Then I can map roles to resource/operations in a database so that it can change easily, or even allow an administrator to make changes to how roles are implemented in the application. Microsoft is taking the same approach with ClaimsPrincipalPermissionAttribute now that they have incorporated WIF into .NET 4.5.
Updated 3/8/2013
I have created an open source project on CodePlex called SimpleSecurity that decouples SimpleMembership from the MVC application. You can read about it here. I still think developers will most likely want to modify SimpleSecurity but since this is open source they can. We will see if this is something we can evolve to be a reusable and better SimpleMembership.
Accepted answer is not correct, that is not N-Tier. The membership data access and business logic are occurring in the same layer. Just because code is in a different assembly doesn't mean it isn't in the same layer.
Without some kind of transport mechanism to the data access layer, this is not N-Tier.
The solution is to inherit and override the WebMatrix SimpleMembershipProvider class such that its data access calls can be performed on a separate host.
I recommend using dotPeek to look at SimpleMembershipProvider so you know what to do in your overrides.
I think your question relates more to SoC than n-tier architecture (which is more about physical separation between layers as pointed out by #klatzib).
I would argue that the logic within the membership providers should not be classed as business logic as they do not contain application or client specific code. In fact the idea of the provider model is that it fulfils a generic contract irrespective of the context in which it's used. A common mistake developers make is extending MembershipProvider and bolting in application specific business logic that should exist in a higher layer. If that's what you want to achieve with a alternative design, then that's the wrong approach. Providers are plugins for the .NET framework, and should be entirely abstracted from code. They certainly shouldn't contain your application domain, and you should very rarely need to extend them.
Addressing your question another way, does the SimpleMembershipProvider prohibit SoC in application design or even n-tier architecture? No it doesn't. The MVC4 template is built for simplicity, but the ActionFilter used to initialize the provider is not part of the membership implementation, and you are free to initialize the the provider in any way you see fit (I prefer making this call from a DI container factory method). In fact SimpleMembershipProvider as no direct dependency on EF at all, so yes it is possible to remove references to EF DbContext in your web app.
Exactly what I was looking for (almost). Just wish it wasn't tied into entity frameworks as I was hoping to get Kevin's n-tier solution working with Dapper ORM :(

Prevent Application changes breaking API

I have an application which I am currently writing an API. This is the first time I have created an API from start to finish and have read lots of good articles and how to do this. However a lot of that material focuses on the API development specifically (as it should) but have not found anything that touches on how to ensure the API doesn’t get broken by changes which happen within the application project.
My application consists of a ASP.NET MVC web app which makes calls to a Service Layer to undertake CRUD like operations. So to get a list of all the users in my app the MVC app calls the service layer and asks for them and is presented with a collection of users. My API (WCF Web API) also uses this service layer internally and when I request a list of users, again I get back a collection of users (JSON, XML etc).
However if for some reason another developer changes the underlying User domain object by renaming a field say surname to last name then this potentially is going to break my API as the Service Layer is going to return to my API a user object with a new field name when its expecting something else. My API does in fact have its own representation of objects which get mapped to the application objects when requested but this mapping will not map the surname property and will be returned as null.
Therefore do all changes in the app have to be strictly controlled because I provide an API? If so then do you have to change your app and API in tandem? What if changes are missed? The aforementioned doesn’t seem correct to me hence my post to seek greater knowledge.
Again I’m quite new to this so any help on this would be much appreciated.
It is inevitable that your application will evolve, if you can create new versions of an API as you applications evolve and support the older versions, then give notice of when older APIs will become obselete.
If you are owning the API design and you don't really want anyone to pollute your design. Introduce dedicate DTOs for your API use. Which be mapped from the underpinning domain models. But your presentation (via xml or json) won't change even underlying models change frequently.