Read in a html page within asp.net mvc - asp.net

i am porting over a website from asp.
i have one page that i can't figure out how to migrate it.
The page is dynamic in the sense that it reads in other html pages and sticks the content into the main "container" page. In the middle of the asp page it has sections like below
<%
Dim fso1, f11, ts1, s1
Const ForReading1 = 1
Set fso1 = CreateObject("Scripting.FileSystemObject")
Set ts1 = fso1.OpenTextFile("" & Server.MapPath("newsletters/welcome.html") & "", ForReading)
s1 = ts1.ReadAll
Response.Write s1
ts1.Close
set fso1 = nothing
set f11 = nothing
set ts1 = nothing
set s1 = nothing
%>
Any suggestions in ASP.net MVC for best way to read in other html pages and stick them into a page view.

I assume that these are HTML fragments, not full pages. You could convert them to partial views -- pretty trivial, you just add the correct page directive and rename to .ascx. Then you would use Html.RenderPartial to include the partial in your main view. Another way would be to create your own HtmlHelper extension that works like RenderPartial but simply reads the named file and writes it to the response just like you are currently doing.
Ex1:
<% Html.RenderPartial( "welcome.ascx" ); %>
Ex2:
<% Html.RenderHtml( Server.MapPath( "newletters/welcome.html" ) ); %>
Note that in the first case the view file needs to live in the Views directory. In the second case, you can reference the file from anywhere that the worker process has read access. You'll need to create the second method yourself. Perhaps something similar to:
public static class MyHtmlHelperExtensions
{
public static void RenderHtml( this HtmlHelper helper, string path )
{
var reader = new StreamReader( path );
var contents = reader.ReadToEnd();
helper.ViewContext.HttpContext.Response.Write( contents );
}
}
Please note that you'll have to add error handling.

To read the contents of a text file in .Net, use the File.ReadAllText method.
The exact equivalent of your code snippet would be
<%= File.ReadAllText(Server.MapPath("newsletters/welcome.html")) %>

You should write like this:
string html = System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("~/htm/external/header.htm"));

Related

Setting the CSS class to "current" for the navigation menu in ASP Classic

I have an include file that contains the primary navigation menu for the site. I want to be able to set a CSS class for the current page. This is what I've been able to put together so far:
public function GetFileName()
Dim files, url, segments, current
'get then current url from the server variables
url = Request.ServerVariables("path_info")
segments = split(url,"/")
'read the last segment
url = segments(ubound(segments))
GetFileName = url
end function
if GetFileName = "index.asp" then
current = "current"
else
current = ""
end if
I'm thinking that a Select Case statement would be the thing to use in this scenario, I'm just not sure how to go about constructing it? Thanks in advance!
You'll need to add the definition of Iif to your code (from here: http://support.microsoft.com/kb/219271 )
Function IIf(i,j,k)
If i Then IIf = j Else IIf = k
End Function
I assume you have something like this.
<li>Click me to go somewhere</li>
You can do this:
<li>Click me to go somewhere</li>
You could do it in jquery
jQuery add class based on page URL
$(function() {
var loc = window.location.href;
if(/index.asp/.test(loc)) {
$(body).addClass('index');
}
});

Working with resources

there!
I'm working with asp.net 3.5 web-site. And I have such problem:
I have 3 aspx pages, that contain asp:Label control with name "LabelContent" and foreach page I have two resx files, that contain LabelContentResource.Text and LabelContent binds LabelContentResource to , for 2 cultures. Also I have content editing page. On this page admin choses page for edit and in WYSIWG editor I need to load appropriate resorce. Like so:
string pageForLoadName = "links.aspx.de-AT.resx";
string key ="LabelContent.Text";
string resValue= LoadREsource(pageForLoadName ,key );
How can I write LoadREsource fnction?
Thanks!
Something along the lines of
public string LoadResource(string pageForLoadName,string key)
{
return (String)HttpContext.GetGlobalResourceObject(pageForLoadName, key);
}
Also, don't think you need pageForLoadName = "links.aspx.de-AT.resx";
just pageForLoadName = "links.aspx.de-AT";

Asp.Net single control render for AJAX calls

I'm trying to implement something similar to this or this.
I've created a user control, a web service and a web method to return the rendered html of the control, executing the ajax calls via jQuery.
All works fine, but if I put something in the user control that uses a relative path (in my case an HyperLink with NavigateUrl="~/mypage.aspx") the resolution of relative path fails in my developing server.
I'm expecting:
http://localhost:999/MyApp/mypage.aspx
But I get:
http://localhost:999/mypage.aspx
Missing 'MyApp'...
I think the problem is on the creation of the Page used to load the control:
Page page = new Page();
Control control = page.LoadControl(userControlVirtualPath);
page.Controls.Add(control);
...
But I can't figure out why....
EDIT
Just for clarity
My user control is located at ~/ascx/mycontrol.ascx
and contains a really simple structure: by now just an hyperlink with NavigateUrl like "~/mypage.aspx".
And "mypage.aspx" really resides on the root.
Then I've made up a web service to return to ajax the partial rendered control:
[ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class wsAsynch : System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
public string GetControl(int parma1, int param2)
{
/* ...do some stuff with params... */
Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl("~/ascx/mycontrol.ascx");
Type viewControlType = viewControl.GetType();
/* ...set control properties with reflection... */
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
}
}
The html is correctly rendered, but the relative path in the NavigateUrl of hyperlink is incorrectly resolved, because when I execute the project from developing server of VS2008, the root of my application is
http://localhost:999/MyApp/
and it's fine, but the NavigateUrl is resolved as
http://localhost:999/mypage.aspx
losing /MyApp/ .
Of Course if I put my ascx in a real page, instead of the pageHolder instance used in the ws, all works fine.
Another strange thing is that if I set the hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx") I get the correct url of the page:
http://localhost:999/MyApp/mypage.aspx
And by now I'll do that, but I would understand WHY it doesn't work in the normal way.
Any idea?
The problem is that the Page-class is not intented for instantiating just like that. If we fire up Reflector we'll quickly see that the Asp.Net internals sets an important property after instantiating a Page class an returning it as a IHttpHandler. You would have to set AppRelativeTemplateSourceDirectory. This is a property that exists on the Control class and internally it sets the TemplateControlVirtualDirectory property which is used by for instance HyperLink to resolve the correct url for "~" in a link.
Its important that you set this value before calling the LoadControl method, since the value of AppRelativeTemplateSourceDirectory is passed on to the controls created by your "master" control.
How to obtain the correct value to set on your property? Use the static AppDomainAppVirtualPath on the HttpRuntime class. Soo, to sum it up... this should work;
[WebMethod(EnableSession = true)]
public string GetControl(int parma1, int param2)
{
/* ...do some stuff with params... */
var pageHolder = new Page() { AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath };
var viewControl = (UserControl)pageHolder.LoadControl("~/ascx/mycontrol.ascx");
var viewControlType = viewControl.GetType();
/* ...set control properties with reflection... */
pageHolder.Controls.Add(viewControl);
var output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
}
The tildy pust the path in the root of the app, so its going to produce a the results you are seeing. You will want to use:
NavigateUrl="./whatever.aspx"
EDIT:
Here is a link that may also prove helpful...http://msdn.microsoft.com/en-us/library/ms178116.aspx
I find the /MyApp/ root causes all sorts of issues. It doesn't really answer your question 'why is doesn't work the normal way', but do you realize you can get rid of the /MyApp/ and host your website at http:/localhost/...?
Just set Virtual Path in the website properties to '/'.
This clears everything up, unless of course you are trying to host multiple apps on the development PC at the same time.
It might be that the new page object does not have "MyApp" as root, so it is resolved to the server root as default.
My question is rather why it works with Page.ResolveUrl(...).
Maybe ResolveUrl does some more investigation about the location of the usercontrol, and resolves based on that.
Weird, I recreated the example. The hyperlink renders as <a id="ctl00_hlRawr" href="Default.aspx"></a> for a given navigation url of ~/Default.aspx. My guess is that it has something to do with the RequestMethod. On a regular page it is "GET" but on a webservice call it is a "POST".
I was unable to recreate your results with hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx")
The control always rendered as <a id="ctl00_hlRawr" href="Default.aspx"></a> given a virtual path. (Page.ResolveUrl gives me "~/Default.aspx")
I would suggest doing something like this to avoid the trouble in the future.
protected void Page_Load(object sender, EventArgs e)
{
hlRawr.NavigateUrl = FullyQualifiedApplicationPath + "/Default.aspx";
}
public static string FullyQualifiedApplicationPath
{
get
{
//Return variable declaration
string appPath = null;
//Getting the current context of HTTP request
HttpContext context = HttpContext.Current;
//Checking the current context content
if (context != null)
{
//Formatting the fully qualified website url/name
appPath = string.Format("{0}://{1}{2}{3}",
context.Request.Url.Scheme,
context.Request.Url.Host,
(context.Request.Url.Port == 80 ? string.Empty : ":" + context.Request.Url.Port),
context.Request.ApplicationPath);
}
return appPath;
}
}
Regards,
It is hard to tell what you are trying to achieve without posting the line that actually sets the Url on of the HyperLink, but I think I understand your directory structure.
However, I have never run into a situation that couldn't be solved one way or another with the ResolveUrl() method. String parsing for a temporary path that won't be used in production is not recommended because it will add more complexity to your project.
This code will resolve in any object that inherits from page (including a usercontrol):
Page page = (Page)Context.Handler;
string Url = page.ResolveUrl("~/Anything.aspx");
Another thing you could try is something like this:
Me.Parent.ResolveUrl("~/Anything.aspx");
If these aren't working, you may want to check your IIS settings to make sure your site is configured as an application.

Embedding jQuery into your ASP.Net Server Custom Control

I am undergraduate student. I had some queries related to embedding jQuery inside your ASP.NET Server side Custom Control.
private string GetEmbeddedTextFile(string sTextFile)
{
// generic function for retrieving the contents
// of an embedded text file resource as a string
// we'll get the executing assembly, and derive
// the namespace using the first type in the assembly
Assembly a = Assembly.GetExecutingAssembly();
String sNamespace = a.GetTypes()[0].Namespace;
// with the assembly and namespace, we'll get the
// embedded resource as a stream
Stream s = a.GetManifestResourceStream(
string.Format("{0}.{1}",a.GetName().Name, sTextFile)
);
// read the contents of the stream into a string
StreamReader sr = new StreamReader(s);
String sContents = sr.ReadToEnd();
sr.Close();
s.Close();
return sContents;
}
private void RegisterJavascriptFromResource()
{
// load the embedded text file "javascript.txt"
// and register its contents as client-side script
string sScript = GetEmbeddedTextFile("JScript.txt");
this.Page.RegisterClientScriptBlock("PleaseWaitButtonScript", sScript);
}
private void RegisterJQueryFromResource()
{
// load the embedded text file "javascript.txt"
// and register its contents as client-side script
string sScript = GetEmbeddedTextFile("jquery-1.4.1.min.txt");
this.Page.ClientScript.RegisterClientScriptBlock(typeof(string), "jQuery", sScript);
// this.Page.RegisterClientScriptBlock("JQueryResourceFile", sScript);
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// the client-side javascript code is kept
// in an embedded resource; load the script
// and register it with the page.
RegisterJQueryFromResource();
RegisterJavascriptFromResource();
}
but the problem I am facing is that all my JQuery code which I have written in separate .JS file and have tried to embed in my Custom control , is streamed as output on the screen . Also , my Control is not behaving correctly as it should have to , jQuery functionality is not working behind due to this reason of not getting embedded properly :-(
Please help me out!
Thank you!
It sounds like you are missing the <script> tags surrounding the javascript. Try this overload of RegisterClientScriptBlock that takes a fourth boolean parameter that will add the script tags if it is true.
Page.ClientScript.RegisterClientScriptBlock(typeof(string), "jQuery", sScript, true);
"all my JQuery code which I have written in separate .JS file and have tried to embed in my >Custom control , is streamed as output on the screen" .
Sounds like you need to add a line that tells the code how to download the embedded javascript. Do it with an Assembly annotation above the start of a class in your custom control project. This is the format:
<Assembly: System.Web.UI.WebResource("Namespace.ScriptName.js", "application/x-javascript")>

How to get server side variable value in xsl template?

I want use localized strings from resources in xsl template as in aspx page, like this:
<%=GetLocalizedString("grid_numberof_claim")%>. I am trying use
<xsl:text disable-output-escaping="yes">
<![CDATA[<%=GetLocalizedString("grid_numberof_claim")%>]]>
</xsl:text>
but it is not useful.
Actually i can pass localized strings inside XML node, for example "localization". But i am looking for way to get its value in aspx style.
Using ASPX style isn't possible.
You can use XsltArgumentList to send parameters to your XSLT template, as explained here: HOW TO: Execute Parameterized XSL Transformations in .NET Applications
EDIT: Yes, you can pass arguments client-side too.
xmldoc = ... // your xml document
var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");
xslDoc.async = false;
xslDoc.load("YourTemplate.xsl");
xslt.stylesheet = xslDoc;
xslProc = xslt.createProcessor();
xslProc.input = xmldoc;
xslProc.addParameter("param1", 123);
xslProc.addParameter("param2", "abc");
xslProc.transform();
But client-side leads to another solution: You can rename your XSLT file to ASPX and to use <%= %> syntax

Resources