Flurl (Fluent Url) custom serialization - query-string

How do I override Flurl's default behaviour when serializing objects to query string values? E.g. the below code
DateTime date = new DateTime(2017, 1, 2, 3, 4, 5);
Url url = "http://domain.com".SetQueryParam("date", date);
produces the following url:
http://domain.com?date=01%2F02%2F2017%2003%3A04%3A05
What I want is this:
http://domain.com?date=2017-01-02T03%3A04%3A05.0000000
which would be the result of serializing the date as follows:
date.ToString("O")

Flurl takes care of URL-encoding but beyond that isn't really concerned with custom string formatting. I guess the most obvious way to do what you want is this:
"http://domain.com".SetQueryParam("date", date.ToString("O"));
If you're doing this a lot and want to avoid specifying the formatting bit every time, you could add your own extension methods (one for Url and one for string, per the pattern):
public static Url SetDateParam(this Url url, string name, DateTime date)
{
return url.SetQueryParam(name, date.ToString("O"));
}
public static Url SetDateParam(this string url, string name, DateTime date)
{
return new Url(url).SetDateParam(name, date);
}
Then you've got:
"http://domain.com".SetDateParam("date", date);

Related

Convert DateTime with a specified language

I am coding a MVC 5 internet application and am wanting to convert a DateTime to be displayed as a LocalTime where I have the language. This is for an Azure website.
Here is my code:
DateTime dateTimeUtcNow = DateTime.UtcNow;
DateTime convertedDate = DateTime.SpecifyKind(dateTimeUtcNow, DateTimeKind.Utc);
DateTime dateTimeLocalTime = convertedDate.ToLocalTime();
return dateTimeLocalTime.ToString(new CultureInfo("en-NZ"));
The output from the above code is the exact same output as if I return the DateTime in UTC with no language culture specified.
How can I convert a DateTime in UTC for a local time where I have the culture language?
Thanks in advance.
You can use the second argument to the toString function and use any language/culture you need...
You can use the "d" format instead of ToShortDateString according to MSDN...
So basically something like this to return as NewZ ealand English:
CultureInfo enAU = new CultureInfo("en-NZ");
dt.ToString("d", enAU);
you could modify your method to include the language and culture as a parameter
public static string ConvertDateTimeToDate(string dateTimeString, String langCulture) {
CultureInfo culture = new CultureInfo(langCulture);
DateTime dt = DateTime.MinValue;
if (DateTime.TryParse(dateTimeString, out dt))
{
return dt.ToString("d",culture);
}
return dateTimeString;
}
You may also want to look at the overloaded tryParse method if you need to parse the string against a particular language/culture...

change query string values without redirect in c#

I have a query string that looks something like this:
"somename1=123&QueryString=PlaceHolder%3dNothing%26anotherid%3dsomevalue&somename=somevalue"
but I want the query string to be something like the query string below and replace the whole query string with the updated one is there any way to do that without redirection?
"somename1=somevalue1&PlaceHolder=Nothing&somename2=somevalue2&somename3=somevalue3"
basically need to remove:
"QueryString=" with empty string
"%3d" with "&"
"%26" with "="
So far I've done is:
string strQueryString = Request.QueryString.ToString();
if (strQueryString.Contains("QueryString="))
{
strQueryString = strQueryString.Replace("QueryString=", "");
if (strQueryString.Contains("%26")) strQueryString = strQueryString.Replace("%26", "&");
if (strQueryString.Contains("%3d")) strQueryString = strQueryString.Replace("%3d", "=");
string x = strQueryString;
}
and:
// reflect to readonly property
PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
// make collection editable
isreadonly.SetValue(this.Request.QueryString, false, null);
if (this.Request.QueryString.ToString().Contains("QueryString="))
{
this.Request.QueryString.ToString().Replace("QueryString=", "");
if (this.Request.QueryString.ToString().Contains("%26")) this.Request.QueryString.ToString().Replace("%26", "&");
if (this.Request.QueryString.ToString().Contains("%3d")) this.Request.QueryString.ToString().Replace("%3d", "=");
string x = this.Request.QueryString.ToString();
}
// make collection readonly again
isreadonly.SetValue(this.Request.QueryString, true, null);
The second part of the code is not replacing the characters and I don't know how after removing all character or replacing them change the query string to new query string.
Any help is greatly appreciated.
Changing the query string of the current request is not supported. Using private Reflection to edit some in-memory state will most likely break ASP.NET because it assumes that the query string is immutable. The only way to change the query string is to issue a new request, either by doing a redirect, or by doing a sort of sub-request, such as by making a new HTTP request to the same page but with a different query string.
May I suggest a not very well known built in key/value dictionary, Context.Items.
With this you very like get a better performance than toggle the readonly QueryString object, and it also last throughout a request so you can share it between module, handlers, etc.
Create
string strQueryString = Request.QueryString.ToString();
if (strQueryString.Contains("QueryString="))
{
HttpContext.Current.Items("qs") = strQueryString.Replace("QueryString=", "").Replace("%26", "&").Replace("%3d", "=");
}
Use
string x = HttpContext.Current.Items("qs_d").ToString();
Side note: I shortened you code some, as there is no need to first check if anything contains and if so, replace, just run replace, it will be faster

How to to find a domain name inside a query string value

I think regular expressions might be able to accomplish this, if not then string manipulation is also a viable solution.
I need to turn the following inputs:
"http://open.thumbshots.org/image.pxf?url=www.party.com"
"http://www.xclicks.net/sc/ct.php?s=9971&l=http%3A//www.google.com/imgres%3F"
"http://whos.amung.us/pingjs/?k=yvybju40twbs&t=Mudswimmer%3A%20Spam%20%26%20Crap%3A%20Http%3AUniversity.com%3A%20No%20Animals%20Allowed..&c=c&y=htt"
into the following outputs:
"party.com"
"google.com"
"University.com"
I am not trying to get the host name of the URL, I want the the second domain, the one in the query string.
With everything that involves regular expressions there is a degree of uncertainty, for me at least, but giving your three inputs the following code works:
string[] urls = new string[]
{
"http://open.thumbshots.org/image.pxf?url=www.party.com",
"http://www.xclicks.net/sc/ct.php?s=9971&l=http%3A//www.google.com/imgres%3F",
"http://whos.amung.us/pingjs/?k=yvybju40twbs&t=Mudswimmer%3A%20Spam%20%26%20Crap%3A%20Http%3AUniversity.com%3A%20No%20Animals%20Allowed..&c=c&y=htt"
};
foreach (var url in urls)
{
var result = HttpUtility.ParseQueryString(new Uri(url, UriKind.Absolute).Query);
foreach (string item in result)
{
string value = result.GetValues(item).Single();
const string DomainNamePattern = "(?:www\\.|\\b)(?<domain>([a-z0-9]([-a-z0-9]*[a-z0-9])?\\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(cat|com|coop|c[acdfghiklmnorsuvxyz])|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))";
var match = Regex.Match(
value,
DomainNamePattern,
RegexOptions.IgnoreCase);
if (match.Success)
{
string domain = match.Groups["domain"].Value;
Console.WriteLine(domain);
}
}
}
The regular expression used was adapted from here.
If you run this you get the following output:
// party.com
// google.com
// University.com
If your link always contain the url querystring key then you can simple get this by
String url = Request.QueryString["url"].ToString();
This will retrun the value of url.

Looks like a query string, but won't act as a query string

I am working with VB in asp.net,
The basic problem is, I want to pair up the elements in a string, exactly like request.QueryString() will do to the elements in the query string of the web page.
However instead of the function looking at the current webpage query string I want it to look at a string (that is in the exact form of a query string) stored as a variable.
So if I define a string such as:
Dim LooksLikeAQueryString As String = "?category1=answer1&category2=answer2"
I want a function that if I input LooksLikeAQueryString and "category1" it outputs "answer1" etc.
Is there anything that can already do this or do I have to build my own function? If I have to build my own, any tips?
I should add that in this case I won't be able to append the string to the url and then run request.QueryString.
You can use the HttpUtility.ParseQueryString method - MSDN link
ParseQueryString will do it for you - something along these lines:
Private Function QueryStringValue(queryString As String, key As String) As String
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(queryString)
For Each s As String In qscoll.AllKeys
If s = key Then Return qscoll(s)
Next
Return Nothing
End Function
Usage:
Dim LooksLikeAQueryString As String = "?category1=answer1&category2=answer2"
Response.Write(QueryStringValue(LooksLikeAQueryString, "category2"))
If you dont want the dependancy of System.Web, of the top of my head
public string GetValue(string fakeQueryString,string key)
{
return fakeQueryString.Replace("?",String.Empty).Split('&')
.FirstOrDefault(item=>item.Split('=')[0] == key);
}

ASP.NET GUID as Unique Identifier - URL Rewrite

can you help? i have a DB, the unique identifiers are GUIDS - we need to implement URL rewriting however the page names look terrible for example:
testpage-2668FF87-0A3A-4cac-B9AB-2367D17A76C3.aspx
title of page / unique identifier
my DB's that i setup i use Ints as unique identifiers so i never had this problem:
testpage-1.aspx
title of page / unique identifier (int)
what do you suggest ?
Ceate a mapping table with GUIDS to a shorter name or a column in your table with a shorter name. Guids are guaranteed to be unique, but that doesn't mean they make for the best unique identifier.
Your public facing URLs should always be clean and legible. (Use "slugs", as above) This ensures that each of your pages generates consistent content for the user (i.e., it is not session based) and is visible to the search engines in a way that they can understand it.
On the database side, just track the extra "url" column and write your queries to utilize it instead of the GUID for "views", but use the GUID internally for UPDATE queries. :)
What I've seen a lot of is instead of exposing the actual guid, base64 encode it and change some of the characters:
public String ConvertBase64( Guid input ) {
String sResult = Convert.ToBase64String(input.ToByteArray(), Base64FormattingOptions.None);
sResult = sResult.Replace("/", "_").Replace("+", "-");
sResult = sResult.Substring(0, 22);
return sResult;
} // method::ConvertBase64(guid)
When converting it back you do the opposite.
public String Base64ToGuid( String input) {
input = input.Replace("_", "/").Replace("-", "+");
result = new Guid(Convert.FromBase64String(input + "=="));
}

Resources