How to get the last two sections of a URL - asp.net

When the URL is: http://www.example.com/services/product/Software.aspx , I need: "product/Software.aspx",
So far I just tried the below code :
string[] SplitUrls = Request.RawURL.Split('/');
string CategorynQuery = SplitUrls[SplitUrls.Length - 2]
+ SplitUrls[SplitUrls.Length - 1];
However, is there some other way to do this using functions IndexOf(), LastIndexOf() etc.. or any other Function? Or any possibility using Substring method ?
Please note that the above URL is just an example, there are around 100 such URls and I need the Last 2 sections for each.

Try this, using the LastIndexOf, and Substring.
string str = "http://www.example.com/services/product/Software.aspx";
int lastIndexOfBackSlash = str.LastIndexOf('/');
int secondLastIndex = lastIndexOfBackSlash > 0 ? str.LastIndexOf('/', lastIndexOfBackSlash - 1) : -1;
string result = str.Substring(secondLastIndex, str.Length - secondLastIndex);
I am also checking the presence when getting the second last index - obviously you can alter this depending on your requirements :)

You can use Uri class:
Uri uri = new Uri("http://myUrl/%2E%2E/%2E%2E");
uri.AbsoluteUri;
uri.PathAndQuery;

Not too efficient but a little more elegant:
string url = "http://www.example.com/services/product/Software.aspx";
var splitted = url.Split('/').Reverse().Take(2).Reverse().ToList();
var str = string.Format("{0}/{1}", splitted[0], splitted[1]);

Related

Split the string of a row of datatable in asp.net

I am using asp.net. I am trying to split the data which is in datatable. I have a code sample like this:
{ dt=objErrorLoggingDataAccess.GetErrorDetails(errorID);
string[] stringSeparators = new string[] { "Message" };
string error = dt.Rows[0]["Message"].ToString();
string[] test = error.Split(stringSeparators, StringSplitOptions.None);
string PageName = test[0].ToString();
PageNameLabel.Text = PageName;
stringSeparators=new string[] {HttpContext.Current.Request.Url.ToString()};
error = dt.Rows[0]["Message"].ToString();
test = error.Split(stringSeparators, StringSplitOptions.None);
string Message = test[0].ToString();
MessageLabel.Text = Message;}
in the datatable following data is there:
{....ID.......Message.......................................................................................................................
....1........http://localhost:10489/images/CategoryIcon/images Message : File does not exist. UserName: naresh#naresh.com
....2........http://localhost:10489/images/CategoryIcon/images Message : File does not exist. UserName: iswar#iswar.com}
My problem is: how can I split the Message and store in the label? I want
{http://localhost:10489/images/CategoryIcon/images}
separately and UserName separately and the message separately. How can I do that? By executing the above code I am able to split
{ http://localhost:10489/images/CategoryIcon/images
}
only. How can I split the Message column and store in pageLabel, MessageLabel, UserNamelabel?
I would use a regular expression in this case. Because only by splitting this string looks a little bit to inflexible to me.
I tested your data example against this quick and dirty RegEx:
(?<id>\d+)\.*(?<url>\w+:\/\/[\w#][\w.:#]+\/?[\w\.?=%&=\-#/$,]*)\s*Message\s*:\s*(?<message>.*)UserName:\s*(?<username>([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3}))
It supports valid URLs and EMail patterns.
Regex regex = new Regex(
"(?<id>\\d+)\\.*(?<url>\\w+:\\/\\/[\\w#][\\w.:#]+\\/?[\\w\\.?"+
"=%&=\\-#/$,]*)\\s*Message\\s*:\\s*(?<message>.*)UserName:\\s"+
"*(?<username>([a-zA-Z0-9_\\-\\.]+)#((\\[[0-9]{1,3}\\.[0-9]{1"+
",3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|"+
"[0-9]{1,3}))",
RegexOptions.IgnoreCase
| RegexOptions.CultureInvariant
| RegexOptions.IgnorePatternWhitespace
| RegexOptions.Compiled
);
// Capture the first Match, if any, in the InputText
Match m = regex.Match(InputText);
// Capture all Matches in the InputText
MatchCollection ms = regex.Matches(InputText);
// Test to see if there is a match in the InputText
bool IsMatch = regex.IsMatch(InputText);
// Get the names of all the named capture groups
// I included your fields as groups: id, url, message and username
string[] GroupNames = regex.GetGroupNames();
I don't know how often you need to call this code. Maybe you get in performance troubles if you have too much data. This regex is q&d - please adjust it to your needs.

Converting tweet link so that it is embedded in asp.net app

I want to convert a tweet url such as https://twitter.com/LindseyGrahamSC/status/320202348263780352 so that it is automagically embedded. So far the best i have come up with is to use a short code type syntax like [tweet:320202348263780352] which then makes the embdded tweet. But i'd really like to just paste the url in and have it work. I am stuck as to how achieve that. What i have so far:
var ctxTwitterContext = new TwitterContext(auth);
if (e.Location != ServingLocation.PostList && e.Location != ServingLocation.SinglePost)
return;
string regex__1 = #"\[tweet:.*?\]";
MatchCollection matches = Regex.Matches(e.Body, regex__1);
for (int i = 0; i < matches.Count; i++)
{
Int32 length = "[tweet:".Length;
string TweetID = matches[i].Value.Substring(length, matches[i].Value.Length - length - 1);
var embeddedStatus =
(from tweet in ctxTwitterContext.Status
where tweet.Type == StatusType.Oembed &&
tweet.ID == TweetID
select tweet.EmbeddedStatus)
.SingleOrDefault();
string html = embeddedStatus.Html;
e.Body = e.Body.Replace(matches[i].Value, String.Format(html));
The status ID is always the last segment of the URL. So, you can do this:
string statusUrl = "https://twitter.com/LindseyGrahamSC/status/320202348263780352";
string tweetID = statusUrl.Substring(statusUrl.LastIndexOf('/') + 1);
Unless I'm not understanding. If so, you can remove the RegEx code and the for loop.

How to get full category path from a keyword in Tridion

Can any one help me to get full category path from a given keyword. I am giving one example as below,
Example:
Category 1----> Keyword 1 -----> Keyword 11,
say from metadata i got the value "Keyword 11", but i need whole path i.e. /Category 1/ Keyword 1/Keyword 11.
Can anyone help me how to achieve this in Template Building Block using c#.
Maybe you can try and play with one of the following:
keyword.ParentKeywords recursively to create the path you are looking for.
OrganizationalItem oi = keyword.OrganizationalItem; // to get all the organizational items
keyword.OwningRepository
Hope that helps!
Below code should help you to get the path.
bool isRecursive = false;
KeywordField kwdField = (KeywordField)metaFields["kwdField"];
Keyword curKwd = new Keyword(kwdField.Value.Id, engine.GetSession());
string kwdPath = curKwd.Title;
while (!isRecursive) {
if (curKwd.ParentKeywords.Count > 0){
foreach (Keyword kwd in curKwd.ParentKeywords) {
kwdPath = kwd.Title + "/" + kwdPath;
}
curKwd = curKwd.ParentKeywords[0];
} else {
isRecursive = true;
}
}
kwdPath = curKwd.OrganizationalItem.Title + "/" + kwdPath;

Increment multidimensional array in Java

I have a file to put in a multidimensional array. I have to put to [0] a date (long) and one of the dimensions must be incremented depending on the value of the second token.
Here's the code :
BufferedReader bufStatsFile = new BufferedReader(new FileReader(statsFile));
String line = null;
List<Long[]> stats = new ArrayList<Long[]>();
stats.add(new Long[11]);
int i = 0; // will be in a loop later
while((line = bufStatsFile.readLine()) != null) {
StringTokenizer st = new StringTokenizer(line,";");
while(st.hasMoreTokens()) {
stats.get(i)[0] = Long.parseLong(st.nextToken());
stats.get(i)[Integer.parseInt(st.nextToken())]++; // Here is the problematic line.
}
}
bufStatsFile.close();
But the incrementation doesn't work. Maybe it is because of my array which is probably not correct, but I didn't found another proper way to do that.
Ok. I have found and it was, of course, stupid.
The problem was in my array declaration. I did it like that :
List<Long[]> stats = new ArrayList<Long[]>();
stats.add(new Long[11]);
And then, I tried to increment an Object and not a long number.
So now, I just do it like this :
List<long[]> stats = new ArrayList<>();
stats.add(new long[11]);
And it's perfectly working.
Check that the elements in your file are numbers from 0 to 10. Why are you having a List if you are only manipulating the row 0?
Which exception are your code throwing away?

FLEX XMLDecoder turns `09.00` to "09.00", but `10.00` to 10

Could someone explain why the FLEX 4.5 XMLDecoder does this to my XML-data?
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>08.00</xmltag> );
// object = "08.00"
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
// Object = "11" (HEY! Where did my '.00' part of the string go?)
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.30</xmltag> );
// Object = "11.3" (HEY! Where did my '0' part of the string go?)
The Flex deserializer also gave me issues with this. It may be interpreting them as Number objects and thus they will return short representations when toString() is called.
Try using .toFixed(2) whenever you need to print a value such as 11.00
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
trace($object); //11
trace($object.toFixed(2)); //11.00
So, to the answer the original question of why this is happening:
In the source code for SimpleXMLDecoder (which I'm guessing has similar functionality to XMLDecoder), there's a comment in the function simpleType():
//return the value as a string, a boolean or a number.
//numbers that start with 0 are left as strings
//bForceObject removed since we'll take care of converting to a String or Number object later
numbers that start with 0 are left as strings - I guess they thought of phone numbers but not decimals.
Also, because of some hacky implicit casting, you actually have three different types -
"0.800" : String
11 : int
11.3: Number

Resources