webapi aspnet 4 Architecture - asp.net-mvc-4

I've project using Entity Framework 5 Code First, WebApi, ASPNET MVC 4, Repository and Unit of Work pattern, etc.
My architecture is as follows:
One project for the POCOS
One project with the context, Repository, Unit Of Work, etc
One project with the contracts (IRepository, IUnitOfWork, etc)
One WebApi project which holds ApiControllers for each entity of the model (GET, POST, PUT, DELETE).
Now, if I don't want to use SPA (as I don't have time right now to learn it) and I want to do something quick, What should I do? a new ASPNET MVC 4 project with Controllers inheriting from Controller rather than ApiController, and those controllers consuming the WebApi controllers?
Like this?
public ActionResult Index()
{
return View(WebApiProj.Uow.Houses.GetAll());
}
That doesn't seems to be quite good as it should be creating a Get pointing to the WebApi controller in the other project.
I'm thinking about this architecture, because mobile clients, web clients and any other clients would be calling the same services which sounds good.
Any advices on this architecture? Pros or cons?

I am not sure if what you show is possible? WebApiProj.Uow.Houses.GetAll() Is treating Houses as if it was a class with a static GetAll function on it. Houses is an instance class that needs to be instantiated per request and may/should have constructor injection concerns to handle too... GetAll would normally be an instance method.
Given you are in a situation where you are going to have multiple code clients i.e. the WebApi controllers and the MVC controllers you should consider adding a Service Layer to your project. http://martinfowler.com/eaaCatalog/serviceLayer.html.
Your Service Layer will probably take the form of a single class (if this is a small ish project but split it up if needed), it will have the Repositories and the Infrastructure code injected. You should end up with a series of CRUD and UseCase sounding method names that contain the orchestration logic between repositories, factories and unit of work classes.
public interface IMyServiceLayerClass
{
IEnumerable<House> GetAllHouses();
House SaveHouse(House house);
IEnumerable<Windows> GetAllHouseWindows(int houseId);
//etc
}
public class MyServiceLayerClass : IMyServiceLayerClass
{
private readonly IRepository<House> _houseRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly IRepositoryTypeB _repositoryTypeB;
Public MyServiceLayerClass(IUnitOfWork unitofwork, IRepository<House> houseRepository, IRepositoryTypeB repositoryTypeB)
{
//Populate the private readonly's
}
public IEnumerable<House> GetAllHouses()
{
return _houseRepository.GetAll();
}
Your two types of controller can then accept the Service class and have very thin logic just to forward on to the service layer.
public class HomeController : Controller
{
private readonly IMyServiceLayerClass _myServiceLayerClass;
public HomeController(IMyServiceLayerClass myServiceLayerClass)
{
_myServiceLayerClass= myServiceLayerClass;
}
public ViewResult Index()
{
return View(_myServiceLayerClass.GetAllHouses());
}
Same for the Api:
public class HouseController : ApiController
{
private readonly IMyServiceLayerClass _myServiceLayerClass;
public HouseController (IMyServiceLayerClass myServiceLayerClass)
{
_myServiceLayerClass= myServiceLayerClass;
}
public IEnumerable<House> Get()
{
return _myServiceLayerClass.GetAllHouses();
}
This will allow you to reuse the same business logic and orchestration across the controllers abstract the logic away from your WebApi and Mvc applications.
This code could easily live in your project that defines the contracts as it is only dependent upon interfaces. Or you could add its interface into contracts too and then create another project class Domain or Service which can hold the implementation of the service class.
I would strongly suggest you leave you Controllers to do what they do best and let them handle the delegation of the UI specific elements and re-factor non UI specific logic into a reusable service layer. This would allow Unit tests for controllers to focus on testing for the correct action result and status codes etc and allow your domain logic to be tested independently.

Take a look at my answer for another architecture question on MVC. The key for your question is to have an application or domain layer that both the MVC Controller and Web API Controllers can use to access the business model (The M in MVC). You do not want to call the Web API directly from the MVC Controller as it has overhead for serialization and de-serialization that is not required here. Instead call the application/domain layer directly.

Related

ASP.NET Core Web API split controller based on aggregates

In my API project I have currently 1 controller with the following syntax:
Abstract base controller
[Produces("application/json")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status406NotAcceptable)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public abstract class BaseApiController : ControllerBase
{
// ....
}
TestApiController
public class TestApiController : BaseApiController
{
// Parent action methods
[HttpGet]
[HttpPost]
...
// Child action methods
[HttpGet("{test:guid}/child")]
[HttpGet("{test:guid}/child/{id:guid}")]
...
}
This gives us the following urls:
http://localhost/api/v1.0/test
http://localhost/api/v1.0/test/1
http://localhost/api/v1.0/test/1/child
http://localhost/api/v1.0/test/1/child/1
Question
How can I split the controller into multiple files without braking the urls but to have a cleaner overview.
So a controller for all the test actions and another controller for all the child actions.
I'm not talking from an abundance of experience with controllers here (I have done some), but I think you'll find that the controller is the controller - in that there's no easy way to have a controller-route that isn't 1:1.
But, if you want to make controllers more manageable you could just keep them as lean as possible and put the bulk of code into classes that the controller calls.
Alternatively, rather than trying to split/decompose the controller and not the route, rework the overall API design/structure so that you have more controllers and routes. The Interface Segregation Principle comes to mind here (yes it's born out of OO but the principle is still applicable).
At the end of the day, you have calls coming into to API's defined by their routes, and off to the controllers - it doesn't really matter how that all looks (is structured) as long as the API is sufficiently sensible, intuitive and fit for purpose.
After some more searching on the internet I came across the following interesting Nuget package:
Nuget: Ardalis.ApiEndpoints.
Source code and examples about this can be found here:
Github: Ardalis.ApiEndpoints.
This allows us to separate controller into folders and for each action a separated class to give use exactly what we want.

preload and cache data in a Web API OWIN application

I'm building a Web API application using OWIN and hosting in IIS. I now want to preload some data from a database which can be used in the controller methods without loading the data from the database for each request. I have also followed this guide to setup Windsor as IoC container. Does anyone know how to properly set this up?
It's easy to do. In the Startup class, populate one or more classes with the database data. Do this as you would normally load data into a data store.
Register each of these classes with your IoC from the Startup class. It is best to separate the controller from data layer, so create a business logic layer or a repository layer that takes your data store class in the constructor like this:
public class Service
{
private readonly IDataStore _dataStore;
public Service(IDataStore dataStore)
{
_dataStore = dataStore;
}
}
Register the service with your IoC and you should be good to go.
Hope that helps.

IAuthenticationFilter equivalent in MVC6

I'm moving a Web Api 2 project to MVC 6, since Microsoft is merging the two APIs in ASP.NET 5. In my WebApi project I had a custom Attribute Filter class that would authenticate, authorize and prevent transaction replays using a combination of public key, private key and HMAC authentication (basically, doing this with some tweaks to fit into my project).
Now in MVC6, as far as I understand I must stop using anything in the Microsoft.Web.Http namespace and instead use Microsoft.AspNet.Mvc. So I have done that, but the Microsoft.AspNet.Mvc.Filters doesn't seem to have any equivalent of Web Api 2's IAuthenticationFilter.
This is a problem for me because my customer AuthenticationFilter implemented all of IAuthenticationFilter, with all the logic in there. More importantly, it was using the Context to temporarily store the public key of the account, so my controller could access it to load up the account in turn.
So my question is, what is the proper way to filter requests in MVC6, using an Authentication Filter-like class to intercept the requests and return the appropriate status codes? I can't find any article that goes specifically in these details (they all tend to cover MVC5).
I know it's an older question, but hopefully someone (maybe even yourself) might find value in the answer.
MVC6 does in fact have an alternative. You have an
public abstract class AuthorizationFilterAttribute :
Attribute, IAsyncAuthorizationFilter, IAuthorizationFilter, IOrderedFilter
which basically tells you, that you can create your custom class, derive it from this (namespace of all of these interfaces, btw, is Microsoft.AspNet.Mvc.Filters and that should be it. You can either decorate the action with it, or you can do this in Startup.cs, to apply to all actions:
public void ConfigureServices(IServiceCollection services)
{
// Add MVC services to the services container.
services.AddMvc(options =>
{
// add an instance of the filter, like we used to do it
options.Filters.Add(new MySpecialFilter());
});
services.AddTransient<LogFilter>();
}
If you want to use a bit more logic in the filter (e.g. my LogFilter above) which is instantiated through DI, you need to use either Service Filters or Type Filters.
You can now decorate the actions with [ServiceFilter(typeof(LogFilter))] or use o.Filters.Add(new ServiceFilterAttribute(typeof(LogFilter))); in the Startup.cs file. But keep in mind, to do this you need to register the type with the DI container, like I did above with the .AddTransient<>() call.
IAuthenticationFilter is no more and IAuthorizationFilter simply does not replace it in MVC 6
Reason: authentication is NOT EQUAL to authorization.
Therefore IMO the authentication filter should stay available!

Windows authentication and Asp.Net Web API

I have an Intranet application with Windows authentication based on MVC4.
When I need the WindowsIdentity for authorization purpose in a Controller I just use
HttpContext.User.Identity
Now I wanted to use the new Asp.Net WebAPI for some Ajax calls.
Is there a way to get the WindowsIdenty object in the same easy way as in an MVC Controller?
Please don't reference the HttpContext from a controller.
You can access the Controllers User property which is way of accessing the Identity through without a dirrect reference to HttpContext.
public class MyController : ApiController
{
public string Get()
{
var indenty = this.User.Identity;
}
}
Why
The controllers User property provides a level of abstraction which allows for easier mocking and thus unit testing. This abstraction also allows for greater portability e.g. if this was WebApi Self Host you wouldn't even have access to HttpContext.
To read more about how to unit test and mock the User property read here. For more information re: portability read here.

asp.net mvc without entity framework

I am learning asp.net mvc and went through a great tutorial that demonstrated it. The tutorial also used Entity Framework.
We have our own data access class which I have to use.
I am a little bit confused as to what I need to do to bridge the gap between our class and MVC framework.
For example, in the tutorial, inside of MovieController.cs file, there is a Edit method, that looks like this:
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
If I don't use the Entity framework, what would it look like? Will I still need to use ModelState.IsValid and save the state like it's done
db.Entry(movie).State = EntityState.Modified;
Please advise. A clearly written example of using asp.net mvc without the use of Entity framework would be great.
What I need to know is what role does state play here and whether it is mandatory to use or is it just a part of how the Entity framework operates.
I would re-write this as:
[HttpPost]
public ActionResult Edit(Movie movie)
{
myDBObject.SaveChanges();
return RedirectToAction("Index");
}
Where myDBObject is my custom database access object.
The examples you see out there where controllers use directly some data access framework such as Entity Framework are bad examples. The whole internet is polluted with such stuff. I can hardly look at it without having my eyes hurt. I consider those as bad practices. Data access should be separated and abstracted in a repository. So for example:
public interface IMoviesRepository
{
Movie Get(int id);
void Save(Movie movie);
}
then you could have some implementation of this interface using plain ADO.NET, EF, NHibernate, a remote web service call, some custom ORM or really whatever:
public class MyCustomFrameworkMoviesRepository: IMoviesRepository
{
...
}
and the controller will take this repository interface as constructor argument:
public class MoviesController: Controller
{
private readonly IMoviesRepository _repository;
public MoviesController(IMoviesRepository repository)
{
_repository = repository;
}
public ActionResult Index(int id)
{
var movie = _repository.Get(id);
return View(movie);
}
[HttpPost]
public ActionResult Index(Movie movie)
{
if (!ModelState.IsValid)
{
return View(movie);
}
_repository.Save(movie);
return RedirectToAction("Success");
}
}
and the last part is to configure your dependency injection framework to pass the correct implementation of the repository into the controller. Now as you can see the way the data is fetched is completely decoupled from the controller logic. It is the way it should be. Always try to avoid the strong coupling between the different layers of your application.
And to answer your question about the State property : this is something completely specific to EF, seeing something like this in a controller is a really pity.
And to bring this even further and improve it you would introduce view models. View models are classes which are specifically designed to meet the requirements of a given view. So for example Movie is a domain model. Domain models should never be directly passed to views. Controller actions should never take domain models as action arguments. You should define view models which will contain only what is required by the given view and then perform the mapping between the view models and the domain models. Frameworks such as AutoMapper make this very simple.
hmm.
MVC and entity framework really have nothing to do with each other; they just work well together.
the if (ModelState.IsValid) validates your view model. If you are not using view objects with validators, it's a little pointless; if you are, then it's quite valuable.
inside the if (ModelState.IsValid) brackets, you would take the post data from your web page (usually a view model) and apply it to the object that will persist it to the database. EF is often used because once it's set up, it's fairly easy to maintain, and a lot less code to write.
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
are both EF-related. These would need to be replaced by your repository class methods and objects.
return RedirectToAction("Index");
is MVC. Upon successful persistence to your data store, return the control to the index page.
return View(movie);
is used to redirect back to the original view, because something failed validation.
You would still check ModelState.IsValid, but otherwise your code would look like what you have.
This assumes that your model has DataAnnotations attributes on it, though, which is what ModelState.IsValid is using to check. Those attributes can be used on any C# class' properties - not just Entity Framework.
You might end up creating specific view models for this purpose.
You need to make some connection between the Movie object (passed in on the http POST) and your database methods (myDBObject).
Maybe you want to say myDBObject.SaveChanges(movie) and assuming your db code knows how to handle the object Movie then you'll be fine.