How to expose only a few inherited CRUD API controller methods? - c#

To speed up development in a small team (and also to enforce consistent REST-ish API), I have created a generic base API controller and also a related generic business service base class that has typical CRUD methods for domain root entities:
create
get by key
update
delete
get a page of records (with a simple query expression and pagination that gets automatically parsed into a Linq expression
get a simple list with all records (id-name pair projections for many cases when that's all you need, e.g. for a dropdown list).
It worked pretty well for most cases. We also had similar architecture on Angular side with some code generation scripts and we could spit out hundreds of forms for a small ERP-like system in a short time.
However, we had quite a few entities that did not need all those CRUD methods. Our Swagger definitions were polluted with methods that should not actually be available and we had to override them and add ignore attributes and throw NotImplementedException as needed.
Is there any clean solution to this CRUD inheritance mess? Is it possible to somehow specify to ASP.NET "hey, for this controller I want to generate routes only for these specific CRUD base methods and ignore all the other ones"? Of course, I would still want to be able to add non-CRUD custom routes and methods to controllers, as usual; so I don't need fully dynamic runtime-generated controllers but only their methods.
In an ideal world, .net should have traits like PHP, so that I could add e.g. "GetByIdTrait" etc...

Related

How to use one ViewModel for all CRUD operations in WebApi

I am making a little API in asp.net. It is coupled with an MVC webapp. I intend for the webapp to use it's own API instead of creating 2 backends that do the same thing.
I am struggling a little to try and keep my duplicate code to a minimum when it comes to creating a model to use in the API for both "incoming" (Post, Put) and "outgoing" (get) actions.
I have a class called Event, it contains properties that are easy to serialize to JSON plus a few complex types. I created a model called EventViewModel (is it appropriate to still call it a view model in API?) with some extra properties to get the Names out of the complex types.
Ideally, I'd like to re-use this Model for everything, but when it comes to defining[Required] tags, my logic breaks down...
I first thought of using [Bind(Include() Exclude()] on each of the API actions. Does this sound like a viable solution?
What other solutions have people used?
Thanks!
Here are some thoughts.
I would use separate controllers for view (Controller) and api (ApiController) since we are talking about two different presentations of data. I would not use the controller as an api, since both return different types. An api controller uses statuscodes in a different way. E.g. ApiController.Delete returns statuscode 204 No Content, while Controller returns statuscode 200 Ok with a view.
You can call the models for Controller ViewModels and for ApiController DTO's. In either case, they are just simple objects. Don't put any logic in those objects except for validation (which you can test with the ModelState) and don't use entity objects.
Do not use models / dto's for multiple purposes for the reason you've already encountered. Just use simple objects and use those only once, keep it simple. In that case, if you want to change something you know it is not going to break your application.
You can save code by using base classes that you can inherit. This will also give you the advantage of writing extensions once for different objects.
But if you insist in reusing objects, you can decide not to use ModelState.Validate in Api's. I think in that case the [required] tag is ignored, but I am not sure. As for the objects, I would not use JsonIgnore / Xmlignore but set default values instead. In that case these properties are omitted on serialization. Makes it easy to use objects for both POST and GET.
[DefaultValue(0)]
public int Id { get; set; } = 0;
Use repositories. You can call the repositories in both the controller as in the api controller. This is where you can really save code.
For Api's (not CRUD) I prefer to write specialized linq queries that return anonymous objects and select those into the dto. This gives multiple advantages. Sometimes I use extensions (on IQueryable) to save code.
You may want to consider using something like automapper to save code, but I wouldn't recommend this.

Right way to work with dbContext

Summary
This question is for a methodology. The answer should be a link to the holy grail in working with contexts for the described scenario.
We have been experiencing different problems in our MVC web application project, related to the use of dbContext.
After reading many question-answer blogs, articles ... including proposals with repositories and injection patterns, Owin, Entity Framework, Ninject, we are still not clear about the right way to work with dbContext’s.
Is there any article, demo, with “The Way” to do it in a more complex application than just “CRUD” operations using separation between MVVC-presentation / Domain Entities / Logic / DataAccess layers, including Identity security handling users and roles permissions?
Description
Previously, our approach was to create dbContext objects when needed in each repository.
Soon we discovered errors like “dbContext is disposed” since the connection dies together with the repository function. This makes the retrieved objects “partially available” to the upper layers in the app (using the trick .ToList(), limited because we can access collections and attributes but not later navigation into the object child tables, and so on). Also using 2 contexts from different repositories, we got an exception telling that 2 contexts are trying to register changes to the same object.
Due to timed commitments to deliver prototypes, we created a single static dbContext shared for the whole application, which is called from everywhere when needed (Controllers, Models, Logic, DataAccess, database initializers). We are aware that is a very dirty workaround but it has been working better than the previous approach.
Still with problems: dbContext can handle only 1 async method call at a time, and we can have many calls (eg. userManager.FindByNameAsync - there are only async methods). Exception: “A second operation started on this context before a previous asynchronous operation completed”.
We were thinking about creating the context as the very first step when an action is called in the controller, then to carry this object as “relay race” to every other layer or function called. In this way the connection will live from the “click in the browser” until the response is loaded back on it. But we don’t like the idea that every single function must have an extra parameter “context” just to share the connection through the layers for the entire operation route.
We are sure that we are not the first ones wondering about what is the right way to use contexts.
Application layers
We have these (logical) layers, differents workspaces, but same webapp MVC project, top to down:
Views: HTML + Razor + JQuery + CSS. Code here is restricted to the layout, but some HTML might depend on the Role. Method calls are to controllers only, plus utils (like formatting).
ViewModels: The data container to be exchanged between Controllers and Views. Classes only define attributes, plus functions to convert to and from Domain entities only (Translators).
Controllers: Actions called from the browser result in calls to functions in the Logic layers. Authentication here restricts access to actions or limits inside an action. Controllers avoid using Domain entities but ViewModels, so that to communicate with Logic layer ViewModels translation functions are called.
Domain Entities: Used for the logic layer, and used to create database tables by Entity Framework.
Logic Classes: A Domain entity has an EntityLogic class with all the operations. These are the core where all the rules that are common and abstracted from specific consumer clients (ViewModels are unknown).
Repositories: To access the database. Not sure if we do need this since Domain entities are already mapped to objects in database by Entity Framework.
Typical scenario
The browser calls an action (POST) in the Products controller to edit a product. The ProductViewModel is used as container of the data.
The controller action is restricted to a collection of roles. Inside the action, depending of the role, a different Logic function is called and ProductViewModel is translated to ProductDomainEntity and passed as parameter.
The logic EditProduct function calls others functions in different logic classes and also use localization and security to restrict or filter. The logic may or may not call a Repository to access the data, or to use a global context for all, and deliver the resulting domain entity collections to the Logic.
Based on the results, the logic may or may not try to navigate the results’ children collections. The results are given back to the controller action as domain entity (or collection of), and depending of this results, the controller may call more Logic, or redirect to another action or respond with a View translating the results to the right ViewModel.
Where, when and how to create the dbContext to support the whole operation in the best way?
UPDATE: All classes within the Logic layer are static. The methods are called from controllers simply like this:
UserLogic.GetCompanyUserRoles(user)
, or
user.GetCompanyRoles()
where GetCompanyRoles() is an extension method for User implemented in UserLogic. Thus, no instances for Logic classes means no constructors to receive a dbContext to use inside its methods.
I want a static method inside a static class to know where to get the instance of the dbContext active to the current HttpRequest.
Could NInject and OnePerRequestHttpModule help with this? Someone who tried?
I don't believe there is a "Holy Grail" or magic-bullet answer to this or any other problem with EF / DbContexts. Because of that, I also don't believe that there is one definitive answer to your question, and that any answers will be primarily opinion-based. However I have found personally that using a CQRS pattern rather than a repository pattern allows for more control and fewer problems when dealing with EF semantics and quirks. Here are a few links that you may (or may not) find helpful:
https://stackoverflow.com/a/21352268/304832
https://stackoverflow.com/a/21584605/304832
https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91
https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92
http://github.com/danludwig/tripod
Some more direct answers:
...This makes the retrieved objects “partially available” to the upper layers in the app (using the trick .ToList(), limited because we can access collections and attributes but not later navigation into the object child tables, and so on). Also using 2 contexts from different repositories, we got an exception telling that 2 contexts are trying to register changes to the same object.
The solutions to these problems are to 1) eager load all of the child and navigation properties that you will need when initially executing the query instead of lazy loading, and 2) only work with 1 DbContext instance per HTTP request (inversion of control containers can help with this).
Due to timed commitments to deliver prototypes, we created a single static dbContext shared for the whole application, which is called from everywhere when needed (Controllers, Models, Logic, DataAccess, database initializers). We are aware that is a very dirty workaround but it has been working better than the previous approach.
This is actually much worse than a "dirty workaround", as you will start to see very strange and hard to debug errors when you have a static DbContext instance. I am very surprised to hear that this is working better than your previous approach, but it only points out that there are more problems with your previous approach if this one works better.
We were thinking about creating the context as the very first step when an action is called in the controller, then to carry this object as “relay race” to every other layer or function called. In this way the connection will live from the “click in the browser” until the response is loaded back on it. But we don’t like the idea that every single function must have an extra parameter “context” just to share the connection through the layers for the entire operation route
This is what an Inversion of Control container can do for you, so that you don't have to keep passing around instances. If you register your DbContext instance one per HTTP request, you can use the container (and constructor injection) to get at that instance without having to pass it around in method arguments (or worse).
ViewModels: The data container to be exchanged between Controllers and Views. Classes only define attributes, plus functions to convert to and from Domain entities only (Translators).
Little piece of advice: Don't declare functions like this on your ViewModels. ViewModels should be dumb data containers, void of behavior, even translation behavior. Do the translation in your controllers, or in another layer (like a Query layer). ViewModels can have functions to expose derived data properties that are based on other data properties, but without behavior.
Logic Classes: A Domain entity has an EntityLogic class with all the operations. These are the core where all the rules that are common and abstracted from specific consumer clients (ViewModels are unknown).
This could be the fault in your current design. Boiling all of your business rule and logic into entity-specific classes can get messy, especially when dealing with repositories. What about business rules and logic that span entities or even aggregates? Which entity logic class would they belong to?
A CQRS approach pushes you out of this mode of thinking about rules and logic, and more into a paradigm of thinking about use cases. Each "browser click" is probably going to boil down to some use case that the user wants to invoke or consume. You can find out what the parameters of that use case are (for example, which child / navigation data to eager load) and then write 1 (one) query handler or command handler to wrap the entire use case. When you find common subroutines that are part of more than one query or command, you can factor those out into extension methods, internal methods, or even other command and query handlers.
If you are looking for a good place to start, I think that you will get the most bang for your buck by first learning how to properly use a good Inversion of Control container (like Ninject or SimpleInjector) to register your EF DbContext so that only 1 instance gets created for each HTTP request. This should help you avoid your disposal and multi-context exceptions at the very least.
I always use a BaseController that contains a dbContext and passes it to the logic functions (Extensions i call). That way you only use one context per call and if something fails it will do a rollback.
Example:
Controller1 that inherits BaseController
Controller1 now have access to the property db that is a context
Controller1 contains an action "Action1"
Action1 will call the function "LogicFunctionX(db, value1, Membership.CurrentUserId, true)"
In Action1 you can call other logic functions or even call them inside "LogicFunctionX". Always passing the property db through functions.
To save the context i do it inside the controller (mostly) after calling all the logic functions.
Note: the argument true that i pass in LogicFunctionX is to save the context inside or not. Like:
if(Save)
db.SaveChanges();
I had several problems before doing this.

Best practice for database methods in MVC 4

I am pretty new to MVC 4, and I have worked mostly with web forms up to this moment in C#. I understand the pattern of MVC, the routing, calling actions and so on.
But what about the actions which are responsible for fetching data from the database, for example by firing stored procedures? I have seen some tutorials where they put the logic for connecting to the database directly in the actions.
However I am thinking of a more centralized way to do it. For example, I can put all the functions which are firing stored procedures in a separate class named DatabaseCoordinator.cs in a folder named Helpers for example. Then I can call them from the actions in the controllers.
In that way I will know that I can find all of my methods for the database in one class, which is a very clean solution, I think (or at least in web forms). However I want to follow the pattern of MVC, and use only models, views and controllers as the name of the pattern itself implies.
So what is the best practice for that? Should I make a separate class for this, or implement the logic directly in the controllers, or perhaps somewhere else?
You should certainly make a separate repository class to contain all of your data access operations.
There is a good worked example here:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I recommend that you put your data access code somewhere other than in your controller. The controller's primary purpose is to gather together the information for display on a page or the reverse - to take the data from the page that is posted back and feed it to the code responsible for business rules and data access.
For most MVC projects (heck, for most projects really!) I build separate class library projects - at minimum one for business rules and data access, though typically I'll make those two separate projects. The purpose of separating the logic is really for simpler future maintenance and reusability. If you keep your various logical parts separate, you can easily swap them out if your logic or database needs to change, or you can easily consume the business rules and data from a new type of user interface; for example, if you decided to implement your project as a Windows forms application in addition to your web system, you could (theoretically) just reuse your business logic and data access logic libraries and only rebuild the user layer. However, if you build your logic into your controller, you really can't reuse that logic without extracting it and converting it to the new application model you're using.
So, simply put, definitely keep 99% of your logic and data access out of your controller. Only put what you must put into your controller, the rest in a separate class, or where appropriate, in separate class libraries.
Good luck!
The Controllers and Views tend to stay within the same project, but it's common to split the data access classes and models into their own seperate class library, as this allows other projects to utilise them.
This will allow you, in the future, to maybe add a windows forms/wpf interface or maybe a mobile device interface, leveraging the work you already have in the standalone class library.
Another thing to consider, is looking into how to use ViewModels in your MVC application. It's a common technique when Views require more than one domain object. Using View Models in MVC.
Check out the Unit of Work Pattern (UOW) combined with the Repository Pattern. It doesn't matter if you ultimately call a stored procedure or an inline linq query to return results, your caller shouldn't know or care how GetPersons is ultimately implemented. The UOW pattern combined with the Repository pattern is a very popular way to expose an Entity Framework database in the ASP.NET community. You will find different ways to do it, some are over-kill and some just create dependencies with no actual benefit but you will find a way that feels right to you with those patterns.
After more experience, I would like to change my answer and state that the Repository Pattern and thus the Unit of Work pattern are pointless layers of abstraction to prevent you from working with Entity Framework, which is your data layer abstraction! directly.
Other than being able to swap out databases from say Microsoft SQL PostgreSQL (when would this ever happen in the real world?) and control the structure of complex queries that you don't want repeated in your code, I see no real value to the repository pattern. To include CreatedBy,ModifiedBy values on Insert/Update you need only override EntityFramework. To encapsulate queries that include business rules such as where active = 1 and isdeleted = 0 just extend Linq queries with extension methods.

Audit Logging using ASP.NET MVC 4 ActionFilter

I'm building a web app using ASP.NET MVC 4, with data storage provided by T-SQL database via Entity Framework. I'm integrating audit logging as I go, and I'd like to provide a nice human-readable summary of the action, so that I can present a friendly logs view with clear statements like "User Bob logged in", "User Alice updated article 'Foo'", etc.
An audit record currently consists of:
GUID
timestamp
user ID
action category (controller name)
action (action method name)
IsError (boolean; true means either this is a record of an error, or this action did not complete successfully)
blob of serialised details
At the moment, my logging uses a custom attribute which implements IActionFIlter; the OnActionExecuting() method logs the attempted action (serialising things like URL, parameters etc to the detail blob) and the OnActionExecuted() method goes back and sets IsError to true if there are no errors, and appends either the returned result or exception with error message and stack trace etc to the details. I want to add another column for description strings, but I can't see a tidy way to do it.
The furthest I got was to pass a string to the attribute, something like "User $user logged in" and then have the log method scan the string for the $ character and replace that word with anything from the parameters dictionary whose key value matches that word (minus the $ character). This is a little limited; for example, if articles are stored by ID number, then the best you can manage is "User 18 edited article 37". There's no real way to get at the username or article title; you can't pass instance data to the attribute because it's baked in at compile time, and I don't really want my logging method to be making all sorts of database calls to get that sort of data, not least because it then becomes impossible (or at least a real pain) to have a single generic logging method.
The alternative to all this is to have a static audit logging class and call something like AuditRecord.WriteLog(foo); all over the place, perhaps with some kind of descriptor class I can use (or inherit from) to describe different types of action, storing all the parameters and generating a description string as needed, but seems less elegant to me; I really like being able to just tag [AuditLog] on top of a method and know that it'll be recorded.
I'd like to avoid huge amounts of conditional logic, like using the controller and action names in some big switch statement to select the correct string template. If I could just get hold of things like article titles in the logging method then it'd be fine. Is there a neat, simple way to do this?
We recently had a similar discussion at work regarding both logging audit history and applying more complex security rules across our new MVC project.
In the end the most "elegant" solution that we came up with was to have the method calls within the controller actions (Your alternative method).
For example:
[HttpPost]
public ActionResult CreateItem(Item item)
{
//Simplified
CheckSecurity(SecurityTypes.ItemCreation);
LogActivity("Created an item");
//Rest of action code
}
This gave us the flexibility to account for all possible use cases, and allowed us to wrap up the logic into simple to use methods to reduce code repetition.
It may be late to answer, but I think there is a good alternative to keep using action filter attributes and to be able to access per-request lifecycle objects.
As anaximander noted it above, the underlying problem is that attributes are resolved by the CLR, so their lifetime cannot be controlled and they don't mix very well with an IoC container (to make them transient, per request instance, etc.).
Usually, in .NET a new instance of attribute is created each time it is resolved by reflection (GetCustomAttribute method).
Furthermore, in the case of MVC/webapi, action filter attributes are cached, so they normally are created just once.
The conclusion is that attributes are designed to annotate only, in other word, they should contain only metadata (they are DTO). Unfortunately, my understanding is MVC and WebApi frameworks are not designed in this way. To restrict action filter attributes to simple DTOs and to be able to manage lifecycle of the logic part around them, special means must be taken.
I think your use case fits perfectly to the solution provided in a Steven van Deursen's great article. It demonstrates how to separate attributes data from logic and it is based on an action filter registered globally, the so called "dispatcher", with the ioc container as a dependency.
The container is not resolved statically. It is provided in the constructor of the global filter when it is registered at the application initialization.
So each time it is executed, it looks for any attribute marker on the action being executed and it resolves a generic interface where the attribute is the generic parameter. Instead of having an action filter attribute which merge data and behavior, you end up using two classes: a plain old attribute - the marker - and the corresponding implementation of the generic interface for its logic counterpart. The container is used to resolve the generic interface. If your filter depends on per-request components, you can create an implementation of the generic interface with the services you need. If it does not depend on other services but you need a per-request lifetime (to measure time between the beginning and the end of an action for example), it also does the job, thank to the use of the container to resolve the generic interface. The aforementioned article contains code examples for WebApi, MVC and ASP.NET 5.
Also, Mark Seemann has made an article on the same approach.
I think it does not provide a good solution for all cases, like authorizations filters and perhaps exception filters, but to me it is the most elegant way for many action filters.
The better way would be to format this data when you view it, rather than build these things during the logging process.
If the action is "login", and the recorded user is available (which you should do) then you build that message in the viewer.
So you log all the raw events, then build the "view model" or "read model" based on this data that is more descriptive. this can allow you to even re-parse all the raw data if you want to change it's description. You could log a lot of data that isn't used yet so you could implement it later within the description.
IMO, sprinkling methods this way inside actions doesn't seem like a good idea and an Action Filter on the controller or base controller is cleaner. if you wanted to do that you could use an AOP (aspect oriented programming) framework to avoid cross cutting...

Best solution: Extension Methods or a New Class?

So I'll try and play devil's advocate on this one...
Hypothetically there is a Framework which services 2 or 3 different web sites. 1 basic function of the framework is to deal with all calls to a certain DB. When making a DB call the websites call a Framework DataSource object and get a generic Framework data object back.
Now for the websites to retrieve properties/methods that are specific to it's needs we've got 2 solution options.
Create a new Class, extending or wrapping the generic data object,
exposing more domain friendly properties & keeping any domain
specific functionality inside of this new class.
Instead of creating a new class, create extension methods inside the Framework to service each of these websites. So everything is
contained inside the Framework and can be shared between web sites
if 1 day needed.
Just to clarify here would be examples:
Properties:
NewObject.GetSiteSpecificProperty
GenericObject.GetProperty("GetSiteSpecificProperty") or GenericObject.GetSiteSpecificProperty()
Methods
NewObject.DoSomethingSpecificToThisWebsite()
GenericObject.DoSomethingSpecificToThisWebsite()
So what solution would you opt for? 1 or 2?
Cheers.
In my opinion when designing a Framework you want to keep as much solution specific aspects out of the Framework and have the calling entities handle that if possible.
Now I'm not sure quite how your framework will be used or by how many different websites\projects but going with option (2) means that now whenever a new website is added the framework now needs to go do work in order to complete this functionality. The work of using the framework in a custom way should be handled by the websites not by the framework. If this framework ever grows to use 10 or even 100 websites, this becomes an absolute nightmare to maintain and your framework ends up looking much less like a framework and more like a solution specific product. Going with (1) is a much cleaner solution. Basically keep your framework reusable and solution-agnostic as possible.
If you are designing a framework that will be used by many different projects and is designed to be around for a while I'd recommend reading Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (2nd Edition)
Generally if you control the source of the class you're extending, I would extend it by inheritance instead of extension methods. Extension methods are great for adding custom functionality to classes you don't control, like .NET built-ins (String, Enum, IEnumerable) and other third-party objects. However, they can be hard to organize, and they're technically static methods, which you usually want to minimize in the interest of startup performance and memory footprint.
You may also find yourself in namespace and method resolution trouble by going with extensions; let's say you put the extension methods into site-specific libraries. If one site ever has to do the same site-specific thing as another, you must either include one site's library containing the extension method in the other site (exposing other things you may not want your code to know about, possibly containing duplicates of objects or extensions), or clone the code (violating DRY).
In my opinion, it's a better design to create a base class and use overrides for your site specific code. Although they could do it, it just doesn't seem like extension methods were meant for this type of operation.
Now if you're looking for a way to get different values using a shared framework on different websites, it seems like the web.config would suit that need. Each site will have it's own Web.Config, can you populate the specific property values you need in there, and have a single function to retrieve that value?
I would go for 1 because it keeps the framework general (and reusable) and specific functionality where it's used and where I would look if I were a maintenance programmer.
To share functionality I'd create a base wrapper class that the specific wrappers derive from.

Categories