I would like to create friendly routes that map to different query string values of a single Razor Page and it's base GET handler. I'd be fine with switching the query string to being a part of the route as well. The idea is we have a single page that loads a file list and can filter. I'd prefer it if the URL was more straight forward. If it's not possible I could just go with /Files/In or /Files/Out
Example
/Files?direction=In -> /In
/Files?direction=Out -> /Out
Is there any way to do something like this?
You can use route data parameters which are defined in a Route Template as part of the #page directive in the .cshtml file :
#page "{direction?}"
Then you can access the route parameter value in OnGet method of your file page :
public void OnGet(string direction)
{
if (!string.IsNullOrEmpty(direction))
{
//filter files based on direction
}
}
You can pass direction value as /Files/In or /Files/Out , without filter directly use /Files .
Related
I have these URLs:
/entity/create
/entity/edit/6
And I want to limit my Razor Page to these two URLs.
I created this route, using #page directive:
#page "/companyInfo/{action}/{id?}";
And it works. But the problem is that it accepts all kind of values for {action} and {id?} segments.
I want to apply these limitations on this route:
{actions} should only take one of the create or edit values
{id} should not exist in create and should exist for edit.
In other words, I want to bind my Razor Page form, to two modes of creation and edition.
What should I do?
Create a page called Crud in your CompanyInfo folder and add a route template to the #page directive with a leading / so that it overrides the default route template:
#page "/CompanyInfo/Create"
Then use AddPageRoute in Startup to define an extra route template for the page:
services.AddRazorPages().AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/CompanyInfo/Crud", "/CompanyInfo/Edit/{id:int}");
});
Ref: https://www.learnrazorpages.com/razor-pages/routing#friendly-routes
I have a JobPosts/Index page with multiple GET parameter bindings to allow filtering: let's take CityId and IsRemote for example. I don't want these to be passed as query string parameters, instead I want to use friendly routes for them. So I have defined these:
options.Conventions.AddPageRoute("/JobPosts/Index", "cities/{cityId}/jobs");
options.Conventions.AddPageRoute("/JobPosts/Index", "remote-jobs");
options.Conventions.AddPageRoute("/JobPosts/Index", "jobs");
The routes work just fine when I type them in the browser and the CityId one is bound properly, but two things are missing.
First, there is no way to specify a default value for my IsRemote param, which I want to set to true ONLY when using the remote-jobs URL.
And second, when trying to generate a URL like this:
<a asp-area="" asp-page="/JobPosts/Index" asp-route-cityId="#Model.CityId"></a>
I get the following URL:
https://localhost:44391/jobs?cityId=2265885
When what I actually expect is:
https://localhost:44391/cities/2265885/jobs
So it looks like the tag helper or the part responsible for constructing the URL doesn't look at all at the different routes to try and get a best match based on the list of parameters. Actually, it will always use the last page route defined for that page.
Nor do I have the option anywhere to specify a route name for the page route and then use asp-route to explicitly say which route I want.
Any ideas how to achieve that? Or if it's something that's on the roadmap for Razor Pages?
EDIT: Hardcoding the href is not an option. I want this to go through the proper routing services as there are other things to be done as well, like generating culture-specific URL for non-english users (eg. {cultureId}/cities/{cityId}/jobs - this is done through route conventions. Hardcoding the href would obviously bypass that.
There is a easy way to set IsRemote default value.
public bool IsRemote { get; set; } = true;
This tag asp-page will link to Page /JobPosts/Index.csthml directly,
https://localhost:44391/JobPosts?cityId=2265885
= https://localhost:44391/JobPosts/Index?cityId=2265885
If you are looking forward the URL https://localhost:44391/jobs?cityId=2265885
you could try this a tag to request.
Go to JobPosts
———————————————————————————————
Using a middleware to handle /remote-jobs
app.Run(next => async context =>
{
if (context.Request.Path == "/remote-jobs")
{
return View with default IsRemote
}
});
Microsoft has a good tutorial for getting your first ASP.NET Web API project going:
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
...but what's unclear to me -- how is the mapping between the API URIs and my C# controller methods defined?
for ex:
/api/products/{id}
resolves to
public IHttpActionResult GetProduct(int id)
{
[...]
}
...but im not sure how. automagic?
I ask because I want to create a new mapping for this URI:
/api/setReportNotificationsAsRead?uid={username}&items={itemIDs}
to this new method in my controller:
public IHttpActionResult SetReportNotificationsAsRead(string username, string itemIDs)
{
[...]
}
...but im not sure how. automagic?
The Automagic lies with HTTP Verbs in Web API. The route /api/products/{id} can map to anything that starts with GET (or just method name Get) if you make a GET request for the WebAPI.
If you make a POST request then it will map to any POST method (or else is you use route prefix).
This link can help you understand the magic. That can also help you understanding how you can configure SetReportNotificationsAsRead function to be called.
You're very close to having a working solution. You have your method parameter names mixed up:
public IHttpActionResult SetReportNotificationsAsRead(string uid, string items)
{
//Do your stuff!
}
The name of the HTTP GET parameter should match the name of the method parameter. This is part of the ASP.NET MVC naming convention.
One final note, if you are actually expecting a group of items (i.e. multiple item ids) you can actually save yourself some work and use a string[] parameter so long as your HTTP parameters are sent correctly. In this case you would want the URI to look like: /api/setReportNotificationsAsRead?items=123&items=456&items=789. Notice how the parameter name is repeated multiple times, but with different values.
For more information about the routing system I would suggest heading over to the ASP.NET MVC routing overview.
I would like my links to be full absolute paths to the resource being linked without me having to hard code the scheme and URI to the resource. I wish to do this in relation to using itemprop='url' on links to have the full url appear in the href attribute.
There are several approaches. The first one I would suggest is a basic helper function passed to jade during the rendering. Perhaps bound to the current request:
In your express code:
function absolute(req, url) {
//you'll need more logic here, but this is the concept
return req.originalUrl + url;
}
res.render("somePage", {absolute: absolute.bind(null, req)});
In your jade markup:
a(itemprop=url, href=absolute(url))
//- This is assuming "url" is a variable with a string like "/cars/42"
Currently (in Yii 1.1.13) all createUrl methods put extra params in the 'path style', which means I cannot then override them by submitting a form, because they take precedence over those that come in a query string. Is there a way to always pass extra parameters in query string but still have the url look normal and not butt-ugly like with the get urlFormat?
You can set appendParams to false in your urlManager component configuration.