Restlet - Status service driven by the requested resource - restlet

I am developing for the following REST inquiries with Restlet.
http://localhost:8182/employees/{empId}
http://localhost:8182/timeline/{empId}
I have an application with an overridden createInbounRoot that has a Router attached to employees/{empId} and timeline/{empId}. In this application, I am able to set one status service, say EmployeeStatusService. How do I tell my application to use a different status service depending on the resource requested ?
Or, is there a completely different way of doing this ?
My application:
public class App1 extends Application {
public CatalogueApplication() {
this.setStatusService(new EmployeeStatusService());
//this.setStatusService(new TimelineStatusService());
}
#Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/employees/{empId}", Employees.class);
router.attach("/timeline/{empId}", Timeline.class);
return router;
}
}

Related

Phalcon Controller $this->session and Phalcon\Session\Manager()

I'm using Phalcon v.4 and I have seen that are two ways to create the session inside a controller:
class PostController extends Controller
{
public function postAction(): Response
{
$session = new Phalcon\Session\Manager()
}
}
or
class PostController extends Controller
{
public function postAction(): Response
{
$this->session;
}
}
I have seen that the methods are the same, but I'm not able to understand the different and which is better to use.
if you created your project using phalcon's cli devtools then the session service would be created by default in app/config/services.php
that being said in your controller when you access the instance's property session aka $this->session this would look for a service called session and by default it would setup session using file adapter and starts it and $this->session would return an instance of Phalcon\Session\Manager

404 Deploying asp.net core hosted blazor webassembly to Netlify

I am attempting to deploy an asp.net core hosted blazor webassembly app to Netlify. I have published the release version of the Server project to a directory on my desktop, and uploaded it to github. I set Netlify's publish directory to wwwroot and the site does render just fine. However, if I attempt a call to an api controller, it returns a 404. Specifically, here is my code:
//Register.razor in the Client project
if (Model.Password.Length >= 6 && Model.Password == Model.ConfirmPassword)
{
await HttpClient.PostAsJsonAsync<RegisterModel>("api/Register/Post", Model);
NavigationManager.NavigateTo("/");
}
//In my controller
[Route("api/Register")]
public class RegisterController : Controller
{
private UserContext UserContext { get; set; }
private IHasher Hasher = new Pbkdf2Hasher();
public RegisterController (UserContext userContext)
{
UserContext = userContext;
}
[RequireHttps]
[HttpPost]
[Route("Post")]
public async Task Post([FromBody]RegisterModel model)
{
var user = new UserModel
{
Email = model.Email,
Password = Hasher.Hash(model.Password)
};
await UserContext.AddAsync(user);
await UserContext.SaveChangesAsync();
}
}
The url request I send is: https://(NetlifyDefaultDomain)/api/Register/Post. However, I get a 404 response. On localhost it works just fine. I'm imagining that there's a setting that I have to change somewhere in order for the request URL to work. I've tried looking but have been unable to find guidance. What do I need to change? Thanks
Edit
Here is the Program.cs file of my Client project
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddTransient(sp => new HttpClient {
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider,
ApiAuthenticationStateProvider>();
builder.Services.AddScoped<IAuthService, AuthService>();
await builder.Build().RunAsync();
}
}
Target framework is netstandard2.1, and it's webassembly 3.2.0.
Netlify is a static file host. They do not run any server-side applications like .NET core on their servers.
So you can host your Blazor client-side application on Netlify but if you want server side code to run you must host it somewhere else.
If you are looking for free hosting for your API there are some cloud providers that have a free tier. Azure has free App Service with some limits, Google cloud has a free micro VPS that can host a small app, heroku also has a free offering.
A cheap VPS from Digital Ocean, Vultr or Linode is another alternative.

Enforce https on one controller and http on the other

I am using ASP.NET core 2.1,
I am looking for a way to enforce https on one controller and http on the other.
The following document shows how to enforce HTTPS for the whole ASP.NET core, but not for individual controller.
https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl?view=aspnetcore-2.1&tabs=visual-studio
One approach would be to make use of two action filters: one for enforcing HTTPS redirects, and another for allowing HTTP requests. The first one would be registered globally, and the second used just with controllers/actions you wish to allow HTTP traffic to. As an example:
[AllowHttp]
public class HomeController : Controller
Where AllowHttp is defined as:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
// Inheriting from ActionFilterAttribute allows this to show
// up in the ActionExecutingContext.Filters collection.
// See the global filter's implementation.
public class AllowHttpAttribute : ActionFilterAttribute
{
}
Next, the global filter:
// Needed for the GetEncodedUrl() extension method.
using Microsoft.AspNetCore.Http.Extensions;
public class RedirectToHttpsActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.Filters.Any(x => x is AllowHttpAttribute))
{
return;
}
if (!context.HttpContext.Request.IsHttps)
{
var insecureUri = context.HttpContext.Request.GetEncodedUrl();
var secureUri = insecureUri.Replace("http://", "https://");
// As you're likely trying this out locally, you'll need to specify
// the port to redirect to as well. You won't need this on production.
// Change the first port to your HTTP port and the second to your HTTPS port.
secureUri = secureUri.Replace(":49834", ":44329");
context.Result = new RedirectResult(secureUri);
}
}
}
Finally, you'll have to register the filter globally in your Startup.cs:
services.AddMvc(options =>
{
options.Filters.Add(new RedirectToHttpsActionFilter());
});
I'm sure you could achieve the same thing with URL rewriting, but in the case where you may change your controller routes, this will carry on working without intervention.

How to run XUnit test on both self-host & production webapi service?

I'd like to write a test for my ASP.NET WebApi service and run it against a self-hosted service and the live web hosted service. I imagine that this can be done with a test fixture, but I'm not sure how to set it up. Does anyone know of an example of using a configurable test fixture so that you can pass a parameter to Xunit to choose a self hosted fixture or a web hosted fixture?
Here is how it works with latest xUnit 2.0 beta.
Create a fixture:
public class SelfHostFixture : IDisposable {
public static string HostBaseAddress { get; private set; }
HttpSelfHostServer server;
HttpSelfHostConfiguration config;
static SelfHostFixture() {
HostBaseAddress = ConfigurationManager.AppSettings["HostBaseAddress"]; // HttpClient in your tests will need to use same base address
if (!HostBaseAddress.EndsWith("/"))
HostBaseAddress += "/";
}
public SelfHostFixture() {
if (/*your condition to check if running against live*/) {
config = new HttpSelfHostConfiguration(HostBaseAddress);
WebApiConfig.Register(config); // init your web api application
var server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
}
}
public void Dispose() {
if (server != null) {
server.CloseAsync().Wait();
server.Dispose();
server = null;
config.Dispose();
config = null;
}
}
}
Then define a collection that will use that fixture. Collections are the new concept to group tests in xUnit 2.
[CollectionDefinition("SelfHostCollection")]
public class SelfHostCollection : ICollectionFixture<SelfHostFixture> {}
It serves as just a marker so has no implementation.
Now, mark tests that rely on your host to be in that collection:
[Collection("SelfHostCollection")]
public class MyController1Test {}
[Collection("SelfHostCollection")]
public class MyController4Test {}
The runner will create a single instance of your fixture when running any test from within MyController1Test and MyController4Test ensuring that your server is initiated only once per collection.
I would recommend to use the In-Memory Server for testing your controllers, so you don't need to spin up a self-host in your unit tests.
http://blogs.msdn.com/b/youssefm/archive/2013/01/28/writing-tests-for-an-asp-net-webapi-service.aspx

Work with OData secured service

I want to generate entity classes and Service class of OData secured service.
In OData Java extension page it is written that I need to use org.restlet.ext.odata.Generator class that should get uri and output directory parameters.
But if my OData service is secured the generator instance is not able to generate service classes without username and password of the service.
I did not find any way to pass username and password to generator class.
I get 401 HTTP response code.
Please help.
In the org.restlet.ext.odata.Generator class, in the method main,
The following code would clear the credential details set in the setCredentials() method.
Service service = new Service(dataServiceUri);
if(service.getMetadata() == null)
{
errorMessage = "Cannot retrieve the metadata.";
}
Kindly provide a solution for this issue as I am currently unable to generate the classes for my rest service as the service is secured with an user password.
I tried the following code to generate the code for my secured service uri:
import org.restlet.ext.odata.Generator;
import org.restlet.ext.odata.Service;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
public class ODataRestletGenerator extends Service {
public ODataRestletGenerator(String serviceUri) {
super(serviceUri);
}
public static final String APPLICATION_URI = "http://ldcigkd.xxx.yyy.corp:50033/xxx/opu/sdata/IWCNT/CUSTOMER/";
public static void main(String[] args) {
// Add the client authentication to the call
ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;
ChallengeResponse credentials = new ChallengeResponse(scheme, "user", "pwd");
new ODataRestletGenerator(APPLICATION_URI).setauth(credentials);
String[] arguments = { APPLICATION_URI, "/customer/src" };
Generator.main(arguments);
}
private void setauth(ChallengeResponse credentials) {
super.setCredentials(credentials);
}
}
In the org.restlet.ext.odata.Service subclass that is generated by OData extension, you can call setCredentials() and pass an instance of ChallengeResponse including scheme (BASIC?), login (identifier) and password (secret).