Should I expect Request Filter Validation (e.g. FluentValidation) to be triggered when instantiating a reference service via AppHostBase.ResolveService<>?
Thus far, I've only successfully received proper error responses to my C# application when using the typed clients (JsonServiceClient in this case specifically).
You are right. If you try use AppHostBase.ResolveService<T> it does not execute any of the registered request filters. Essentially it only resolves the Service from the AppHost dependancy container, you get back just the Service instance. Thus your validators aren't triggered.
ServiceStack v4:
As #mythz points out you can use the MQ entry point API of the HostContext to execute the call with the MQ request filters and thus have the validation run. To do this:
HostContext.ServiceController.ExecuteMessage(new Message<T>(requestDto), httpReq);
#mythz also notes you can execute a service using just a DTO, rather than having to determine the service and handling method to call, but in a similar fashion to AppHostBase.ResolveService<T> it doesn't trigger the request filters. Usage:
HostContext.ServiceController.Execute(requestDto, httpReq)
ServiceStack v3:
GetAppHost().Config.ServiceManager.ServiceController.ExecuteMessage(new Message<T>(requestDto), httpReq);
Related
We're all being taught to use Dependency-Injection for coding in ASP.NET Core applications, but all of the examples I've seen so far that related to the retrieval of services via DI relate to situations where the method that has the service reference injected is strictly bound to a specific HTTP request (HttpContext) (e.g. MVC controllers, Routing delegates).
Service location is warned against as an anti-pattern, but I'm not sure on how to obtain a proper service (e.g. DbContext) reference via DI in code that is not bound a specific HTTP request, e.g. code that has to respond to messages arriving over a websocket.
Although the websocket itself is set-up initially with a specific HTTP request, messages will get responses over potentially a long lifetime of the websocket (as long as the user web session lasts). The server should not reserve/waste a DbContext/DB connection over this entire lifetime (this would result in exhaustion quickly), but rather obtain a DB connection temporarily when a message arrives and requires a response; discarding the DbContext/connection immediately afterwards - while the original HTTP request that set-up the websocket in the very beginning of the user-session technically is still there.
I haven't been able to find anything else but using:
httpContext.RequestServices.GetService(typeof(<MyNeededDbContext>)
This way I use the initial httpContext (obtained via DI when the websocket was set up), but at multiple times after that whenever a websocket message needs a response I can request a transient service object (a DbContext in this example), that may be recycled or pooled after the message response is complete, but while the original httpContext is very much still alive.
Anyone aware of a better approach?
You can create a new service scope to manage the lifetime of services yourself;
IServiceProvider provider = ...;
using (var scope = provider.CreateScope())
{
var context = scope.ServiceProvider.GetService<MyNeededDbContext>();
...
}
If I have a hub method that accepts parameters
e.g.
public IObservable<MyStreamItem> StreamData(SomeRequestData request)
{}
How do I propogate validation errors in the request?
An actual http request is only made when the socket connection is established.
So subsequent calls to Hub methods dont pass through any middleware. They are just frames/messages in the open websocket.
I've had a look at this package which is for the previous version of Signalr (for the full .net framework)
https://github.com/AGiorgetti/SignalR.Validation
This uses a HubPipelineModule which doesn't seem to exist in the new .net core Signalr.
Is there an appropriate place in the pipeline that I can tap into to do the validation?
Or should it be done in the hub method itself? And if so, how would you conditionally return a structured set of errors, as opposed to what the actual return type is meant to be?
thanks
There are currently no HubPipelineModules in SignalR alpha but we're looking at an equivalent for preview 2. Today, you'd need to do it in the method and potentially throw an error to get it back to the client.
I need to be able to call my SS services from the controllers of an MVC application. Ideally i'd like to call them in-process to avoid the overhead of buiding a http request etc.
From scouring documentation I feel there are 2 suggested methods, but neither work fully.
1) ServiceGateway - Use the service gateway. This calls validation filters, but does not call other customer filters I've added. No option to applyFilters.
2) HostContext.ServiceController.Execute - There is a dedicated option on this method called applyFilters, and when I set it to true it works and applies filters and validation (though it only executes GlobalFilters, not TypedRequestFilters). However, if [CacheResponse] attribute is set on the service it overwrites and flushes a response to my client overriding the flow of the MVC controller and i don't know how to stop this. It does not do this if I set to applyFilters to false or if I take CacheResponse off. Changing the priority of the cache has no effect.
I'm calling the Execute method as follows from within an Action method on my controller:
HostContext.ServiceController.Execute(serviceRequest, HostContext.GetCurrentRequest(), true);
Before this method even returns control a response is flushed to the webpage on Chrome and then nothing/null is returned from method.
I feel there is regarding point 1) a feature missing and point 2) a bug in the implementation, though am not confident enough in my knowledge of SS to remedy either! Please help!
Thanks.
Filters are executed as part of the HTTP Request Pipeline and can terminate the current Request with a custom HTTP Response. You can check IRequest.IsClosed after executing the Request to check if it has been terminated by a Request Filter. They're behavior is incompatible with internal Gateway requests so there's no option to execute them in the Gateway.
I've marked these ServiceController methods as an In Process Request in this commit which should resolve the issue with the [CacheResponse] attribute which ignores In Process Requests.
This change is available from v4.5.13 that's now available on MyGet.
I am new to WCF services and currently testing out things.
I have got a little REST API, which has several methods. Some of them require a user context (session), some others don't. At login, each user gets a session token. The client should supply this token and his user ID on every request via HTTP headers.
At the moment, I wrote a method for getting those two headers and validate the session, calling it on every method which will need a user context. This seems kinda nasty if the API gets bigger.
Is there a better approach for doing this?
You can leverage of following solutions:
Custom class deriving IClientMessageInspector/IDispatchMessageInspector for client and service respectively. Then you add its instance to MessageInspectors. Advantage of having messageInspector is that it's applied to single endpoint so regardless of having many endpoints exposed (both SOAP and REST), messageInspector can be associated only with single one. Whenever message is either received or sent, AfterReceive or BeforeSent method is invoked respectively. There you retrieve headers and if token does not match any expected you can throw an exception. Such a way out provides separation between exposed contract and background checks such as token validation.
Custom class deriving IOperationInvoker. Within custom operation invoker you explicitly call method and thanks to it you can examine headers (OperationContext.Current.IncomingMessage) before any method gets invoced.
I brought up only concepts, extensive information and examples can be looked up on Internet.
I'm implementing new REST API method which allows calling other REST API methods in batch\bulk manner. Similar to Facebook's https://developers.facebook.com/docs/graph-api/making-multiple-requests
Request example:
POST /batch
[
{"method":"GET", "relative_url":"/user/anton"},
{"method":"GET", "relative_url":"/user/vitaliy"}
{"method":"POST", "relative_url":"/user/dan", "body":{name:Dan}}
]
Response example:
status 200
[
{"status":"200", "body":{name:"Dan"}},
{"status":"404"},
{"status":"201"}
]
In short, batch method should on server-side call OTHER methods one-by-one and return result as array of results.
The most simple solution will be create .Net HttpClient on server side and call other WCF methods on-by-one.
The question is: How implement this using WCF infrastructure without calling WCF method externally via HttpClient?
The reason for that - I don't want to have network-round trips.
The most perfect solution will be to use .Net Reflection, but this not good solution in terms of REST abstraction
The most close solution is create WCF Message including HttpRequestMessageProperty (URL, Headers, Method, Content-Type) and send it to processing by WCF infrastructure (just it was sent via HTTP protocol) (not sure about this):
Message responseMessage = wcfInsfrastucture.Process(createWcfMessage(url, method,contentType,body));
Currently I'm lost in WCF Samples, and WCF server-side channel architecture.
Most similar question was asked in Sending custom WCF Message to a service but I can't making it work with existing configured server-side behaviors.
Similar questions:
Sending custom WCF Message to a service
https://stackoverflow.com/questions/26049136/generic-way-to-send-wcf-messages-to-different-channels
How implement this using WCF infrastructure without calling WCF method externally via HttpClient?
The only way I found is to implement request-response pattern over WCF.
Create a single entry point in WCF service, that receives an abstract request as an argument and returns an abstract response.
For example,
<OperationContract> function Execute(Request as IRequest) as IResponse
Create concrete request and response classes for service operations
Create CompositeRequest and CompositeResponse for Batch / Bulk operations
All service has to do is to apply business logic according to request type.
In case service receives CompositeRequest it just calls the same Execute method for all nested requests one-by-one and aggregates responses into CompositeResponse.