How to check route parameter exists in layout page asp.net MVC - asp.net-mvc

I have 2 parameters in url id & text. I am trying to check whether 'text' exists in layout page because initially I will have only Id and later I am addding 'text' to url from different action but same controller.
I have following code in my layout page but it works only when both parameters are available.
var Newid,Newtext;
Newid = ViewContext.RouteData.Values["id"];
Newtext = ViewContext.RouteData.Values["text"].ToString();
I am trying to check when my url is localhost:8122/products/12
#
{
if(ViewContext.RouteData.Values["text"].ToString()!=null)
{
}
}
but it gives object reference error.
I have to include .tostring() since I am checking like below in the same page
#if (Newtext =="t") {}

Related

How do I pass an id to a link when using the method call syntax in a tagLib?

I've got a tag definition:
def myCustomLink = { attrs, body ->
def url = complexUrl(attrs.whatever)
def linkAttrs = [url: url, class:'css-class', id: 'actual-id']
out << g.link(linkAttrs, body() ?: "Book a service")
}
I'd expect id="actual-id" in the HTML element to turn up in the output, but this isn't the case.
It's quite confusing for beginners (sometimes) between id & elementId used in g:link Taglib.
The id attribute in various Taglibs like g:form, g:link, g:textField etc. is not for the id attribute of any HTML tag, instead this is the Identity or id field referencing a domain class. So if you use id in any of those taglibs, it's gonna be used in /$controller/$action/$id URL mapping (the default mapping).
So ultimately, to generate <a> tag with id attribute, you need to use elementId instead (as you already answered).
http://docs.grails.org/3.2.9/ref/Tags/link.html
elementId (optional) - this value will be used to populate the id attribute of the generated href
Map linkAttrs = [url: url, class: 'css-class', elementId: 'actual-id']
The answer is, (for anyone else who has this issue):
// Use the elementId attribute to pass an id for the anchor tag itself.
def linkAttrs = [url: url, class:'css-class', elementId: 'actual-id']
Found in the source code for ApplicationTagLib https://searchcode.com/codesearch/view/72308377/
This is because the id attribute (and all other attributes) are used in the link href itself.

Reconstructing a Razor URL using referring URL and language selection

To implement language selection in an MVC Razor application, I use a leading path segment in the route mapping like www.mydomain.com/lang/controller/action/id?param= where lang is a 2 letter ISO country code like fr, de, it, en etc
I use the following route mapping (which works fine):
// Special localisation route mapping - expects specific language/culture code as first param
routes.MapRoute(
name: "Localisation",
url: "{lang}/{controller}/{action}/{id}",
defaults: new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { lang = #"[a-z]{2}|[a-z]{2}-[a-zA-Z]{2}" }
);
Previously I generated my language selection links in the master page, so that they were simply variations of the current URL (with only the first segment changed). Now I need to be able to create the links from within a partial view, that may be loaded dynamically via Ajax and the menu items (countries) are data driven.
That means I need to take the referring URL instead (the actual loaded page) and modify it to have a new language inserted, for each available language. The menu items are all database driven, so only contain the 2 letter language code and the display name.
Googling for "how to separate a URL into controller and action" I found an interesting link here: http://average-joe.info/url-to-route-data/
Based on that link, this is what I tried, but it blows up on a root URL like http://localhost:51176/ or with a full URL like http://localhost:51176/en/home/index. I would have expected it to return the defaults of home (controller) and index (action). Instead I get a Null reference exception.
string path = Request.UrlReferrer.ToString();
string queryString = ""; // Blank for now
System.Web.Routing.RouteData routeFromUrl = System.Web.Routing.RouteTable.Routes.GetRouteData(new HttpContextWrapper(new HttpContext(new HttpRequest(null, new UriBuilder(Request.Url.Scheme, Request.Url.Host, Request.Url.Port, path).ToString(), queryString), new HttpResponse(new System.IO.StringWriter()))));
// Blows up with Null exception as routeFromUrl is always null
string controller = (string)routeFromUrl.Values["controller"];
string action = (string)routeFromUrl.Values["action"];
string id = (string)routeFromUrl.Values["id"];
The idea being I can then generate links with href values like these using the referrers controller, action and parameters and therefore stay on the "same page" (except for the obvious language change):
http://localhost:51176/en/home/index
http://localhost:51176/de/home/index
http://localhost:51176/fr/home/index
What is wrong with the way I have used that piece of code (or does it just not work as I expected)?
Do'h... so simple.
Just needed to supply the path part of the URL only as it uses the current scheme, host & port applied to that path.
string path = Request.UrlReferrer.AbsolutePath;
Also note (valuable tip):
If you follow that example I linked, like I did, you need to adjust the following to use ToString() as they do not cast to string when empty:
string controller = routeFromUrl.Values["controller"].ToString();
string action = routeFromUrl.Values["action"].ToString();
string id = routeFromUrl.Values["id"].ToString();
This will give controller="home", action="index" and id="" as expected! Phew

MVC routing changes url hash when requesting partial view via AJAX

I'm using AJAX calls to request partial views and load their html into a content area on my main Index view. I'm leveraging a hash in to the url to enable browser history support (the same way GMail url browser history works).
Everything is working fine, except after my partial view is returned and loaded, MVC seems to be clearing everything after my url hash symbol which affects the javascript browser history stack.
I have a link on my main view which initiates the request:
<div class="linkButton" data-bind="click:function(){Nav.makeRequest('#/MyController/Profile/2')}">Profile</div>
Here's the javascript that I'm using to request and load the partial views:
var Nav:function(){
var self = this;
$(window).bind("hashchange", self.onHashChange);
makeRequest: function(hash){
window.location.hash = hash;
};
onHashChange: function (e) {
var hash = window.location.hash.substring(1);
var url = 'http://localhost:3333/' + hash.substring(1);
$.get(url, function (data) {
$('#content').html(data);
});
}
}
So, one of my example requests would be for: http://localhost:3333/#/MyController/Profile/2
The request is completed successfully and my Profile view is loaded with the correct model for the id (2) passed to it in the routing and the url in the browser's navigation is what is shown above.
However after the view finishes loading, the browser's url then automatically changes to this: http://localhost:3333/#
This doesn't affect what's currently loaded on the page, but it adds this new url to the browser's history so when I hit the 'back' button it sends the request for the partial profile view again.
The only route I have in my Global.axax is the following:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "MyController", action = "Index", id = UrlParameter.Optional }
);
I suspect that the MVC routing engine sees my request for the partial view come in (http://localhost:3333/MyController/Profile/2) and then matches it to the Default route which returns the url for my Index view, which of course is: http://localhost:3333/
I have debugged extensively on the client and the onHashChange event does indeed fire both times, once for the partial view request and then again when the url changes back to localhost:3333/# The call stack doesn't reveal any calls being made client side to cause the url to change back.
Is there a way that I can request and load my partial view using AJAX, and hashes for history support, and have the browser's url not automatically route back to the default route path?
This must what you searching for:
To manipulation with browser history you need to use new method with Html5 support
//use it in ur ajax function to save history
history.pushState({page: 1}, "title 1", "?page=1");
//and to get ur history
window.onpopstate = function(event) {
something like
$.post('url',{page:event}function(event) {
do something
})
}

Grails "loses" custom URL mapping when following any links on the page

I have an application where users can browse maps in two ways (like thumbnails and in a list)
/map/browse
/map/list
Now, I would like to restrict these views to just show maps of a specific user, for example through
/user/3/browse
/user/3/list
So I created the mapping:
"/user/$userId/browse" {
controller = "map"
action = "browse"
}
"/user/$userId/list" {
controller = "map"
action = "list"
}
Now, I can go to /user/3/browse, but as soon as I click on a pagination link or change the pagination filters, the URL goes back to /map/browse.
Also, if I set the userId to null in the controller, I get the error:
Error 500: Error processing GroovyPageView: Error executing tag : Unable to create URL for mapping [/user/(*)/list] and parameters [["action":"list", "controller":"map", "max":20, "offset":0, "sort":"uploadDate", "order":"desc", "userId":null, "totalMaps":30]]. Parameter [userId] is required, but was not specified! at /views/map/browse.gsp:26
The pagination works as follows:
<div class="paginateButtons">
<g:paginate controller="map" action="browse" total="${mapInstanceTotal}"></g:paginate>
</div>
What can I do against that or what would be the correct way of implementing what I want?
I don't necessarily need to have that URL mapping, I only need a nice way of saying: "Display maps of only one user"
It seems that the problem is not at your URL mapping configuration ,but in your way to create link. I think it's better if you use Named URL Mapping : it's clearer than your approach now, and when create link for pagination you only need to specify the url name. For example:
In UrlMappings.groovy:
static mappings = {
name accountDetails: "/details/$acctNumber" {
controller = 'product'
action = 'accountDetails'
}
}
In view - gsp page:
<g:link mapping="accountDetails" params="[acctNumber:'8675309']">
Show Account
</g:link>

JSF Link Parameter get null

I have a page with link http://localhost:8080/Test/Page.faces?id=asdasdasd
The page got 2 text field and one button, after user key in the details and click submit, it works well when you first time click the submit button, the id will return me the exact value, but if the user never enter the value and click submit the validation will be invoked and next click the button again the id return null? How to solve this problem anyone can help?
Yes, when the user clicks on the button, the browser does a new request to the server. That new request doesn't have the ?id=asdasdasd as part of it. The easiest solution I can think of is to store that value into a hidden text field on the page. You can use some javascript to populate the value.
So, if you have a <h:hidden id="idHidden" value="#{mybean.idHidden}"/> on your JSP, maybe some javascript like this:
<script type='text/javascript'>
function gup( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
if(gup('id') != "") {
document.forms[0].idHidden.value = gup('id');
}
</script>
I haven't checked this code for errors, but the idea is the first time the page loads, the value of 'id' is stored in a hidden input field. That field is bound to your managed bean so the value is persisted across page refreshes. Just reference the id value stored on the bean (as idHidden in the example above) instead of the request parameter.
BTW: I stole the GUP function from http://www.netlobo.com/url_query_string_javascript.html
Nick

Resources