Using Request.Url.AbsoluteUri to construct a breadcrumb link - asp.net

Inside my _layout view I have added the following link , to refresh the current page as part my breadcrumb bar:
#(aoutput == "Index" ? "Home" : aoutput)
The above is working well on my development environment , but I am not sure If using the Request.Url.AbsoulteUri is the correct way to reference the current page URL ?

AbsoluteUri includes the scheme (such as http), the host, the port, the path, query string data and the fragment. As far as I know the fragment will not be included in the current URL because it is not sent with the request (that is, it's handled by the browser client-side).
This should be fine to use and is unlikely to cause you issues. Just be aware that query string data is included, which means that if you had a (poorly-designed) data manipulation system such as /Users/Index?action=deleteMostRecentUser then the user might accidently delete users because the URI would include the action.
Alternatives are
Absolute Path: /Home/Index
Path & Query: /Home/Index?query=keyword

You can use it as you mentioned.
Better way you make a separate partial view to implement breadcrumb.
And pass wanted model from Controller side. (Or in ViewBag)
The main benefit is you'll get is better control over Logic also flexible for future changes.
Hope helps.

Related

jquery mobile 1.4.5 single-page template href querystring ajax

I am a newbie to JQM (I use 1.4.5) and my webapp (asp.net C# apache Cordova) contains many separate pages of .cshtml (single-page template) only. I am testing my webapp on a Samsung Galaxy Grand using Android 4.2.2
A.
I am not sure about my understanding of 'linking pages', even after reading all the JQM docs on this and also after reading up many, many posts on this topic about passing querystring values to another page; mainly because I find that ALMOST ALL the examples are directed towards providing answers for internal pages (Multi-Page template) within a single html page.
So I request some of you JQM experts to confirm or correct the following understanding of mine....
From the JQM docs I understood that
I could use in any link (e.g button), href="page2.cshtml?par1=1&par2=2"; and JQM will automatically use Ajax for this link to work.
I also understood that use of querystring is always allowed in such cases of different html pages of the same domain and it will work via Ajax automatically ; so long as the attr such as rel="external", data-ajax="false" etc. are not used in the same link.
but querystrings are not allowed in case of the internal pages (multi-page template) only....;
and if I need to use the above href to link to a page in another domain e.g. www.anotherdomain.com/page2.cshtml?par1=1&par2=2, then I need to use rel="external".
Are all my above points (that reflect my understanding) CORRECT? KIndly confirm ro please correct me ...
B.
In my app, I find that most of the links work according to my understanding as above, to connect to different pages in the same domain; and I assume it happens via Ajax. Is it correct? I am also able to use the querystring params in page2 ( i.e. To-Page).
But in one case, though it works, in the To-Page the Panel features do not operate correctly, unless I introduce rel="external' in the href link !!! I suppose it means it IS NOT AJAX anymore? Also I am unable to find the reason..
Further independent of the above topic, I face another issue. The loading time (i.e. Time taken to display the To-Page) varies.
Mostly it is OK, but at times the loading-circle goes on forever.... and I presume it has crashed....??? then If I go back using the back button and come forward again, many times it loads immediately...!!!!!
Any thoughts or suggestions.....?
Thanks in anticipation...
Ratna
Before you can worry about how to pass attributes from one page to another you need to understand the difference between multi-page and multi-HTML templates.
Multi HTML page template
Smaller and lighter, each data-role=”page” is inside a separate HTML file and page structure is much more modular.
Can become even smaller if every subsequent HTML page is stripped from HEAD content, or anything that isn’t data-role=”page” div. Unfortunately in this case fallback if JavaScript is not supported is out of question.
DOM size is relatively small, only first page is permanently loaded into the DOM, any other page will also be loaded into the DOM but at the same time it will also be removed when not used actively, basically each time you move from it.
Better fallback if JavaScript is not supported. Works great in desktop browsers after a page refresh, mainly because every HTML page has an existing HEAD content. This also allows your app to behave like normal web app mainly because AJAX can be turned off.
Multipage template
Since all pages are already loaded, no additional requests are generated for navigating between pages.
First load is slower as the file size is larger, but subsequent page navigation is fast, thus making transitions much more smooth. Almost native-like smooth, emphasize on almost.
Suitable for relatively smaller applications and situations where you know the capabilities of your target platforms including presence of JavaScript support, thus making it a great solution for a hybrid app. It works much better as a Phonegap app then multi HTML template.
The “page” data-role element is required.
More about this topic can be found here: Multipage template vs Multi HTML template in jQuery Mobile
Now let's talk about how to properly pass data between jQuery Mobile pages.
jQuery Mobile uses AJAX by default
You can turn off AJAX using rel="external"
If you turn off AJAX you will lose almost everything good about jQuery Mobile, including animations. So if you don't want AJAX page handling better find some other responsive framework like Bootstrap or Foundation.
If you don't want to use AJAX you can still use querystrings but inside a href or via changePage function.
Better querystrings alternatives:
Global object.
If you're using AJAX you can simply use a global object(s) to store all of your data.
Something like this:
// Store object
var storeObject = {
parameter1: null,
parameter2 : null
}
Access data from the previous page
Again if you're using AJAX you don't need to pass any data because all that data is till in the DOM.
// Store object
$(document).on('pagebeforeshow', '#second', function(e, data){
alert("My name is " + data.prevPage.find('#test-input').val());
});
Localstorage or Sessionstorage
This solution will work no matter if you use AJAX or not.
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#change-page-button', function(){
// store some data
if(typeof(Storage)!=="undefined") {
localStorage.firstname="Dragan";
localStorage.lastname="Gaic";
}
// Change page
$.mobile.changePage("#second");
});
});
$(document).on('pagebeforeshow', '#second', function(){
alert('My name is ' + localStorage.firstname + ' ' + localStorage.lastname);
// Lets change localStorage data before we go to the next page
localStorage.firstname="NewFirstNeme";
localStorage.lastname="NewLastName";
});
$(document).on('pagebeforeshow', '#third', function(){
alert('My name is ' + localStorage.firstname + ' ' + localStorage.lastname);
});
Send data through changePage function or via href
// Send
$.mobile.changePage('page2.html', { dataUrl : "page2.html?paremeter=123", data : { 'paremeter' : '123' }, reloadPage : true, changeHash : true});
or
Send parameter
receive that same data:
$(document).on('pagebeforeshow', "#index", function (event, data) {
var parameters = $(this).data("url").split("?")[1];;
parameter = parameters.replace("parameter=","");
alert(parameter);
});
If you need more information about this solutions including working examples find them here: Passing data between jQuery Mobile pages
Several methods mentioned here are deprecated (still usable) in the version 1.4. Though you don't need to worry about that, almost everything here will be unusable in version 1.5. This new version will overhaul jQuery Mobile from the bottom to the top.
Update
Yes, you can use any such link and jQuery Mobile will use AJAX. If you take a look at my previous examples you will find a working one.
If you want AJAX you CAN'T use rel="external", data-ajax="false" though stringquerys will work in bot cases.
Correct they will only work in multi-HTML template. Though there used to be a 3rd party plugin that allowed this to work with multi-page template but I don't think it works with newer jQuery Mobile versions.
Correct, if you want to link external page you need to use rel="external".

Using a dynamic stylesheet with CodeIgniter

I have a dynamic PHP stylesheet, but I can't find a way to send variables to it so I used sessions instead. Figured this kinda sucked, so I'm going to give it another try but could need some help. It's an external stylesheet where a variable has effect through the whole document.
You probably want to use an embedded stylesheet (a <style> block) in the page: it increases the size of the main page, but solves the variable access issue without needing sessions and reduces your number of requests. You can just load your dynamic stylesheet into the main page's view using load->view.
EDIT: Ah, massive amounts of CSS would be one problem. Well, two alternatives are to:
Turn on the $_GET support in your CI install, you COULD pass in a request parameter in the CSS link and then check for the request parameter in the PHP controller or view file that generates the actual CSS. Not visually the tidiest option, but it does work.
Put in a cookie that you check in the controller that gets called for the CSS: you can then check that in the controller or view and do the right thing. Visually much tidier than the request parameter option, but a bit more involved.

Should I replace string patterns in asp.net mvc using a custom viewengine?

Have an ASP.NET MVC site that is localized. The localization functionality adds the two digit language ID to the URL, e.g. /es/Page. If no language Id is found in the URL, the site switches to the user's browser culture. All's good. However, the site's hyperlinks, a mixture of hard-coded href tags, actionlinks, etc., don't include the base language ID, so when clicking through the site the set culture is lost, and the site reverts to the user's browser culture.
My (lazy) thought is to replace all href values, that don't point to an external site, with the localized URL (e.g. include the /es/). Otherwise, all site links will need to be updated to include the culture code.
Is this just plain dumb? Or, reasonable, and should be done using a custom view engine, or some other approach?
My answer is (currently):
The app has a base controller, there I've added:
if (PathLanguageCode == "" && requestContext.HttpContext.Session["LanguageCode"] != null && requestContext.HttpContext.Request.RequestType == "GET")
{
requestContext.HttpContext.Response.Redirect("/" + requestContext.HttpContext.Session["LanguageCode"] + requestContext.HttpContext.Request.RawUrl);
}
This example doesn't show how the PathLanguageCode variable is defined, but it should at least suffice to show how this can be handled centrally, without replacing string values.
The one downside to this approach, that I can see, is that the site really isn't friendly for search engines, etc., since we end up doing a lot of redirects.
If you would like you can look at my approach that we took. It talks about putting the culture in the URL. Hope it helps!
Cultured View Engine for MVC

Problem passing parameters via Iframe in IE

I'm trying to execute an HTTP GET from my website to another website that is brought in via iframe.
On Firefox, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it works.
On IE, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it doesn't work...
Is there something about IE that doesn't let you pass parameters through an iframe in the querystring?
I've tried refreshing the iframe in IE, I've tried refreshing my page & the iframe in IE, and I've tried copying the url and re-pasting it into the iframe src (forcing it to refresh as if I just entered it into the address bar for that iframe window). Still no luck!
Anyone know why this is happening, or have any suggestions to try to get around this?
Edit: I cannot give a link to this because the site requires a password and login credentials to both our site and our vendor's site. Even though I could make a test account on our site, it would not do any good for the testing process because I cannot do the same for the vendor site. As for the code, all it's doing is creating the src from the backend code on page load and setting the src attribute from the back end...
//Backend code to set src
mainIframe.Attributes["src"] = srcWeJustCreated;
//Front end iframe code
<iframe id="mainIframe" runat="server" />
Edit: Problem was never solved. Answer auto accepted because the bounty expired. I will re-ask this question with more info and a link to the page when our site is closer to going live.
Thanks,
Matt
By the default security settings in IE query parameters are blocked in Iframes. On the security tab under internet options set your security level to low. If this fixes your problem then you know that is your issue. If the site is for external customers then expecting them to turn down their security settings is probably unreasonable, so you may have to find a work around.
Let's say your site is www.acme.com and the iframe source is at www.myvendor.com.
IIRC, most domain-level security settings don't care about the hostname, so add a DNS CNAME to your zone file for myvendor.acme.com, pointed back to www.myvendor.com. Then, in your IFRAME, set the source using your hostname alias.
Another solution might be to have your Javascript set the src to a redirector script on your own server (and, thus, within your domain). Your script would then simply redirect the IFRAME to the "correct" URL with the same parameters.
If it suits you, you can communicate between sites with fragment identifiers. You can find an article here: http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html
What BYK said. I think what's happening is you are GETting a URL that is too large for IE to handle. I notice you are trying to send variable named src, which is probably very long, over 4k. I ran into this problem before, and this was my code. Notice the comment about IE. Also notice it causes a problem with Firefox then, which is addressed in another comment.
var autoSaveFrame = window.frames['autosave'];
// try to create a temp form object to submit via post, as sending the browser to a very very long URL causes problems for the server and in IE with GET requests.
var host = document.location.host;
var protocol = document.location.protocol;
// Create a form
var f = autoSaveFrame.document.createElement("form");
// Add it to the document body
autoSaveFrame.document.body.appendChild(f);
// Add action and method attributes
f.action = protocol + '//' + host + "/autosave.php"; // firefox requires a COMPLETE url for some reason! Less a cryptic error results!
f.method = "POST"
var postInput = autoSaveFrame.document.createElement('input');
postInput.type = 'text'
postInput.name = 'post';
postInput.value = post;
f.appendChild(postInput);
//alert(f.elements['post'].value.length);
// Call the form's submit method
f.submit();
Based on Mike's answer, the easiest solution in your case would be to use "parameter hiding" to convert all GET parameters into a single URL.
The most scalable way would be for each 'folder' in the URL to consist of the parameter, then a comma, then the value. For example you would use these URLs in your app:
http://example.com/app/param,value/otherparam,othervalue
http://example.com/app/param,value/thirdparam,value3
Which would be the equivalent of these:
http://example.com/app?param=value&otherparam=othervalue
http://example.com/app?param=value&thirdparam=value3
This is pretty easy on Apache with .htaccess, but it looks like you're using IIS so I'll leave it up to you to research the exact implementation.
EDIT: just came back to this and realised it wouldn't be possible for you to implement the above on a different domain if you don't own it :p However, you can do it server-side like this:
Set up the above parameter-hiding on your own server as a special script (might not be necessary if IE doesn't mind GET from the same server).
In Javascript, build the static-looking URL from the various parameters.
Have the script on your server use the parameters and read the external URL and output it, i.e. get the content server-side. This question may help you with that.
So your iframe URL would be:
http://yoursite.com/app/param,value/otherparam,othervalue
And that page would read and display the URL:
http://externalsite.com/app?param=value&otherparam=othervalue
Try using an indirect method. Create a FORM. Set its action parameter to the base url you want to navigate. Set its method to POST. Set its target to your iframe and then create the necessary parameters as hidden inputs. Finally, submit the form. It should work since it works with POST.

Export ASPX to HTML

We're building a CMS. The site will be built and managed by the users in aspx pages, but we would like to create a static site of HTML's.
The way we're doing it now is with code I found here that overloads the Render method in the Aspx Page and writes the HTML string to a file. This works fine for a single page, but the thing with our CMS is that we want to automatically create a few HTML pages for a site right from the start, even before the creator has edited anything in the system.
Does anyone know of any way to do this?
I seem to have found the solution for my problemby using the Server.Ecxcute method.
I found an article that demonstared the use of it:
TextWriter textWriter = new StringWriter();
Server.Execute("myOtherPage.aspx", textWriter);
Then I do a few maniulatons on the textWriter, and insert it into an html file. Et voila! It works!
Calling the Render method is still pretty simple. Just create an instance of your page, create a stub WebContext along with the WebRequest object, and call the Render method of the page. You are then free to do whatever you want with the results.
Alternatively, write a little curl or wget script to download and store whichever pages you want to make static.
You could use wget (a command line tool) to recursively query each page and save them to html files. It would update all necessary links in the resulting html to reference .html files instead of .aspx. This way, you can code all your site as if you were using server-generated pages (easier to test), and then convert it to static pages.
If you need static HTML for performance reasons only, my preference would be to use ASP.Net output caching.
I recommend you do this a very simple way and don't do it in code. It will allow your CMS code to do what the CMS code should do and will keep it as simple as possible.
Use a product such as HTTrack. It calls itself a "website copier". It crawls a site and creates html output. It is fast and free. You can just have it run at whatever frequency you think is best.
It decouples your HTML output needs from your CMS design and implementation. It reduces complexity and gives you some flexibility in how you output the HTML without introducing failure points in your CMS code.
#ckarras: I would rather not use an external tool, because I want the HTML pages to be created programmatically and not manually.
#jttraino: I don't have a time interval in which the site needs to be outputted- the uotput has to occur when a user creates a new site.
#Frank Krueger: I don't really understand how to create an instance of my page using WebContext and WebRequest.
I searched for "wget" in searchdotnet, and got to a post about a .net class called WebClient. It seems to do what I want if I use the DownloadString() method - gets a string from a specific url. The problem is that because our CMS needs to be logged in to, when the method tries to reach the page it's thrown to the login page, and therefore returns the login.aspx HTML...
Any thoughts as to how I can continue from here?

Resources