Optional parameters in thymeleaf url - thymeleaf

I am generating a url in thymeleaf using the following code.
#{/schedule/data/bookableTimes/{teacherUsername}(teacherUsername=${teacher.user.username},lessonLengthType=${lessonLengthType},studentId=${#httpServletRequest.getParameter('studentId')})}
This works perfectly, when the studentId is supplied. However I also want to cater for the scenario when the studentId is not supplied.
Currently if the studentId is not supplied it will generate a url like so
/schedule/data/bookableTimes/teacher?lessonLengthType=full&studentId=
However this is not what I want, in the case that the studentId is null, I'd rather not have the studentId portion of the url generated at all. Is there a simple way to do this using thymeleaf?

I would create a string and concatenate some part something like
string url ="/schedule/data/bookableTimes/";
if (teacherUser) url.add(teacher)
if (studentId) url.add(studentId)
#{*url}

Related

URL and query string in Grails UrlMappings

After searching for a while, I'm still not able to do the following using Grails. I want match a variable with some part of URL plus the query string.
I have the following rule in UrlMappings:
"/myservice/$url**?"{
controller = "mycontroller"
action = "myaction"
}
With this, I'm able to grab the portion of the URL that want via params.url, except the query string.
In other words, I want to grab everything that comes after /myservice/ in a variable.
I know I can get the query string with request.queryString, but I would prefer the way I'm suggesting. Maybe this is not even possible...

QueryString with MVC 5 AttributeRouting in Web API 2

I have the following code
[HttpGet]
[Route("publish/{id}")]
public IHttpActionResult B(string id, string publishid=null) { ... }
So as far as I understood,
~/..../publish/1?publishid=12
~/..../publish?id=1&publishid=12
Should work and bind both parameters but it won't work on the second case.
In the first case, publishid will not be bound.
So I do not understand why this is not working. Any idea why it is in this way?
The second case will not work because id is a required variable in the route template publish/{id}. In Web API first route template matching happens and then the action selection process.
other cases:
publish/1 - will not work as action B is saying that publishid is required. To prevent this you can change the signature of action to be something like B(string id, string publishid=null) and only id is bound
publish/1?publishid=10 - works as expected where both are bound.

MVC - Query string and action parameter issue

I have an action method with the following signature,
ActionResult Search(string searchQuery)
This gets called from a partial view on button submit from a form. Problem is, please look at the 2 patterns below. When I submit my search key from my page it uses the following url (suppose search key is tool)
Search/?searchQuery=tool
But then if I click on a tool then,
Search/tool?searchQuery=garden
Now my method is reading tool in the parameter instead of garden (which is expected of course). I presume this is to do with incorrect presentation of items from both the context of the item itself and that of search.
Is there a nice way of resolving this issue? I want to read the query string term and search for it from the main search context i.e. Search/?searchQuery=<term> no matter where I am.
To get the QueryString, in your controller you should write something like this:
var mystring =Request.QueryString["searchQuery"];
This will get the query string no matter where is placed in your url.
Rename the input to
ActionResult Search(string searchQuery)
The model binder will then deserialize the query string param to that input value. It will work for both route params and query string params.

Nullable DateTime Parameter is never bound when calling the action

I have the following function signuture:
public JsonResult PopulateGrid(int page, Guid? accountId, Guid? systemUserId, Guid? branchId, DateTime? fromDate, DateTime? toDate, HomeVisitType? homeVisitType)
Every single parameter is bound just fine except toDate which turns out to be always null.
When inspecting the Request.QueryString["toDate"] it retrives the right value which is 30/09/2010.
It seems that DateTime expects another format when binding.
What is the right format?
A quick test on my system shows that it expects the data in MM/DD/YYYY and not DD/MM/YYYY which is probably why you're having problems. My guess is that if you try the same date on the fromDate you'll also have the same null issue.
I've changed the current culture in my app to one that uses the DD/MM/YYYY and it seemed to have no effect. Seems to have the same problem with the , decimal for a language that uses 10,01 instead of 10.01...
Update from someone a developer on the ASP.Net team.
"This is intentional. Anything that is part of the URI (note the 'Uniform' in URI) is interpreted as if it were coming from the invariant culture. This is so that a user in the U.S. who copies a link and sends it over IM to a friend in the U.K. can be confident that his friend will see the exact same page (as opposed to an HTTP 500 due to a DateTime conversion error, for example). In general, dates passed in RouteData or QueryString should be in the format yyyy-mm-dd so as to be unambiguous across cultures.
If you need to interpret a QueryString or RouteData parameter in a culture-aware manner, pull it in as a string, then convert it to the desired type manually, passing in the desired culture. (DateTime.Parse has overloads that allow you to specify a culture.) If you do this, I recommend also taking the desired culture as a QueryString or a RouteData parameter so that the 'Uniform' part of URI isn't lost, e.g. the URL will look something like ...?culture=fr-fr&date=01-10-1990."

ASP.NET MVC POST Parameters in the url

url : /jobs/UpdateJobResults/GUIDHERE
When I do a post to the below function the guid id is always blank, can I use the above format to POST the GUID in the url (as the form body has the results dictionary) ?
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateJobResults(Guid Id, Dictionary<string, object> results)
{
}
You can try revising your Html.BeginForm by passing this as a route value...
Html.BeginForm("myAction", "myController", new { Id = myGuid });
Obviously where myGuid is your param.
If your routing is setup correctly, MVC will know to post your form with this value in the URL (and/or querystring) rather than in the Request.Form data...
Good luck!
I believe that MVC uses Convert.ChangeType for conversions. This method does not support Guids. My recommendation would be to change the parameter to a string and convert it in the method.
Yes, the 3rd parameter of the default route is id. In most of the examples that is an integer, but a Guid should work.
Did you try it with the id parameter as a string instead of a Guid? Normally MVC is smart enough to give you the type of object you're looking for, but I haven't tried it with a Guid. Expecting id to be a string might work. Then at least you'd know your routing was working.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateJobResults(string id, Dictionary<string, object> results)
{
}
Are you using the default route or have you set up your own routes?
Edit: So, you're using your own routes. Please edit your question to include those. Also, you say it works for the GET, but not for the POST. What does your action look like that is hit with the GET request? I think we're going to need more information in order to help with this one. Are you sure the client requests contain the Guid in the url?
ended up being the model binder created was looking in the form for the guid on the post rather than the query string

Resources