Blazor retrieve relative url - url-routing

I am looking to retrieve the relative part of the current Blazor page URL.
For example if I am currently on https://www.mywebsite.com/someoverview, I wish to retrieve /someoverview.

It's not Blazor specific, we have the Uri class:
var uri = new Uri(#"https://www.mywebsite.com/someoverview");
var relativePath = uri.LocalPath; // or .PathAndQuery
or for the current Blazor page:
#inject NavigationManager Navigator
here
but do note that ToBaseRelativePath() does not include a leading /, it is different from LocalPath. You can mix & match.

Related

pass relative url in signalR hub connection

I am trying to implement signalR in angularJS,
I want to pass relative url to hub connection, but it's making current url (on which my angular application is hosted)
My API base url : http://localhost:81/NrsService/api/TestSignal
My angular application running at
http://localhost:81
Here is my signalR setup :
$.connection.hub.url = "/NrsService/api/TestSignal";
//Getting the connection object
connection = $.hubConnection();
Like it is sending request at http://localhost:81/signalr/negotiate? but I want it to be http://localhost:81/NrsService/api/TestSignal/negotiate?
You have to edit the generated JavaScript code where the client proxy is defined. As of SignalR 2.4.0 there is a createHubProxies function defined where you should find this line of code:
signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
Change it to the following to prevent the "/signalr" ending in your requests:
signalR.hub = $.hubConnection("", { useDefaultPath: false });
After that, you can simply change the url which should be called the way you provided in your question, e.g.:
$.connection.hub.url = "/NrsService/api/TestSignal";
If you also want to change this Url dynamically, you can use the document.location properties. In my case, I did something like this:
var subPath = document.location.pathname.substr(0, document.location.pathname.lastIndexOf("/"));
$.connection.hub.url = subPath; // subpath equals to "/NrsService/api"
Hope this helps.

Restlet + Google App Engine + CORS

I am using Restlet on Google App Engine for developing my sample application.
The front end is Angular 2 App.
The Rest API is working fine with browser.
However, I am getting the following issue when I am trying to hit the URL from Angular app.
XMLHttpRequest cannot load https://1-dot-jda-saas-training-02.appspot.com/rest/projectsBillingInfo/123. The 'Access-Control-Allow-Origin' header contains multiple values 'http://evil.com/, *', but only one is allowed. Origin 'http://localhost:3000' is therefore not allowed access.
So, I thought I will go ahead and add the CORS headers in the response. I used CorsFilter for that as follows but the issue is still there. When I see the header of the Response, I do not see any CORS headers. What am I missing here?
#Override
public Restlet createInboundRoot() {
// Create a router Restlet that routes each call to a
// new instance of HelloWorldResource.
Router router = new Router(getContext());
CorsFilter corsFilter = new CorsFilter(getContext(), router);
corsFilter.setAllowedOrigins(new HashSet<String>(Arrays.asList("*")));
corsFilter.setAllowedCredentials(true);
// Defines only one route
router.attachDefault(AddressServerResource.class);
router.attach("/contact/123",ContactServerResource.class);
router.attach("/projectsBillingInfo/123",ProjectBillingResource.class);
return corsFilter;
}
EDIT
I could get this working. May be I was doing some mistake.
But, I am not able to make this work with the GaeAuthenticator. When I am putting the GaeAuthenticator along with Corsfilter, it skips the authentication part of it. So, either the authentication works or the corsfilter works but not both. Is there any easy way to set/modify HTTP headers in restlet.
Here is the code I am using ..
#Override
public Restlet createInboundRoot() {
// Create a router Restlet that routes each call to a
// new instance of HelloWorldResource.
Router router = new Router(getContext());
// Defines only one route
router.attachDefault(AddressServerResource.class);
router.attach("/contact/123",ContactServerResource.class);
router.attach("/projectsBillingInfo/123",ProjectBillingResource.class);
GaeAuthenticator guard = new GaeAuthenticator(getContext());
guard.setNext(router);
CorsFilter corsFilter = new CorsFilter(getContext(), router);
corsFilter.setAllowedOrigins(new HashSet<String>(Arrays.asList("*")));
corsFilter.setAllowedCredentials(true);
return corsFilter;
First, I think you can use the service instead of the filter:
public MyApplication() {
CorsService corsService = new CorsService();
corsService.setAllowedCredentials(true);
corsService.setSkippingResourceForCorsOptions(true);
getServices().add(corsService);
}
Do you mind to set the "skippingServerResourceForOptions"?
#Override
public Restlet createInboundRoot() {
// Create a router Restlet that routes each call to a
// new instance of HelloWorldResource.
Router router = new Router(getContext());
// Defines only one route
router.attachDefault(AddressServerResource.class);
router.attach("/contact/123",ContactServerResource.class);
router.attach("/projectsBillingInfo/123",ProjectBillingResource.class);
return router;
}
Best regards, Thierry Boileau

Best way to provide url to angular $http.get/.post

I am using angular with MVC4. I would like to call a MVC controller method from javascript using $http.get(). It requires a url (obviously). I would like this to be a relative path, but how do I write that? My controller is in Controllers/Api/ExampleController. I would like the path to resolve even if I move the javascript file into another location, meaning I would like the path to be relative to application root as opposed to the javascript file. I Have tried "~/Controllers/Api/ExampleControllerMethod" and "Controllers/Api/ExampleController/Method.
The $location service does provide information from the url. So, you could construct something to then make the host and port dynamic:
var url = $location.host() + '/Controllers/Api/ExampleControllerMethod';
From the documentation:
**url: http://www.example.com/base/path?a=b#h**
$location.protocol() = http
$location.host() = www.example.com
$location.port() = 80
$location.path() = /path
$location.search() = {"a":"b"}
$location.hash() = h
Thanks for the ideas but this kind of thing is what I was looking for:
Configure the WebApiConfig to add a route like so (should have it as default):
config.Routes.MapHttpRoute(
name: "ApiMethods",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
So now I can go $http.get('api/{controller}/{method}')
What worked for me was to provide the Url as "/ControllerName/Action" (instead of "ControllerName/Action")

Retrieve external URL of media file

I have a page data folder with a property "Image", which is a reference to a Media file in the Composite C1 backend.
I now want to retrieve the data in my asp.net user control, but all I get when I access the "Image" Property of my PageDataFolder Type, is a string with the following format:
mediaarchive:b5354eba-3f69-4885-9eba-74576dff372d
I am not sure how to get the external image url from that. Is there an API function I can use?
Build a url like
~/media({MediaKey})
example: "~/media(mediaarchive:b5354eba-3f69-4885-9eba-74576dff372d)"
Once C1 page is rendered, it will be replaced with the following SEO friendly url:
/media/{Path to your image in media archive})
example: "/media/5611182f-6462-4b80-a051-3c3b9bb3276d/References/Screenshots/Olympiacos/1_png"
Note that you can specify image resing/cropping options via query string.
http://docs.composite.net/Getting-started/Configuration/Resizing-Images
If you, for some reason cannot rely on the C1 page rendering logic, you can build a public media url with the following code:
protected string GetMediaUrl(string mediaPath)
{
string[] parts = mediaPath.Split(new[] { ':' });
string mediaStore = parts[0];
Guid mediaId = new Guid(parts[1]);
string mediaUrl = MediaUrls.BuildUrl(new MediaUrlData { MediaStore = mediaStore, MediaId = mediaId, QueryParameters = new NameValueCollection() },
UrlKind.Public);
// Temporary fix, allows media player to receive a nice url with an extension
return mediaUrl.Replace("_jpg", ".jpg").Replace("_mov", ".mov").Replace("_m4v", ".m4v").Replace("_swf", ".swf");
}
I found a way, but it's not exactly the shortest one:
MediaUrlHelper.GetUrl(MediaUrlHelper.GetFileFromQueryString(new NameValueCollection { {"id", myItem.Image} }))
I still hope someone comes up with a better solution, I will be happy to mark that one as the answer.

Jax-Rs service is not getting invoked

I am developing JAX-RS Rest service using Apache CXF. After deploying it to Tomcat 7 server, if I type the URL http://localhost:8080/Rest/rest?_wadl it shows me the WADL. but if I enter the URL http://localhost:8080/Rest/rest/retrieve it gives me 404 error.
In above URLs: Rest is the name of my project
/rest is the url-pattern for my CXFServlet which is specified in web.xml
/ is the address of jaxrs:server which is specified in beans.xml
retrieve is the path of service which is specified in my interface with #Path annotation.
(My apologies: I can't provide the XML documents referred to above.)
I think this is a CXF bug which get the incorrect base URL for restful web services.
The class "org.apache.cxf.transport.servlet.ServletController" invokes the method "getBaseURL" of the class "org.apache.cxf.transport.servlet.BaseUrlHelper".
It gets the base URL from request URL, and it ignores the parameters part.
This is correct for SOAP web servcies, because SOAP web services URL is just like: http://host:port/basepath?para=a. Unfortunately, for restful web services, the URL is just like http://host:port/basepath/method/parameter. The correct base URL should be http://host:port/basepath, but actually, the BaseUrlHelper gives you http://host:port/basepath/method/parameter. It just gives the URL before "?". It's why the result is correct when you access http://localhost:8080/Rest/rest?_wadl, in this case, it gives the correct base URL http://localhost:8080/Rest.
If you access http://localhost:8080/Rest/rest?_wadl at first then you access http://localhost:8080/Rest/rest/retrieve, it would be correct. Because, CXF set the base URL as the address of EndpointInfo only at the first time. It means, you MUST access the correct base URL at the first time! :(
The solution is: override the method "getBaseURL(HttpServletRequest request)" of "org.apache.cxf.transport.servlet.ServletController", let it return correct base URL.
For example, step1: extends the ServletController.
public class RestfulServletController extends ServletController {
private final String basePath;
public RestfulServletController(DestinationRegistry destinationRegistry, ServletConfig config,
HttpServlet serviceListGenerator, String basePath) {
super(destinationRegistry, config, serviceListGenerator);
this.basePath = basePath;
}
#Override
protected String getBaseURL(HttpServletRequest request) {
// Fixed the bug of BaseUrlHelper.getBaseURL(request) for restful service.
String reqPrefix = request.getRequestURL().toString();
int idx = reqPrefix.indexOf(basePath);
return reqPrefix.substring(0, idx + basePath.length());
}
}
step2: extends CXFNonSpringServlet and use the RestfulServletController in the subclass
public class RestfulCXFServlet extends CXFNonSpringServlet {
... ...
private ServletController createServletController(ServletConfig servletConfig) {
HttpServlet serviceListGeneratorServlet = new ServiceListGeneratorServlet(destinationRegistry, bus);
ServletController newController = new RestfulServletController(destinationRegistry, servletConfig,
serviceListGeneratorServlet, basePath);
return newController;
}
}
step3: instead of CXFNonSpringServlet , you use the derived class RestfulServletController.
Don't forget, you should config the "basePath" as /Rest/rest.
Hope this can help you.

Resources