ASP.NET Core API with localized strings - asp.net-core

We have an ASP.NET Core API. There are no views as again this is a simple API. We have strings in resource files(by culture) and we want each user to get the correct resource (in each API request we have a language name parameter). Also we like to use strongly typed resources in the code. What is the best way to do it? if i simply set the thread UI culture to be the culture from the user it works fine until there is an 'await' in the code(i assume that a different thread kicks in)

Related

ASP.NET Transfer data from controller action

There is a sales service implemented as a Telegram bot. I need to create a website control panel for this service. Since the service is a .NET application I am thinking to use ASP.NET Core technology.
How do I transfer data from the controller action to the Program class containing all the functionality of the service (maybe it is worth defining the Program as a static class)?
You may have misunderstood Asp.Net Core. .net core adopts the pipeline mode, that is, when you call the action in the controller, it will enter the middleware pipeline of Program.cs(.net 5 is Startup.cs), and execute in sequence according to the order of your middleware, adopting the principle of first in, last out. This means that if you follow the normal .net core logic, the value you get in the controller (except the parameters defined in the URL), you cannot pass it into Program.cs. When you successfully enter the action of the controller, Program.cs has been executed.
Not sure what your sales service looks like, but I think you can register it as a service and use it in your controllers using dependency injection.
Helpful link: ASP.NET Core Middleware.

How to fix WrongInputException in ASP.NET Core?

I want to use a SOAP web service prepared by another team, used internally in my new REST API prepared in ASP.NET Core. My web service client code was scaffolded with WCF Web Service Reference Provider Tool. I cleaned up code (e.g. I changed property and method names) according to my team's naming convention.
When I send requests by my new REST API, I received WrongInputException. I checked all the parameters from an example request, all of them are in the same place in my C# code consuming scaffolded client.
I don't know what message exactly is sent by my new REST API.
In my case, the main cause of the described behavior and WrongInputException was premature refactoring. I changed the names of properties in the web service client without knowledge of the consequences.
E.g. if the element in the request body is objectRefNum, then I cannot simply change the related property in the scaffolded service reference class, because - without extra configuration - that name is copied with the same letter case to the request body of the SOAP envelope. The SOAP envelope should be encoded in the case-sensitive mode.
To trace the raw request body send by my new REST API in ASP.NET Core, I followed instructions from this excellent answer.
(Note, BTW, that kind of error (applying inappropriate letter case) could be handled by IDE, at least as a warning, but it is not, so: we need to be careful when we make refactoring, even if we have unit tests covering all the paths, and even if we use semantic renaming supported by IDE.)

Can Webapi be used in an application which is not excessed by any external application?

I'd read it somewhere that whenever one needs to do data intensive work then Webapi could be used. Ex: autocomplete textbox where we get data from using ajax on key press.
Now someone told me that Webapi shouldn't be used within applications which are not externally accessed. Rather action should be used to the same work as it is capable of returning the data back in a similar fashion to webapi.
I'd like to know your suggestions over it.
Depends on how you look at it. If all you need is ajax-ification of your controller actions, then you really don't need Web-API. Your actions can return a JsonResult and it is very easy to consume that from your client side through an AJAX call.
Web-API makes it easy for you to expose you actions to external clients. It supports HTTP protocol and Json and XML payloads automatically, out of the box, without you writing the code for it. Now, there is nothing preventing you from consuming the same Web-API actions from your own internal clients in an AJAX manner.
So the answer to your question depends on your design. If you don't have external clients, then there is no string need for you to have Web-API. Your standard controller actions can do the job.

Calling ConfigureAwait from an ASP.NET MVC Action

I was working on a presentation and thought the following should fail since the ActionResult isn't being returned on the right context. I've load tested it with VS and got no errors. I've debugged it and know that it is switching threads. So it seems like it is legit code.
Does ASP.NET not care what context or thread it is on like a client app? If so, what purpose does the AspNetSynchronizationContext provide? I don't feel right putting a ConfigureAwait in the action itself. Something seems wrong about it. Can anyone explain?
public async Task<ActionResult> AsyncWithBackendTest()
{
var result = await BackendCall().ConfigureAwait(false);
var server = HttpContext.Server;
HttpContext.Cache["hello"] = "world";
return Content(result);
}
ASP.NET doesn't have the 'UI thread' need that many clients apps do (due to the UI framework below it). That context isn't about thread affinity, but for tracking the page progress (and other things, like carrying around the security context for the request)
Stephen Toub mentions this in an MSDN article:
Windows Forms isn't the only environment that provides a
SynchronizationContext-derived class. ASP.NET also provides one,
AspNetSynchronizationContext, though it's not public and is not meant
for external consumption. Rather, it is used under the covers by
ASP.NET to facilitate the asynchronous pages functionality in ASP.NET
2.0 (for more information, see msdn.microsoft.com/msdnmag/issues/05/10/WickedCode). This
implementation allows ASP.NET to prevent page processing completion
until all outstanding asynchronous invocations have been completed.
A little more detail about the synchronization context is given in Stephen Cleary's article from last year.
Figure 4 in particular shows that it doesn't have the 'specific thread' behavior of WinForms/WPF, but the whole thing is a great read.
If multiple operations complete at once for the same application,
AspNetSynchronizationContext will ensure that they execute one at a
time. They may execute on any thread, but that thread will have the
identity and culture of the original page.
In your code, HttpContext is a member of your AsyncController base class. It is not the current context for the executing thread.
Also, in your case, HttpContext is still valid, since the request has not yet completed.
I'm unable to test this at the moment, but I would expect it to fail if you used System.Web.HttpContext.Current instead of HttpContext.
P.S. Security is always propagated, regardless of ConfigureAwait - this makes sense if you think about it. I'm not sure about culture, but I wouldn't be surprised if it was always propagated too.
It appears because the Controller captures the Context whereas using System.Web.HttpContext is live access to what is part of the synchronization context.
If we look at the ASP.NET MVC5 sources we can see that the ControllerBase class that all controllers inherit from has its own ControllerContext which is built from the RequestContext.
I would assume this means that while the synchronization context is lost after a ConfigureAwait(false); the state of the Controller in which the continuation is happening still has access to the state of the control from before the continuation via the closure.
Outside of the Controller we don't have access to this ControllerContext so we have to use the live System.Web.HttpContext which has all the caveats with ConfigureAwait(false);.

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