Calling a ServiceStack service from Razor - servicestack

A bit of an edge case here:
I need to call a servicestack service from razor (same website)
Right now I'm doing
CheckIfConfiguredResponse aResponse= new JsonServiceClient("http:\\localhost:2000").Get<CheckIfConfiguredResponse>("/CheckIfConfigured");
Is that the proper way to go about doing it? Or is there better?
Also, How do I eliminate having to specify the web address manually and have it automatically populate the host (since it's the same web site)
Thanks in advance,
Will.

You never want to make a HTTP call back to yourself just to call a ServiceStack service.
Unlike other frameworks, Services in ServiceStack are simply auto-wired C# types which you can access from the IOC like every other registered IOC dependency. i.e. Inside a Razor View you can simply resolve it and call it directly from the IOC with:
var response = base.Get<CheckIfConfiguredService>().Get(new CheckIfConfigured());
This resolves and calls the service like a normal auto-wired C# dependency, but doesn't inject the current request context. If your service does need it, you can instead use AppHostBase.ResolveService which does, e.g:
var response = AppHostBase
.ResolveService<CheckIfConfiguredService>(HttpContext.Current)
.Get(new CheckIfConfigured());

Related

why should I not use MVC Jsonresult instead of apicontroller get method

I have developed an application which was MVC application. It has a requirement that the application will return json data for one get request.
So I have added apicontroller and created a get method to return json data.
So far so good. but then I thought, is it really needed to add apicontroller to create just one get method.
I started exploring and googling what is the difference other than content negotiation. Got lots of answers and articles but non of them were satisfactory.
So here is the actual confusion, why can't I just create a method in the MVC controller with JsonResponse and return the json data(Which I know only is need for my requirement, but other application on different domain will consume it).
Can anyone convince me why should I use apicontroller instead of MVC JsonResponse for my requirement or should I not be using apicontroller at all.
apology if there is any mistake.
If I get it right the question is Can we use MVC action to serve json content answer is yes! Is it okay to use Json Result? answer is It depends where do you want to consume it
Say I am an in a Web Environment where I have no need for the APIs (that means I am not going to serve my data to multiple clients) If that's the scenario where only your View is going to consume data returned from your Action Method you are good to go. An Action returning a Json Result is basically an Action Result and that's what it is made for.
but If you are in a REST scenario and you need your backend to serve your data to the client de facto standard is to use an independent Web API for that.
Controllers' main responsibility should be to work as an intermediary between your View and Model and whatever service layer you want to bring inside it. on the other hand, Web APIs are data-driven there only purpose is to serve data (use them if you need them)
Web APIs are good cause they give you the flexibility of serving the data to possibly any client that might need it. That's what I would pick if I am starting from scratch but if I only need to serve data to one client Controller Action methods will be way to go.
Hope this helps.

Using ServiceStack's Funq to LazyResolve dependencies

We are using ServiceStack in a web hosted API service, and have done so for awhile now. The execution path for any request follows the pattern:
Request comes in:
--> Service (handles request, utilizes IManager injected via constructor)
--> IManager (performs business logic, utilizes IRepository/ies that are injected via constructor)
--> IRepository/ies (SQL Server, NoSQL, utilizes connection factory/ies injected by constructor)
Now that we are entertaining another client, some of these requests need to follow slightly different business logic, and potentially utilize a different repo strategy. However, the API will remain consistent. To this end, I am extracting client specific logic (the concrete IManager and IRepository implementations above) to separate assemblies. I've written a component that inspects the current request context, identifying the client this request is for, which then uses reflection and the Activator to instantiate an instance of the specific implementation I want to execute for any given request.
However, because of this, I can't just register implementations of IManager and IRepository in the container at startup - this needs to be resolved dynamically per request. I'd like to do some type of LazyResolve, but I can't find any solid example of how this is done to get me started here.
Am I thinking crazy here? My API is essentially just that with this - the custom logic that occurs is isolated to client specific assemblies that are called at runtime. This all makes perfect sense to me in theory, but in practice it's proving a challenge. Thoughts? Ideas?
If you only want to resolve adhoc dependencies at runtimes you can just resolve them from the IOC as needed in your Service with:
base.TryResolve<T>();
In any Filter from IRequest with:
req.TryResolve<T>();
Or externally outside ServiceStack with:
HostContext.TryResolve<T>();

What is the TableController class for and where are its methods used?

I've been starting out with Azure and have chosen to set up a Mobile Service using .NET in VS. I've been learning about the constituents of the Azure Todo get-started server project.
One thing I'm struggling to understand (even with extensive Googling) is what the TableController methods are for? I understand that TableController exposes the table to HTTP requests? But when I access data from my client I'm using ".LookupAsync" or ".UpdateAsync" methods on the Table returned by my MobileServiceClient instance.
Are the GetAllToDoItems(..), PathToDoItem(..), GetToDoItem(..), PostToDoItem(..), DeleteToDoItem(..) methods in the TableController being used behind the scenes somewhere when I make those calls on the MobileServiceClient Table?
Can I access those methods from my client? Are these methods standard/required method names?
Is TableController a good place to put server code for authorisation? E.g. the classic example of only returning that user's records?
Thanks for any help,
Tom.
Can I access those methods from my client? Are these methods standard/required method names?
At currently, Azure mobile app support C# and node.js as its backend language. From the Get started article, we can know that we can take advantage of Mobile App using native SDKs whether you're building native iOS, Android, and Windows apps or cross-platform Xamarin or Cordova (Phonegap) apps. We can see a lot of functions like GetAllToDoItems(..), PathToDoItem(..), GetToDoItem(..), PostToDoItem(..), DeleteToDoItem(..) in the backend project. This method is a MVC controller action name. Please note the SDK functions are the important, as we can see below, the backend project has a function called GetTodoItem.
public SingleResult<TodoItem> GetTodoItem(string id)
{
return Lookup(id);
}
However the function Lookup which under the namespace "Microsoft.Azure.Mobile.Server" is the key method in this function:
Is TableController a good place to put server code for authorisation? E.g. the classic example of only returning that user's records?
If you want to add authentication, I think this article may be give you helps. Just use Azure AD for example, if you want to protect some table controller, we only need to configure Azure AD then add [Authorize] attribute before table controller, it is not necessary to add authrize code in that table controller.

Apply IHasRequestFilter to Plugin registered service dynamically

I have a set of Services that I want to use in various ServiceStack projects (okay, two) so I have created a ServiceStack Plugin that registers them.
However I want to allow users to determine their own method of securing access to these services.
Currently I have an IHasRequestFilter in one my projects that can determine which services a user should be able to access. I do not want a reference to this in the Plugin project, so I want to add this dynamically after the fact.
I want to somehow get a reference to the Service Definition in AppHost to add this IHasRequestFilter to the pipeline for a specific set of services.
Ideally I should be able to do something like this:
new CustomPlugin(new CustomPluginParams {
RestrictTo = CustomRestrictions,
RequestFilters = [],
ResponseFilters = []
});
This should use those properties to configure their services without having a previous typed reference.
Edit:
Investigating further it appears that the IHasRequestFilter and IHasResponseFilters are only parsed once, in the ServiceExec<TService> class. I could get round this by creating my Services with a Proxy which adds the attribute I require to the MemberInfo of the operations, however I don't regard that as a clean approach.
Does anyone have recommendation?
In ServiceStack all configuration should happen within AppHost's Configure() method and remain immutable thereafter.
Lifecycle Events
To help with LifeCycle events there are IPreInitPlugin and IPostInitPlugin Plugin Interfaces which your Plugins can implement so they will get called back before and after all plugins are registered.
There's also an IAppHost.AfterInitCallbacks plugins can use to get called back after the entire AppHost has finished initialiazing.
Typed Request/Response Filters
Attributes are typically statically defined on Services, to dynamically add logic that apply to specific Request/Responses you can use a typed Request/Response filter.
The nice thing about ServiceStack Filters is that they share the same API (IRequest, IResponse, object) which makes them easily composable, e.g:
RegisterTypedRequestFilter<CustomRequest>(new RequestAttributeFilter().Execute);
Dynamically adding Attribute filters
As all ServiceStack libraries use ServiceStack.Text's Reflection API's you're able to extend ServiceStack's attribute-based code-first API dynamically by adding attributes to types or properties at runtime, e.g:
typeof(CustomRequest)
.AddAttributes(new RuntimeAttributeRequestFilter());
This can be done for most of ServiceStack's code-first API's inc. Request/Response Filters.
Route attributes and Action Filters
There is sometimes an issue for Services Route attributes and Action filters that already pre-configured and autowired before the AppHost's Configure() is called.
One solution is to add them in the AppHost constructor (or by overriding AppHost.OnBeforeInit) so they're added before the Services are configured. Otherwise you can reset the action filter caches by calling the AppHost's ServiceController.ResetServiceExecCachesIfNeeded().

Inserting parameter to a web service call in service stack

Lets say I have the Hello World web service defined, from the Service Stack examples, but instead of just calling it as /hello/{name}, I want to be able to call it as /hello/{name}/id, where I define id to be a separate parameter (by storing it in refId, within a CustomUserSession).
In other words, I want to split the authentication and the actual web service call into 2 parts, but I don't want to expose this id in the actual web service call, because this is private, only within my system. How would I go about doing this? My ideal workflow is:
client calls web service : /hello/{name}
authentication happens. As part of this authentication, I get hold of this secret id
I now call the web service as /hello/{name}/id
It's almost as if I want to call a web service from within another web service.
I apologize if this seems like a misguided question, but how can I go about achieving this workflow?
Thanks
I recommend taking a look at ServiceStack routing. Your service will only be called if it matches an existing route (or uses a pre-defined route) which means if you only had:
[Route("/hello/{name}")]
It wont match /hello/{name}/{id} and your service wont be called. To match that route you can either have an explicit route for it, e.g:
[Route("/hello/{name}/{id}")]
But this is public info which you're saying you would like to hide. The alternative is to use a wildcard route, e.g:
[Route("/hello/{name*}")]
Which matches any /hello/* route inc. /hello, /hello/foo, /hello/foo/id, /hello/foo/id/and/more/etc.
But what gets populated in your Hello.Name property would be foo/id which you'd have to detect and parse in your service.
An alternative is to supply the hidden id in a QueryString or POST'ed form parameter which you can use in ServiceStack to further populate any request DTO, e.g. using the original route:
[Route("/hello/{name}")]
Will let you call the service with /route/foo?id=secret which if your Request DTO had an id property will be populated with secret. If you didn't have (or want) to have an id property you can still access the param with:
base.Request.QueryString["id"];
base.Request.FormData["id"];
But since you want this to be hidden, you should probably avoid passing it in the url which is visible by everyone (inc. web proxies, http logs, and other middle ware). A better place to hide a param is to pass it as a custom HTTP header, e.g: X-id: secret which you can access in your service with:
base.Request.Headers["X-id"];

Resources