Better/efficient way to check users url input? - c#

I know there are other ways of checks and questions like this but still trying to debug my piece of code. It checks if user entered the url without "http://"
//page is a global variable, a string in this case
//loadPage(string url) loads the requested page;
private void checkIfUrlRight(string s)
{
if (!s.StartsWith("http://"))
{
if (!s.Contains("www."))
{
s += "http://www.";
page = s;
}
else
{
s += "http://";
page = s;
}
urlRTextBox.Text = page;
loadPage(page);
}
else
page = s;
urlRTextBox.Text = page;
loadPage(page);
}
I get an error when loading a page, it says that Url is wrong. Will actually my code make any sense or shall I just switch to complicated stuff like regex (looked through the web, looks harsh, don't where to start) or playing around with c# Uri class? Any suggestions?
Thanks in advance.

There is a method in the Uri class that validates certain uri, you can use it as follows:
void checkIfUrlRight(string s)
{
if (Uri.IsWellFormedUriString(s, UriKind.RelativeOrAbsolute))
{
urlRTextBox.Text = page;
loadPage(page);
}
}
EDIT:
Note that actually not every URI is URL (described here). But I believe for your case (when all URLs are URIs) it is the simplest way to validate.

Related

Variable cannot be accessed below a certain point in the code

I have a small problem with a piece of code I cannot seem to work out what the issue is, I never wrote this initial part of the code which is why I don't understand the problem.
Code:
public async Task GetEnumerableLinksAsync(string entryPointUrl)
{
Uri baseUrl = new Uri(entryPointUrl);
await foreach (Uri url in GetEnumerableLinksAsync(baseUrl, 1000))
ListBoxMain.Items.Add(url);
// TEST
string[] threads = File.ReadAllLines(#"logic\markers.txt");
if (threads.Any(url.Contains)) {
}
// TEST
}
The problem is here if (threads.Any(url.Contains)) { I cannot access the url variable.
ListBoxMain.Items.Add(url); the listbox can access it fine, but any code below this and I get the name `url` does not exist in the current context
Can anyone see the issue at all? any help is appreciated.
The code you have written looks correct because of indentation, but C# ignores any formatting.
This is your code formatted properly:
await foreach (Uri url in GetEnumerableLinksAsync(baseUrl, 1000))
ListBoxMain.Items.Add(url);
// TEST
string[] threads = File.ReadAllLines(#"logic\markers.txt");
if (threads.Any(url.Contains)) {
}
// TEST
Can you see the why url doesn't exist after the foreach now?
You need to add a 'scope' to the foreach to allow url to exist beyond the first line:
await foreach (Uri url in GetEnumerableLinksAsync(baseUrl, 1000))
{
ListBoxMain.Items.Add(url);
// TEST
string[] threads = File.ReadAllLines(#"logic\markers.txt");
if (threads.Any(url.Contains)) {
}
// TEST
}
Two hints:
start using Ctrl+KD more often. This formats your code and would have shown the issue.
Always use braces when using compound functions, like if,else,foreach etc.

How to maintain culture through session variable

I have a multilingual web-forms web application which I am using resource files and a BasePage class which sets the culture based on the QueryString that was included in the page which is inheriting from this class. This is all working well, if a tad clunky as I am having to do this sort of thing for every button which takes the user to a different page to maintain the culture:
if (Thread.CurrentThread.CurrentCulture.ToString() == "cy-GB")
{
return "~/Secure/Details.aspx?lang=cy-GB&PersonId=" + currentPersonId;
}
else
{
return "~/Secure/Details.aspx?PersonId=" + currentPersonId;
}
I knew there was probably a better way of doing this but being a novice as it worked I simply made do.
This was until I had to implement an asp:SiteMapPath control. I initially assumed that I could simply create a resource entry for the url property like I had done for the title:
<siteMapNode
title="$resources:SiteMapLocalizations,HomePageTitle"
description="Home"
url="~$resources:SiteMapLocalizations,HomePageUrl">
However this resulted in a server error:
A potentially dangerous Request.Path value was detected from the client (:).
I've done some reading and I believe I need to somehow store the current culture to a session variable which will follow the user around so when they click 'Home' on the breadcrumb it will be consistent with the culture and grab the appropriate text from the resource files, I'm also hoping this will allow me to remove all of the IF ELSE statements I've had to write to maintain the current language throughout the application.
My question is however, where do I start with this, I cannot find any guide step by step to follow in order to achieve this, can anyone provide some instructions?
Make sure you have a button of some sort which triggers the change of language. In my case I have two versions of the header, one with an English link which will append the Query String to English and one for Welsh, something like:
ASP
<a id="languagelink" runat="server" title="Cymraeg">Cymraeg</a>
C#
if (Thread.CurrentThread.CurrentCulture.ToString() == "en-GB")
{
Uri uri = new Uri(currentPage);
languagelink.HRef = String.Format(uri.GetLeftPart(UriPartial.Path)+"?lang=cy-GB");
}
Every page which requires the language switch needs to inherit from my custom BasePage like so:
Inheritance
public partial class Secure_CustomerSummary : BasePage
Base_Page
public partial class BasePage : System.Web.UI.Page
{
protected override void InitializeCulture()
{
if (Session["language"] == null)
{
Session["language"] = "en-GB";
}
else
{
if (Request.QueryString["lang"] == null)
{
SetSessionCulture();
}
if (Request.QueryString["lang"] != null)
{
string qs = Request.QueryString["lang"];
Session["language"] = qs;
}
SetSessionCulture();
}
SetSessionCulture();
}
private void SetSessionCulture()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Session["language"].ToString());
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Session["language"].ToString());
base.InitializeCulture();
}
}

How to detect if WSFederationSession has expired or ended?

I have a several methods in controller:
public ActionResult Issue()
{
var message = WSFederationMessage.CreateFromUri(HttpContext.Request.Url);
// sign in
var signinMessage = message as SignInRequestMessage;
if (signinMessage != null)
{
return ProcessWSFederationSignIn(signinMessage, ClaimsPrincipal.Current);
}
// sign out
var signoutMessage = message as SignOutRequestMessage;
if (signoutMessage != null)
{
return ProcessWSFederationSignOut(signoutMessage);
}
return View("Error");
}
And the most valuable for me in this question:
private ActionResult ProcessWSFederationSignOut(SignOutRequestMessage message)
{
FederatedAuthentication.SessionAuthenticationModule.SignOut();
var mgr = new SignInSessionsManager(HttpContext, _cookieName);
// check for return url
if (!string.IsNullOrWhiteSpace(message.Reply) && mgr.ContainsUrl(message.Reply))
{
ViewBag.ReturnUrl = message.Reply;
}
return View("Signout");
}
All works fine, but, there are interesting moment.
This thing works in both cases, if I ended session by myself, or session simply expired. Its fine but actually, I need to tell the difference between those cases, write in ViewBag something like "You are singed out" or "Session expired" depends on result and show it oy the View.
Is there are some kind of way to detect session expired situations or should it be something different?
P.S Sorry for my bad English.
Since you changed the topic I will update my answer. I haven't used WSFederatinSession but maybe you could store the inf about how session ended (in a cookie for example) and during the next request (in a global asax for example) read this inf and do what you want to do.

Detect when the selenium webdriver changes url in browser

I need to detect when the url in the browser changes whether it was because of click on a link, a form post or I changed the url in code.
I need it because I'm creating an object to represent the page and I need to dispose recreate it when the url changes.
Here is what I have tried so far:
private string _pageUrl;
protected T _page = default(T);
protected T Page
{
get
{
if (_page == null || UrlHasChanged())
{
_page = GetPage<T>();
SetPageUrl();
}
return _page;
}
}
private bool UrlHasChanged()
{
var driver = Session.GetDriver();
return driver.Url != _pageUrl;
}
public void SetPageUrl()
{
_pageUrl = Session.GetDriver().Url;
}
This works in most cases but it fails when the test goes forward a page and then goes back to the initial page.
I need a way to detect when the url changes so I can reset the _page field.
I'm a Java developer, so, I search in the C# documentation what looked similar to the Java API. I think you should use the EventFiringWebDriver :
EventFiringWebDriver firingDriver = new EventFiringWebDriver(driver);
firingDriver.NavigatingBack += new EventHandler<WebDriverNavigationEventArgs>(...);
firingDriver.NavigatedBack += new EventHandler<WebDriverNavigationEventArgs>(...);
firingDriver.NavigatingForward += new EventHandler<WebDriverNavigationEventArgs>(...);
firingDriver.NavigatedForward += new EventHandler<WebDriverNavigationEventArgs>(...);
I looked at the unit tests and I found this one that may be useful for you :
http://selenium.googlecode.com/svn/trunk/dotnet/test/WebDriver.Support.Tests/Events/EventFiringWebDriverTest.cs

UrlRewriter+HttpModule+Session problem

I need to write a custom "UrlRewriter" using a HttpModule, in the moment of "rewriting" I need access to the Session and has followed the advice from another SO thread:
Can I access session state from an HTTPModule?
Everything works, except the RewritePath/Redirect part. I don't get any exceptions, but the browser takes forever to load. Is this really the best way to build a urlrewriter like this?
using System;
using System.Web;
using System.Web.SessionState;
using System.Diagnostics;
namespace MyCompany.Campaigns
{
public class CampaignRewriteModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.PostAcquireRequestState += new EventHandler(Application_PostAcquireRequestState);
application.PostMapRequestHandler += new EventHandler(Application_PostMapRequestHandler);
}
void Application_PostMapRequestHandler(object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState)
{
return;
}
app.Context.Handler = new MyHttpHandler(app.Context.Handler);
}
void Application_PostAcquireRequestState(object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;
if (resourceHttpHandler != null)
{
HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
}
Debug.Assert(app.Session != null);
string path = HttpUtils.Path();
if (!CampaignCodeMethods.IsValidCampaignCode(path)) return;
string domain = HttpUtils.Domain();
CampaignCode code = CampaignManager.RegisterCode(path, domain.Equals(Config.Instance.Domain.ToLower()) ? null : domain);
if (code != null)
{
//app.Context.RewritePath(code.CampaignCodePath.Path, false);
app.Context.Response.Redirect(code.CampaignCodePath.Path, true);
}
}
public void Dispose() { }
public class MyHttpHandler : IHttpHandler, IRequiresSessionState
{
internal readonly IHttpHandler OriginalHandler;
public MyHttpHandler(IHttpHandler originalHandler)
{
OriginalHandler = originalHandler;
}
public void ProcessRequest(HttpContext context)
{
throw new InvalidOperationException("MyHttpHandler cannot process requests.");
}
public bool IsReusable
{
get { return false; }
}
}
}
}
I think I know what it is. Your module is executed on ALL requests and assigns a handler that throws an error unless there is a valid campaign code (where a rewrite/redirect occurs).
But because this is not just for your "handler campaign code" url it is causing an error to be thrown, which is causing you to be redirected to your error page, which is being caught by the module, which is assigning the handler, which is throwing an error, which is redirecting... I think you get where I'm going ;)
Otherwise I'd try a few things:
Setup Fiddler and check for an infinite redirect loop
Put a breakpoint on app.Context.Response.Redirect - make sure your not in an infinite loop
Put a breakpoint on MyHttpHandler.ProcessRequest - make sure it's not being called and the exception swallowed
I wrote a simple URL rewriter module that did something similar. The url rewriting is done in BeginRequest by comparing the requested url to a list of known urls. If we find a mach we use HttpContext.RewritePath to change the requested url.
This appears to work well with no serious side effects.
I notice that you use Response.Redirect instead of Context.RewritePath. Using Redirect will cause the users browser to request a new page with the new url. Is this really what you want? The user will then see the new url in his browser. If this really is what you want you could use an alternative approach where you use a custom 404 page not found error handler to redirect the user to the appropriate page.
If you set up IIS to redirect all 404 errors to a new page, say Custom404.aspx, that you have set up. In this page you can check the requested url to see if the url should be rewritten. If it should you can simply set the Response.Status to "301 Moved Permanently" and write a header with the name "Location" and the new url as the value. If the url should not be rewritten you can just output the standard 404 page not found error.
This last approach works well, but as with your Response.Redirect approach the user will see the new url in his browser. Using Context.RewritePath allows you to serve a different page than the one requested.
Is your URL rewriter handling requests that aren't for an actual page? If they are, then I don't think you can access Session... the last URL rewriter that I had written was there to handle 404 errors, and I remember digging around and finding (somewhere, can't remember where) that you don't get access to Session if that request is not for an actual .aspx page.
I'm thinking the problem may be inside this block:
if (code != null)
{
//app.Context.RewritePath(code.CampaignCodePath.Path, false);
app.Context.Response.Redirect(code.CampaignCodePath.Path, true);
}
Try putting a breakpoint in the if statement and see if continually gets hit.
I think there should be a call to 'return' after you reset it to the original handler, else you will continually rewrite the path.
Thinking about it, that's probably why the page is loading forever! :)

Categories