Part of my application maps resources stored in a number of locations onto web URLs like this:
http://servername/files/path/to/my/resource/
The resources location is modelled after file paths and as a result there can be an unlimited level of nesting. Is it possible to construct an MVC route that matches this so that I get the path in its entirety passed into my controller? Either as a single string or possibly as an params style array of strings.
I guess this requires a match on the files keyword, followed by some sort of wildcard. Though I have no idea if MVC supports this.
A route like
"Files/{*path}"
will get the path as a single string. The * designates it as a wildcard mapping and it will consume the whole URL after "Files/".
For more information on ASP.NET's Routing feature, please see MSDN:
http://msdn.microsoft.com/en-us/library/cc668201.aspx
And for the "catch-all" parameters you want to use, see the section under "Handling a Variable Number of Segments".
Related
I have URLs like:
/return/{pid}.xml?d1='123'&d2='345'
/return/{pid}.json?d1='123'&d2='345'
the swagger specification calls for:
path:/return/{pid}
....
but how can I map the extension ie
path:/return/{pid}.xml
or
path:/return/{pid}.json
It is a jersey+spring mvc application - so both the URLs are hitting the same controller and only based on the extension the rest framework is going to generate the xml / json output.
I can't ignore the extension from the path ie:
path:/return/{pid}
because the user needs to know that he/she has to provide the file extension as part of the URL. Also I can't use two paths corresponding to xml / json because they are treated the same by the application. In addition it will duplicate things (I am not sure whether there is a fall-through like mechanism just like "case" statements in c++/java "switch" block)
In Swagger specs,You can define the file extensions in the path as below :
/return/{pId}.{fileExtension}
and define the fileExtension in parameters .
also the below is valid (not for your case) :
/return/pid.{fileExtension}
I'm trying to migrate my ASPX site to Kentico, and as part of my task I'm migrating URLs. I need to preserve my URL structure, so I need to keep URLs which look like : "foo.com/bar.aspx?pageid=1".
I checked page's "URLs" property tried to use wildcards, some patterns like /bar/{pageid}- /bar/{?pageid?}-, etc but Kentico always replaces question marks.
Is there a way to achieve that via the admin interface?
You don't need to do anything in order to use "foo.com/bar.aspx?pageid=1" url.
Create a page under the root and call it bar, so you'll get a page # foo.com/bar.aspx. Kentico and/or .net does not care what you add to a url after question mark, so foo.com/bar.aspx?pageid=1 will work as well as foo.com/bar.aspx?someparam=sdf, or foo.com/bar.aspx?id=1&p=3&t=3.
You may (or may not) implement some functionality based on query string (e.g. paging), so it will parse query string and act in appropriate way.
By default Kentico UI does not handle adding URL aliases with URL parameters like you show. There is an article on the DevNet for a URL Redirection module which has code you can import into your site to allow you to perform these redirects within the Kentico UI. I'd suggest using this approach.
Unfortunately, I can't share a code sample since it's an article but it also has a link to download the code too. This appears to only be coded for Kentico 8.2 right now but I'm guessing you could do some work to make it work for other versions if you needed.
I think there are few concepts that you are clubbing here. I will start with your line code here
/bar/{pageid} - {pageid} is a positional parameter in Kentico's language if you choose to use dynamic URLS based on patterns. SO if you have a code that relies on pageid parameter to fetch some data then Kentico will pass that value. E.g in case of /bar/420, it will pass pageid as 420 different web parts on your template
/bar/{?pageid?} - This will search for query string parameter "pageid" on the request URL and replace its value here. So if you passed foo.com/bar.aspx?pageid=366, the resulting URL will be /bar/366
The #1 is positional parameter and #2 is the way in which Kentico resolves query string macros.
I hope this clarifies.
Backbone.js maintains routing information in a URL after the hash mark, e.g.:
http://localhost:3000#page/hardware/table/?action=details&actionTargetId=5&actionTargetName=10.3.177.185&actionTarget=host
Even though the routing information is in the format ?p1=v1&p2=v2&p3=v3, this portion is not technically part of the url query string since it comes after the hash mark.
My question is if I add an actual query string to our app's urls like this:
http://localhost:3000?newparam=newvalue#page/hardware/table/?action=details&actionTargetId=5&actionTargetName=10.3.177.185&actionTarget=host
is there any possibility of the "newparam" url parameter interfering with the backbone portion?
the problem is your not actually creating a legit query string. your mixing your route with your parameters.
your example is formatted as:
domain ? param # route ? other params
as soon as a questionmark appears in a url everything after it is interpreted as a query string. (in this case) even your route.
personally i suggest using the html5 pushstate.
Backbone.history.start({pushState: true})
this will give you clean(er) urls
http://localhost:3000/page/hardware/table/?newparam=newvalue&action=details&actionTargetId=5&actionTargetName=10.3.177.185&actionTarget=host
that will help your routes to not interfere with your parameters.
I have a Java component which scans through a set of folders (input/processing/output) and returns the list of files in JSON format.
The REST URL for the same is:
GET http://<baseurl>/files/<foldername>
Now, I need to perform certain actions on each of the files, like validate, process, delete, etc. I'm not sure of the best way to design the REST URLs for these actions.
Since its a direct file manipulation, I don't have any unique identifier for the files, except their paths. So I'm not sure if the following is a good URL:
POST http://<baseurl>/file/validate?path=<filepath>
Edit: I would have ideally liked to use something like /file/fileId/validate. But the only unique id for files is its path, and I don't think I can use that as part of the URL itself.
And finally, I'm not sure which HTTP verb to use for such custom actions like validate.
Thanks in advance!
Regards,
Anand
When you implement a route like http:///file/validate?path you encode the action in your resource that's not a desired effect when modelling a resource service.
You could do the following for read operations
GET http://api.example.com/files will return all files as URL reference such as
http://api.example.com/files/path/to/first
http://api.example.com/files/path/to/second
...
GET http://api.example.com/files/path/to/first will return validation results for the file (I'm using JSON for readability)
{
name : first,
valid : true
}
That was the simple read only part. Now to the write operations:
DELETE http://api.example.com/files/path/to/first will of course delete the file
Modelling the file processing is the hard part. But you could model that as top level resource. So that:
POST http://api.example.com/FileOperation?operation=somethingweird will create a virtual file processing resource and execute the operation given by the URL parameter 'operation'. Modelling these file operations as resources gives you the possibility to perform the operations asynchronous and return a result that gives additional information about the process of the operation and so on.
You can take a look at Amazon S3 REST API for additional examples and inspiration on how to model resources. I can highly recommend to read RESTful Web Services
Now, I need to perform certain actions on each of the files, like validate, process, delete, etc. I'm not sure of the best way to design the REST URLs for these actions. Since its a direct file manipulation, I don't have any unique identified for the files, except their paths. So I'm not sure if the following is a good URL: POST http:///file/validate?path=
It's not. /file/validate doesn't describe a resource, it describes an action. That means it is functional, not RESTful.
Edit: I would have ideally liked to use something like /file/fileId/validate. But the only unique id for files is its path, and I don't think I can use that as part of the URL itself.
Oh yes you can! And you should do exactly that. Except for that final validate part; that is not a resource in any way, and so should not be part of the path. Instead, clients should POST a message to the file resource asking it to validate itself. Luckily, POST allows you to send a message to the file as well as receive one back; it's ideal for this sort of thing (unless there's an existing verb to use instead, whether in standard HTTP or one of the extensions such as WebDAV).
And finally, I'm not sure which HTTP verb to use for such custom actions like validate.
POST, with the action to perform determined by the content of the message that was POSTed to the resource. Custom “do something non-standard” actions are always mapped to POST when they can't be mapped to GET, PUT or DELETE. (Alas, a clever POST is not hugely discoverable and so causes problems for the HATEOAS principle, but that's still better than violating basic REST principles.)
REST requires a uniform interface, which in HTTP means limiting yourself to GET, PUT, POST, DELETE, HEAD, etc.
One way you can check on each file's validity in a RESTful way is to think of the validity check not as an action to perform on the file, but as a resource in its own right:
GET /file/{file-id}/validity
This could return a simple True/False, or perhaps a list of the specific constraint violations. The file-id could be a file name, an integer file number, a URL-encoded path, or perhaps an unencoded path like:
GET /file/bob/dir1/dir2/somefile/validity
Another approach would be to ask for a list of the invalid files:
GET /file/invalid
And still another would be to prevent invalid files from being added to your service in the first place, ie, when your service processes a PUT request with bad data:
PUT /file/{file-id}
it rejects it with an HTTP 400 (Bad Request). The body of the 400 response could contain information on the specific error.
Update: To delete a file you would of course use the standard HTTP REST verb:
DELETE /file/{file-id}
To 'process' a file, does this create a new file (resource) from one that was uploaded? For example Flickr creates several different image files from each one you upload, each with a different size. In this case you could PUT an input file and then trigger the processing by GET-ing the corresponding output file:
PUT /file/input/{file-id}
GET /file/output/{file-id}
If the processing isn't near-instantaneous, you could generate the output files asynchronously: every time a new input file is PUT into the web service, the web service starts up an asynchronous activity that eventually results in the output file being created.
The reason I'm asking is because IIS protects certain ASP.NET folders, like Bin, App_Data, App_Code, etc. Even if the URL does not map to an actual file system folder IIS rejects a URL with a path segment equal to one of the mentioned names.
This means I cannot have a route like this:
{controller}/{action}/{id}
... where id can be any string e.g.
Catalog/Product/Bin
So, instead of disabling this security measure I'm willing to change the route, using a suffix before the id, like these:
{controller}/{action}_{id} // e.g. Catalog/Product_Bin
{controller}/{action}/_{id} // e.g. Catalog/Product/_Bin
But these routes won't work if the id contains the new delimeter, _ in this case, e.g.
// These URL won't work (I get 404 response)
Catalog/Product_Bin_
Catalog/Product/_Bin_
Catalog/Product/__Bin
Why? I don't know, looks like a bug to me. How can I make these routes work, where id can be any string?
Ok, I have a definitive answer. Yes, this is a bug. However, at this point I regret to say we have no plans to fix it for a couple of reasons:
It's a breaking change and could be a very hard to notice one at that.
There's an easy workaround.
What you can do is change the URL to not have the underscore:
{controller}/{action}/_{id}
Then add a route constraint that requires that the ID parameter starts with an underscore character.
Then within your action method you trim off the underscore prefix from the id parameter. You could even write an action filter to do this for you if you liked. Sorry for the inconvenience.
You can use characters that are not allowed for a directory or file name like: *,?,:,",<,>,|.
With ASP.NET MVC if you look at the source they have a hard-coded value for the path separator (/) and to my knowledge cannot be changed.