I wanted to create a function which would return the path of the current web site. This is what I thought was working while running in the IDE:
Public Shared Function WebsiteAbsoluteBaseUrl() As String
Dim RequestObject As System.Web.HttpRequest = HttpContext.Current.Request
Return "http://" & RequestObject.Url.Host & ":" & _
RequestObject.Url.Port & "/" & _
RequestObject.Url.Segments(1)
End Function
this seem like it should work? Is there a more straight forward way?
I am trying to replace all occurrences of the tag "{WebSiteBaseUrl} in an html email with the absolute web site path.
<A HREF="{WebSiteBaseUrl}Files/filename.pdf/>Some Text</A>
I don't want to have to parse the template and try to make sense of it in order to use MapPath function on a relative path to a file name.
The resulting email will become the html body of an html email, so I need the links to be absolute.
Some Text
I guess what I am seeing in dev, running in the IDE, is that "RequestObject.Url.Segments(1)" returns the name of the virtual folder and that in production it seems to be returning the name of the web page. I guess this probably has to do with how the web site is set up in IIS.
What does this suggest about how the web site is set up in production and how would you suggest I modify the code to yield a correct path after replacing {WebSiteBaseUrl} with the result of the function? This assumes that the file "filename.pdf" is in the relativepath ~/files/filesname.pdf.
You can use Request.Url.AbsoluteUri for this. Server.MapPath(".") will give you physical path.
Also you can use other Request properties which are listed here.
Try this to get the website's application path:
Public shared ReadOnly Property FullyQualifiedApplicationPath() As String
Get
Dim appPath As String = Nothing
Dim context As HttpContext = HttpContext.Current
If Not context Is Nothing Then
'Formatting the fully qualified website url/name
appPath = String.Format("{0}://{1}{2}{3}", _
context.Request.Url.Scheme, _
context.Request.Url.Host, _
IIf(context.Request.Url.Port = 80, String.Empty, ":" & context.Request.Url.Port), _
context.Request.ApplicationPath)
End If
Return appPath
End Get
End Property
or try this (just founded):
HttpContext.Current.Request.UrlInternal
Related
I am trying to render a hyperlink in an email template which will be sent to the user and if the user clicks on that link it will direct to a unique url. I have given the coding below,
email.AddMailmerge("RequestUrl", "Feedback Requests")
My problem is the link doesnt resolve correctly and take me to the right url. What am I doing wrong?
It resolves as:
C:\Users\Test\Desktop\localhost/Requests/Requests.aspx?Company_ID=KirprZ17bg5u5Qf1
Make sure you Appsetting contains http:// so instead of just
localhost
it needs to be
http://localhost
Be sure to format your href with quotes. Instead of relying on your app.config's value, which is return the C:\ value, use the .NET methods to get the current domain/URL.
Dim target As String = _
String.Format("<a href='{0}/Requests/Requests.aspx?Company_ID={1}'>Feedback Requests</a>",_
Request.Url.GetLeftPart(UriPartial.Authority),_
objCompany.IDHashed)
Dim strRequestLink As String = System.Configuration.ConfigurationManager.AppSettings("DomainName") & "/Requests/Requests.aspx?Company_ID=" & Me.ID & "&key=" & Me.IDHashed
Dim strRequestUrl As String = "http://" & strRequestLink & ""
I used the above formatting.
Trying to use a loop to check if images exists however it is always returning false. I am sure I am doing something simple and stupid but here is the code:
dim fs, sql_except
set fs=Server.CreateObject("Scripting.FileSystemObject")
if Not rs.eof then
arrRS = rs.GetRows(30,0)
set rs = nothing
If IsArray(arrRS) Then
For i = LBound(arrRS, 2) to UBound(arrRS, 2)
sku = arrRS(0, i)
if (fs.FileExists("../i/"&sku&".gif")=false) Then
response.write sku&"does not exist<br>"
end if
next
end if
erase arrRS
end if
set fs=nothing
You appear to be operating under the impression that the current folder context the your call to FileExists will assume is the physical folder containing the ASP script being executed. This is not so, it most likely will be "C:\windows\system32\inetsrv". You are also using URL path element separator / where FileExists is expecting windows physical path folder separator \.
You need to use Server.MapPath to resolve the path. This may work:
if Not fs.FileExists(Server.MapPath("../i/"&sku&".gif")) then
However you may run in to trouble with the parent path "..", this may not be allowed for security reasons. This might be a better approach:
Dim path : path = Server.MapPath("/parentFolder/i") & "\"
For i = LBound(arrRS, 2) to UBound(arrRS, 2)
sku = arrRS(0, i)
if Not fs.FileExists(path & sku & ".gif") Then
response.write Server.HTMLEncode(sku) & " does not exist<br>"
end if
next
Where "parentFolder" is the absolute path from the site root.
i want to set a link in VB.net dynamically to a file.
My url looks like that:
http://server/folder/folder2/file.aspx?get=param
I tried to use Request.URL but i have not found any solution to get only
http://server/folder/folder2/
without the query string and without the filename.
Please help.
Dim url = Request.Url;
Dim result = String.Format(
"{0}{1}",
url.GetLeftPart(UriPartial.Authority),
String.Join(string.Empty, url.Segments.Take(url.Segments.Length - 1))
)
You can easily get a relative file path using the Request instance, then work with that, using Path class ought to help:
Dim relativePath = Request.AppRelativeCurrentExecutionFilePath
Dim relativeDirectoryPath = System.IO.Path.GetDirectoryName(relativePath)
It's worth noting that GetDirectoryName might transform your slashes, so you could expand the path:
Dim mappedPath = HttpContext.Current.Server.MapPath(newpath)
So, to remove redundancy, we could shorten this:
Dim path = _
Server.MapPath( _
Path.GetDirectoryName( _
Request.AppRelativeCurrentExecutionFilePath)))
But you'll need to check for possible exceptions.
You can use Uri.Host to get the computer name and then Uri.Segments (an array) to get everything up to the filename, for example:
var fileName = Uri.Host && Uri.Segments(0) && Uri.Segments(1)
This will give you: server/folder/folder2
If you have a variable number of segments, you can iterate over them and ignore the last one.
I hope that might help :)
In my global.asax.vb file, I have code to re-write the URL if there is a prefix on the URL. We are introducing a new context in our application. So every page will either be of context hair or saliva.
Before the ASP.NET code (stack) even reaches this Global code, it calls an application block called UIProcess. It's code that Microsoft wrote years ago, and is no longer supported. The UIP block sort of mimics MVC, and you store all views, navigation and controller details inside the web.config. The UIP block is doing a redirect as shown below. Note, they had a known bug that was never fixed (commented out), so I had to recompile it before upgrading from .NET 2.0 to .NET 3.5. That's what I have commented out. That's the only bug I'm aware of.
private void RedirectToNextView(string previousView, ViewSettings viewSettings)
{
try
{
//if (previousView == null)
// HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ApplicationPath + "/" + viewSettings.Type, true);
//else
// HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ApplicationPath + "/" + viewSettings.Type, false);
if (previousView == null)
HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + viewSettings.Type, true);
else
HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + viewSettings.Type, false);
}
catch (System.Threading.ThreadAbortException) { }
}
Here is the Global.asax.vb code:
(again this code doesn't matter right now because it's not getting here YET with the exception being thrown)
Sub Application_BeginRequest(ByVal sender As Object, _
ByVal e As EventArgs)
' Fires at the beginning of each request
Dim originalUri As Uri = Request.Url
Dim rewrittenUrl As String = String.Empty
'Rewrite Saliva and Hair Testing urls
Select Case True
Case originalUri.AbsolutePath.StartsWith("/HairTest/")
rewrittenUrl = originalUri.AbsolutePath.Remove(0, 9)
If Not originalUri.Query.Contains("SampleTypeContext=247") Then
rewrittenUrl += "?sampleTypeContext=247"
End If
Case originalUri.AbsolutePath.StartsWith("/SalivaTest/")
rewrittenUrl = originalUri.AbsolutePath.Remove(0, 11)
If Not originalUri.Query.Contains("SampleTypeContext=3301") Then
rewrittenUrl += "?sampleTypeContext=3301"
End If
End Select
If rewrittenUrl <> String.Empty Then
'append the original query if there was one specified
If originalUri.Query <> String.Empty Then
If rewrittenUrl.Contains("?") Then
rewrittenUrl += "&"
Else
rewrittenUrl += "?"
End If
rewrittenUrl += originalUri.Query.Remove(0, 1)
End If
Context.RewritePath(rewrittenUrl)
End If
End Sub
The application is actually causing an exception above, when I try to pre-pend my URL (viewSettings.Type variable above) with "/HairTest" or "/SalivaTest". It causes that System.Threading.ThreadAbortException. I'm thinking because that path doesn't actually exist in our web application, but I'm just guessing. Notice, we're doing a re-write in our global, not a redirect. Our re-write prepends the URL with "/HairTest" or "/SalivaTest".
All of the pages in our web application expect that "SampleTypeContext" parameter if it needs it. If you can think of a way that will work better for this situation, let me know. I'll try to get more details on the exception.
Looking for ideas!! Our architecture approach is still up for discussion if we run into issues with this UIProcess block. We can't just get rid of the UIP block since it's used throughout our application, but I can modify the code above (in my first code snippet) if we need to.
There's no standard way to do this with the UIP block. And Microsoft doesn't maintain it anymore. I overloaded a bunch of the methods in the library to make it work. So that we can append a query string parameter (applicationScope) on each of our UIP redirect calls.
If you need the code, add a comment here, and I'll send you the source.
How can I transform a website to be able to handle multi language (example : english, french, spanish)?
I do not like the resource file because I feel limited and it's pretty long to build the list. Do you have any suggestion?
Update
For the moment the best way we found is to use an XML file and with some Xpath et get values.
Implicit localization (on the Visual Studio - Tools menu - Generate Local Resources) is about as easy as it can be. Write your pages in your default language, pick the menu option, and your resource files are created and can be sent to someone to translate.
The resx file is just xml, so if the translation company wants you can transform it into (and out of) spreadsheets easily.
Using a databases instead of resx as your backing store is not difficult. Rick Strahl has a good explanation and example code for a database-driven localization provider here - there's a nice built in localization editor too with interface to Google translations and Babelfish.
We store resources for multilingual sites in a database. We've created a couple of tools to make it easy to create and access these. There's a custom ExpressionBuilder that allows us to use this syntax:
<asp:linkbutton runat='server' text='<%$ LanguageStrings:ClickMe%>' />
And a custom label that contains the default text, and adds a row to the database if there's not already one.
<r:languagelabel runat="server" name="AboutUs">About Us</r:languagelabel>
The table containing the strings has one column per language. This makes it very easy to create the site in English (or whatever the default language is), then hand off the table (which populates itself) to a translator. It's also very easy to see what languages you need to have stuff translated for. With resources, every time you need to add a new string, you have to stop what you're doing, and then go to the resource file for each language and add the resource.
Here's the code for the language label:
''' <summary>
''' Retrieves a language-specific string.
''' </summary>
Public Class LanguageLabel
Inherits Label
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private Sub Populate()
If Len(Me.Name) > 0 Then
Dim LanguageString As String = GetLanguageString(Me.Name, Me.Text)
If Len(LanguageString) > 0 Then Me.Text = LanguageString
End If
End Sub
Private Sub LanguageLabel_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
Populate()
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
' By default a label wraps the text in a <span>, which we don't want in some situations
writer.Write(Me.Text)
End Sub
End Class
and the utility function:
Public Function GetLanguageString(ByVal Name As String, Optional ByVal DefaultText As String = "") As String
Dim DefaultLanguage As Language = Languages.GetById(1)
Name = StripPunctuation(Name).Trim.Replace(" ", "") ' Remove punctuation, spaces from name
Dim SelectSql As String = String.Format("Select {0},{1} from LanguageStrings where Name=#Name", Languages.CurrentLanguage.Code, DefaultLanguage.Code)
Dim LanguageStringTable As DataTable = ExecuteDataset(cs, CommandType.Text, SelectSql, New SqlParameter("#Name", Name)).Tables(0)
If LanguageStringTable IsNot Nothing AndAlso LanguageStringTable.Rows.Count > 0 Then
Dim LanguageText As String = LanguageStringTable.Rows(0)(Languages.CurrentLanguage.Code).ToString
Dim DefaultLanguageText As String = LanguageStringTable.Rows(0)(DefaultLanguage.Code).ToString
If Len(LanguageText) > 0 Then
' We have a string in this language
Return LanguageText
Else
' Nothing in this language - return default language value
Return DefaultLanguageText
End If
Else
' No record with this name - create a dummy one
If DefaultText = "" Then DefaultText = Name
Dim InsertSql As String = String.Format("Insert into LanguageStrings (Name, {0}) values (#Name, #Text)", DefaultLanguage.Code)
ExecuteNonQuery(cs, CommandType.Text, InsertSql, New SqlParameter("#Name", Name), New SqlParameter("#Text", DefaultText))
Return Name
End If
End Function
Resource files are the way to go. We ship our product in 12 languages. We pull all strings out into resource files and ship them to a translation company. It's a pain at times, but that is the defacto way to do it.
It also gets fun when 4-letter English words get translated into 17-letter phrases and you have to tweak your UI.
How late in the design process are you? If not too late, and if the budget allows, consider porting to a multi-lingual CMS like Ektron CMS300.net (which has built-in translation tools). If not, then you've got a huge task ahead of you.
Another solution I am using is to create the language folders which contain the aspx pages containing all the required text in that particular language.
The only problem here is how can you inject as little code as possible into those replicating pages. I am using a controller pattern here to do this, and then a object data source to get the data and bind it to the controls in all pages.
In this way I have achieved the goal of getting rid of the resource files and I can keep the code behind in one place without replicating it (unless necessary).
Edit: I would recommend a good CMS framework as well.
One of the web apps I develop has this NLS requirement too.
I found that there are at least 3 locations where you have localized texts:
user interface
database tables ("catalogs" or whatever you want to call them)
backend code (services etc)
My solution has one table for the pages, tables, etc ("Container"), one table for each item in that container (e.g. labels, buttons by ID, record identifiers), and one table for the translated items (plus language identifier).
A translation application helps me keep the translations up-to-date, and exports all translations in XML.
The product ships with translations, but customers can adjust the translations, changes taking effect immediately.
Sample code i have done using resource file
add global.asax
void Application_BeginRequest(Object sender, EventArgs e)
{
// Code that runs on application startup
HttpCookie cookie = HttpContext.Current.Request.Cookies["CultureInfo"];
if (cookie != null && cookie.Value != null)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(cookie.Value);
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cookie.Value);
}
else
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en");
}
}
http://satindersinght.blogspot.in/2012/06/create-website-for-multilanguage.html
http://satindersinght.wordpress.com/2012/06/14/create-website-for-multilanguage-support/