Dot.NET Core Routing and Controller Processing discrepancy - asp.net-core

I am trying to use the asp-route- to build a query string that I am using to query the database.
I am confused on how the asp-route- works because I do not know how to specifically use the route that I created in my cshtml page. For example:
If I use the old school href parameter approach, I can then, inside my controller, use the specified Query to get the parameter and query my database, like this:
If I use this href:
#ulsin.custName
then, in the controller, I can use this:
HttpContext.Request.Query["ID"]
The above approach works and I am able to work with the parameter. However, if I use the htmlHelper approach, such as:
<a asp-controller="Report" asp-action="Client" asp-route-id="#ulsin.ID">#ulsin.custName</a>
How do I get that ID from the Controller? The href approach does not seem to work in this case.

According to the Anchor Tag Helper documentation, if the requested route parameter (id in your case) is not found in the route, it is added as a query parameter. Therefore, the following final link will be generated: /Report/Client?id=something. Notice that the query parameter is lowercase.
When you now try to access it in the controller as HttpContext.Request.Query["ID"], since HttpContext.Request.Query is a collection, indexing it would be case-sensitive, and so "ID" will not get you the query parameter "id". Instead of trying to resolve this manually, you can use a feature of the framework known as model binding, which will allow you to automatically and case-insensitively get the value of a query parameter.
Here is an example controller action that uses model binding to get the value of the query parameter id:
// When you add the id parameter, the framework's model binding feature will automatically populate it with the value of the query parameter 'id'.
// You can then use this parameter inside the method.
public IActionResult Client(int id)

Related

FromForm Swashbuckle and ModelBinder

I'm using JsonConverter for ID properties to convert them back and forth using hashids (when receiving request - from hashed string to int64, when sending response - from int64 to hashed string).
That all works flawlessly but I'm having now a problem with routes that receive Form Data. I tried using ModelBinder for ID properties but then swashbuckle generates that action with ID property outside request body, it defines it as a query parameter. Is there any other way to convert form data properties like JsonConverter is doing doing so for JSON?
Thanks
/edit: more info
I want swagger to generate schema like this where I use ModelBinder for Id property
Current:
Wanted:
Beside swagger schema, I want Id property to have ModelBinder (or if there's any other way) to have it convert it from string to int64 before it calls service to update user.
I have tried only ModelBinder for converting itself, as I'm not aware of anything else capable to do that, and for swagger scheme I tried applying IOperationFilter without success. I'm guessing I would have to alter scheme and remove Id Parameter and add it inside Request body instead?

Is there a named routes and default params equivalent for Razor Pages page 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
}
});

In Yii, is there a way to have urlFormat => path but still pass query params with an ampersand?

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.

How to use Global Property name in my JSON input request using SoapUI?

I have a SoapUI project which contains around 60 plus services. Each service requires some input which will be changed for every execution. So I have created certain Global Properties and assign some values to that properties.
I have to use these properties values in my SoapUI request ( i.e. JSON Format request ).
If it is groovy script means, I will use like this.
String HTiC_Username = com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils.globalProperties['HTiC_Username'].value;
But, how to get the value of the Global Property in the request?
Hope you understand my question. Please provide proper guidance.
Thanks
To dynamically "expand" (i.e. substitute) the value of a property into a test step, the following syntax is used: ${#scope#propertyName}
...where 'scope' refers to the level at which the property has been defined (e.g. Global, Project, TestSuite, TestCase).
So to expand a property named username defined as a Global property, for example, the following code can be used directly within a Request Test Step (e.g within a JSON body, or header value, etc):
${#Global#username}
To access the same property value within a Groovy Test Step, you can use the following syntax:
context.expand('${#scope#propertyName}')
...as in the following example:
context.expand('${#Global#username}')
What we did was the following:
created a test data file to store all the specific input data for the different services (testdata.properties)
Example content of testdata.properties:
Billing_customerID=1234567
OtherService_paymentid=12121212
....
create a SoupUi global parameter (File/Preferences/Global properties): testdata_filepath=C:\...
For specific services we added a Properties test step. You can specify the "Load from" field to our new global parameter: ${#Global#testdata_filepath} Now you can use the Load button to load parameters.
Finally you can reference the parameter in your xml in the following format: ${Properties#Billing_customerID}
Example content of a service with parameter:
...
<BillingCustomerIdentification>
<BillingCustomerID>${#Properties#Billing_customerID}</BillingCustomerID>
</BillingCustomerIdentification>
...
To set up your projects in this manner also helps to automate service tests eg. using Hudson (see my previous SO answer).
If it is too heavy and automation is not a target, you can simply use ${#Global#someinputvariable} format in your xml ;-)

How to enable dojox.data.JsonRestStore access struts2's action to retrieve data? I mean how to configure 'target' or others

I tend to use dojox.data.JsonRestStore as my grid's store, but I am always failed to access struts2 action, I am unfamiliar in REST, is it only can be used in servlet rather than struts2, etc.
Currently, My project is using struts2 + spring as backend skill and dojo as front-side skill, have you any ways for me to make dojox.data.JsonRestStore access a structs2 action class?
Thanks in advance.
to get the data, all you need is an HTTP GET that returns an array of JSON objects. The return value from the action must be a string with something like:
[
{
"penUser":"Micha Roon",
"submitTime":"12.03 13:20",
"state":"Eingang",
"FormNumber":"001001"
},
{
"penUser":"Micha Roon",
"submitTime":"12.03 13:20",
"state":"Eingang",
"FormNumber":"001001"
}
]
If you want to be able to update objects you have to have a method that reacts to PUT with the same URL as the one you used for GET and if you need to delete, DELETE will be used. The important part is that it must be the same URL.
In order to have JsonRestStore pass the ID in a GET parameter instead of appending it to the URL, you could specify the URL like so:
target:"services/jsonrest/formstore?formId="
When you call yourStore.get("123") the request will try to get http://yourserver:port/AppContext/services/jsonrest/formstore?formId=123
REST is nothing more than a convention.
You can use a RESTFull API like jersey.java.net in order to make your life easier and your URL more RESTFull.