Bind the request data to a model manually instead of it being in the action's parameters list - asp.net-core

I have an action that handles different kinds (but similar) requests. So I need the request data to bind to different models depending on several external inputs.
Is there a way to do that (so that the model isn't in the action's parameters list but bound manually)?

Implementing your own IActionModelConvention realisation, you can change the parameter binding rules.
Article, that may help: Customising model-binding conventions in ASP.NET Core
Here and here are examples in MVC github repo.

Related

Sulu: how to make custom entity translatable?

So I have my custom entity type, created it by following official tutorial:
https://docs.sulu.io/en/2.2/book/extend-admin.html
However entity I got is not translatable like i.e. standard pages or articles. I also didn't any info on how to make it translatable. Expected behavior is just to work as those standard types.
How to achieve that?
There are basically three things to do:
You have to add a new Translation entity for your custom entity. So if you have an Event entity, you need an additional EventTranslation entity. See https://github.com/sulu/sulu-workshop/tree/master/src/Entity
You need to tell Sulu, that your custom entity is translatable by adding the available locales to the view in your AppAdmin class, see https://github.com/sulu/sulu-workshop/blob/master/src/Admin/EventAdmin.php#L74
You need to adjust your custom entity's admin controller (it will receive a locale request parameter now) to persist the localized properties to the CustomEntityTranslation instead of the CustomEntity iself, see https://github.com/sulu/sulu-workshop/blob/master/src/Controller/Admin/EventController.php
So as conclusion, Sulu is only responsible for showing the locale switcher in the upper right corner and appending the current selected locale as locale parameter to your api calls. Everything else is completely up to you, you have to implement that like in a normal symfony application

Specifying properties returned from API in client

I want to limit the amount of properties that are returned from my REST api built in dotnet core. When accessing resources the client only needs specific subsets of the data returned from the api. What is a good way to tell the api which properties the client wants returned?
My initial thought would be to add query parameters to the endpoint like this:
http://www.restapi.com/v1/resource?fields=id,name,type
But I am not sure the best way to implement this in the api so that it is reusable and clean.
You're right that you usually don't want to return your full domain model or data model over your web API. Usually you define a custom model type for this purpose, which you can also decorate with attributes for model binding and model validation, if desired.
If you want the client to be able to determine what properties it gets, you can return an anonymous type built for this purpose, or perhaps have several DTO types predefined that the client's parameters result in.

How do I restrict which properties are bound using aspnetcore JSON from body of request

I could using [Bind("properties to include")] on an MVC action in ASPNET MVC 4. How do I restrict binding to specific properties using AspNetCore/MVC6? (RC2)
You could use JSON.NET's JsonIgnoreAttribute on properties which you want to exclude from deserialization, but note that this also makes the property not to serialize also. (Ideally you should have a model which is exactly what you expect from the user instead of ignoring certain properties, but I am not aware of how your requirements are)

What is the difference between a cornice.Service and cornice.resource in Cornice?

I have read through the documentation many times over and search all over for the answer to this question but have come up short. Specifically I've looked at Defining the service and the Cornice API for a service and at Defining resource for resource.
I'm currently building a REST API that will have a similar structure to this:
GET /clients # Gets a list of clients
GET /clients/{id} # Gets a specific client
GET /clients/{id}/users # Gets a specific clients users
What would be the best way to go about this? Should I use a service or a resource or both? And, if both, how?
Resources are high-level convenience, services offer lower level control.
I am just learning cornice myself. Looking at the source code, a Resource creates Services internally, one for the item and one for the collection (if a collection path is specified). The resource also adds views to the services for each method defined with an http verb as the name or in the form collection_[verb].
So there is little difference except that resources are a neat, structured way to define services.
The resource decorator uses a url for the collection, as well as a url pattern for an object.
collection_path=/rest/users
path=/rest/users/{id}
The resource decorator is best used in view classes where you can use get/put/post/delete methods on the objects, as well as collection_get, collection_put, etc. on the collection. I have some examples here:
https://github.com/umeboshi2/trumpet/blob/master/trumpet/views/rest/users.py
Since I make heavy use of the resource decorator and view classes, I haven't found a need for the service function, but it allows you to create get,put,post decorators that wrap view callable functions.
If you are using backbone.js on the client side, the resource decorator and url examples work well with the Backbone collections and models.

ASP.NET, MVC 3, EF 4.1: Filtering data based on ASP.NET Authentication login

If you have a decent layered ASP.NET MVC 3 web application with a data service class pumping out view models pulled from a repository, sending JSON to an Ajax client,
[taking a breath]
what's a good way to add data filtering based on ASP.NET logins and roles without really messing up our data service class with these concerns?
We have a repository that kicks out Entity Framework 4.1 POCOs which accepts Lambda Expressions for where clauses (or specification objects.)
The data service class creates query objects (like IQueryable) then returns them with .ToList() in the return statement.
I'm thinking maybe a specification that handles security roles passed to the data service class, or somehow essentially injecting a Lambda Expression in just the right place in the data service class?
I am sure there is a fairly standardized pattern to implement something like this. Links to examples or books on the subject would be most appreciated.
If you've got a single-tiered application (as in, your web layer and service/data layer all run in the same process) then it's common to use a custom principal to achieve what you want.
You can use a custom principal to store extra data about a user (have a watch of this: http://www.asp.net/security/videos/use-custom-principal-objects), but the trick is to set this custom principal into the current thread's principal also, by doing Thread.CurrentPrincipal = myPrincipal
This effectively means that you can get access to your user/role information from deep into your service layer without creating extra parameters on your methods (which is bad design). You can do this by querying Thread.CurrentPrincipal and cast it to your own implementation.
If your service/data layer exists in a different process (perhaps you're using web services) then you can still pass your user information separately from your method calls, by passing custom data headers along with the service request and leave this kind of data out of your method calls.
Edit: to relate back to your querying of data, obviously any queries you write which are influence by some aspect of the currently logged-in user or their role can be picked up by looking at the data in your custom principal, but without passing special data through your method calls.
Hopefully this at least points you in the right direction.
It is not clear from your question if you are using DI, as you mentioned you have your layers split up properly I am presuming so, then again this should be possible without DI I think...
Create an interface called IUserSession or something similar, Implement that inside your asp.net mvc application, the interface can contain something like GetUser(); from this info I am sure you can filter data inside your middle tier, otherwise you can simply use this IUserSession inside your web application and do the filtering inside that tier...
See: https://gist.github.com/1042173