Inline Code on Webform Property - asp.net-mvc

Why doesn't this display the date/time when rendered?
<asp:Label runat="server" ID="test" Text="<%= DateTime.Now.ToString() %>" ></asp:Label>
Is there anyway to make this work?

Asp.net server controls don't play well with the <%=, instead you can do:
<span><%= DateTime.Now.ToString() %></span>
Ps. you could alternatively set the label's text on the code-behind. It might work for your scenario to set it on the PreRenderComplete.

I'm not sure if you've got a code behind file, but if you really need to set the label's Text property in the .aspx markup you could add the following code to the page:
<script runat="server">
protected override void OnPreLoad(EventArgs e)
{
if (!Page.IsPostBack)
{
this.test.Text = DateTime.Now.ToString();
base.OnPreLoad(e);
}
}
</script>
This way you can maintain the label control's state on postback.

Put the inline code inside the label's tag as below,
< asp:Label ID="Lbl" runat="server" Text="">
<%= DateTime.Now.ToString() %>
< /asp:Label>

Well the asp tags are rendered. You will have to set the property at runtime. or just do the <%= DateTime.Now.ToString() %>.

The simplest way to make that work would be to use a data-binding expression in place of the code render block...
<asp:Label runat="server" ID="test" Text="<%# DateTime.Now.ToString() %>" ></asp:Label>
Now the Text property will be set whenever Page.DataBind() is called, so in your code-behind you'll want something like
protected override void OnPreRender(EventArgs e)
{
if (!Page.IsPostBack)
{
DataBind();
}
base.OnPreRender(e);
}

The real problem here though is I need to set the property of a WebControl with code on the markup page. The only way I've found to do this is put the whole control in a code block. Its not elegant or suggested but when all else fails this will work.
<%
var stringBuilder = new StringBuilder();
var stringWriter = new StringWriter(stringBuilder);
var htmlWriter = new HtmlTextWriter(stringWriter);
var label = new Label { Text = DateTime.Now.ToString() };
label.RenderControl(htmlWriter);
Response.Write(stringBuilder.ToString());
%>
But this won't work if you need the control to maintain state.
UPDATE:
After researching Kev's answer I did find an even better solution. I don't have a code behind (its an MVC page) but you can still reference a control on the page through a code block so my new solution is the following. Note - You have to place the code block first for this to work.
<%
lblTest.Text = DateTime.Now.ToString();
%>
<asp:label runat="server" ID="lblTest" />
Thanks for the inspiration Kev!

Related

Ember: How to bind action to code generated with JS

I have a simple view which renders set of images depending on given items array (simplified code), using this as I need to collect some other data to 'build' required class name(s):
App.MyView = Ember.View.extend({
buildTemplate: function () {
var itemz = this.get('items');
var classname = 'classNameDependingOnSomeCalculations...';
var out = '<div>';
$.each(itemz, function (index, obj) {
out += '<img {{action myActionHere}} src="' + obj.href + '" alt="" class="'+classname+'"/>';
});
out += '</div>';
return out;
}.property('view'),
defaultTemplate: Ember.Handlebars.compile(
"<div>{{{view.buildTemplate}}}</div>"
)
});
And in template I'm using it as
{{#each myObj in myCollection}}
{{view App.MyView itemsBinding="myObj.items" otherBinding="otherProps" }}
{{/view}}
Unfortunately this way Ember instead of binding the action puts {{action myActionHere}} directly into code...
How can I bind an action instead while building dynamic template?
I'm using Ember 1.1.2
P.S. Or maybe I should use quite other approach for building this view?
There is a workaround to make this work with the view as you've laid it out here... But this is really not the ember way of doing it. If for some reason you need this kind of an approach, I'll append an answer for that, but I'm going to aim to fix the underlying issue.
Instead of doing this as shown here, you should instead have code that looks like the following directly in your JSP:
{{#each myObj in myCollection}}
<div>
{{#each item in myObj.items}}
<img {{action myActionHere}} src={{item.href}} alt='' class={{classNameFunction}}/>
{{/each}}
</div>
{{/each}}
If your reason for wanting to do this as a view is so that you can reuse this functionality without rewriting the code, take a look at partials which are specifically designed for that purpose.

Mvc Html.Label or Html.TextBox doesn't create

I'm making a test page for a project I'm working on and I've made desired progress so far but I'm trying to create TextBoxes from a model of List being passed to the view, however, the it seems to just ignore anything I have tried.
<form id="form1" runat="server">
<input id="btnsubmit" type="submit" name="Submit" onclick="Submit" />
<div id="divControls">
<% foreach (TextBox control in (this.Model as List<TextBox>))
{
Html.Label("lblLabel", control.Text);
Html.TextBox(control.ID, control.Text, new { id = control.ID, style = "width:50", name = "txt" + control.ID });
} %>
</div>
</form>
The List isn't null in the Controller on return. I don't have a clue at what the problem could be. If I throw a Something in the for loop it executes the appropriate number of times so why isn't it creating the labels or textboxes?
At first I thought it was that I'm adding them inside a form but I removed the form tags and it still didn't work so I really have no Idea, any help would be much appreciated. I'm relatively new to MVC.
[HttpPost]
public ActionResult Index(FormCollection form)
{
List<TextBox> controls = new List<TextBox>();
foreach (String Key in form.Keys)
{
if (Key.Contains("txt"))
{
TextBox textBox = new TextBox();
textBox.ID = Key;
textBox.Text = form.GetValues(Key)[0];
controls.Add(textBox);
}
}
return View("Index", controls);
}
Here's my Action encase it's helps.
Also encase I wasn't clear enough, I am adding controls to a form at runtime using JQuery and then that Action will be part of the submit so it must send the textboxes back to the view so they are not deleted.
Like I said I'm new to the whole MVC and Asynchronous thing so If there's a better way to do this, advice would be much appreciated.
Your not printing the html
<% foreach (TextBox control in (this.Model as List<TextBox>))
{%>
<%=Html.Label("lblLabel", control.Text)%>
<%=Html.TextBox(control.ID, control.Text, new { id = control.ID, style = "width:50", name = "txt" + control.ID })%>
<% } %>
Your code is looping through the controls and the Html.whaterever is returning a string but your not doing anything with it, just discarding it.
you also don't need to return a whole TextBox object. This is probably inefficient. Just return an struct or a class containing your data
Html.Label returns a string containing a <label> tag.
You're discarding that string.
You need to write it to the page by writing <%= Html.Whatever() %>.

How to use or use not a tag basing on a condition in ASP.NET MVC3?

How could I correctly use the following?
{ bool submitter = value; }
...
#(submitter ? "" : #"<a href=""" + Url.Action(actionName, "Queue") + #""">")
<div>
...
</div>
#(submitter ? "" : "</a>")
My error is that the anchor tag definition is being outputed like it should be in a HTML code right to the web browser and instead of seeing a link around the <div> I see the <a href="... etc.
Why?
If you don't want that encoded, then you need to use the Raw extension method:
#Html.Raw(submitter ? "" : #"<a href=""" + Url.Action(actionName, "Queue") + #""">")
<div>
...
</div>
#Html.Raw(submitter ? "" : "</a>")
This is because you cannot put block level elements, like div, inside inline elements like a, unless you use HTML5. I guess from your description you aren't.
If you're checking in a browser DOM inspector, you will see your code looks something like this:
<div></div>
<div></div>
<a></a>
The alternative is to change your div to span and set display: block on it in CSS if you require.
Also, that kind of logic would be better placed in a ViewModel.
Solution that I've: found
#(new MvcHtmlString(#"blah blah"))

Print all steps of asp:Wizard control

I have a asp:Wizard control in my Web Application.I need to be able to print at any step within the wizard , and print all steps up to that step not just the current step.
I've added a print button to every step page , and tried to call the javascript:window.Print(), but only the current step gets printed.
How do i get all the steps to print in 1 page?
i'd like to try and get this working in javascript first before i go down the PDF route . I've tried doing somehting like this :
protected void Page_Load(object sender, EventArgs e)
{
StringWriter sw = new StringWriter();
HtmlTextWriter tw = new HtmlTextWriter(sw);
this.WizardStep2.RenderControl(tw);
string wizardHtmlContent = sw.ToString().Replace("\r\n", "");
string printScript = #"function printDiv(printpage)
{
var headstr = '<html><head><title></title></head><body>';
var footstr = '</body>';
var newstr = printpage;
var oldstr = document.body.innerHTML;
document.body.innerHTML = headstr+newstr+footstr;
window.print();
document.body.innerHTML = oldstr;
return false;
}";
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "PrentDiv", printScript, true);
this.Button1.Attributes.Add("onclick", "printDiv('" + wizardHtmlContent + "');");
}
and for the aspx:
<form id="form1" runat="server">
<div>
<asp:Wizard ID="Wizard1" runat="server">
<WizardSteps>
<asp:WizardStep ID="WizardStep1" runat="server" Title="Step 1">
step1
</asp:WizardStep>
<asp:WizardStep ID="WizardStep2" runat="server" Title="Step 2">
step2
</asp:WizardStep>
</WizardSteps>
</asp:Wizard>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
But i'm getting a missing runat=server error on line 3 , when i attempt to render the wizard control , so i think i may need to create a new window, then output the string before i print it , but cant seem to get that working ...Anyone any ideas ?
i have found a solution for my problem , i didnt manage to accomplish it client side , but ive managed to solve it server side which is better than going down the PDF route which i didnt want to do.
I found a great article here :
Printing in ASP.NET
which i ammended to print all steps of my wizard control in one go. thanks for all your help.
The javascript print method you're already using will work if you put the wizard steps in to a single page so they all render ...
the other way I guess is to simply browse to each step and hit your print button.
the way I would do it is use something like pdfsharp and give it the markup generates by each step and tell it to create a pdf page for each steps worth of markup ... from there the user has a pdf doc which they can simply view save or print using their usual pdf viewer.
The problem is that the javascript method is using a dom based api call to ask the browser to print the page which of course ultimately means you can only print the wizard step you're currently looking at ... using the pdf method means the user can preview the expected print out before printing and you have more control over what's printed.
It does require a bit more code though ...
pdfsharp can be found here: http://www.pdfsharp.net/Downloads.ashx
As you can see its free and open source.

What is the equivalent to Page.ResolveUrl in ASP.NET MVC?

What is the equivalent to Page.ResolveUrl in ASP.NET MVC available in the Controller?
It is Url.Content:
ASPX:
<link rel="stylesheet" href="<%= Url.Content("~/Content/style.css") %>" type="text/css" />
Razor:
<link rel="stylesheet" href="#Url.Content("~/Content/style.css")" type="text/css" />
This should do what you're looking for...
System.Web.VirtualPathUtility.ToAbsolute("~/")
Here are a whole bunch of ways to resolve a path that uses that application root operator (~)
UrlHelper.Content
HttpServerUtility.MapPath
WebPageExecutingBase.Href
VirtualPathUtility.ToAbsolute
Control.ResolveUrl
To call any method with inline code on an asp.net page, the method either needs to be exposed as an instance variable on the current object, or available as a static/shared method.
A typical MVC page gives us access to quite a few of these as properties via the WebViewPage. Ever wonder when you type #ViewData, you get magically wired up to the ViewData? That's because you have hit a property exposed by the MVC page you're on.
So to call these methods, we don't necessarily refer to the type they represent, but the instance property that exposes them.
We can call the above instance methods like this (respectively):
href="#Url.Content("~/index.html")"
href="#Server.MapPath("~/index.html")"
href="#Href("~/index.html")"
We can do this to call a shared method that doesn't need an instance:
href="#VirtualPathUtility.ToAbsolute("~/index.html")"
AFAIK, an MVC page doesn't automatically create an instance of anything from the System.Web.UI namespace, from which ResolveUrl inherits. If, for some reason, you really wanted to use that particular method, you could just new up a control and use the methods it exposes, but I would highly recommend against it.
#Code
Dim newControl As New System.Web.UI.Control
Dim resolvedUrl = newControl.ResolveUrl("~/index.html")
End Code
href="#resolvedUrl"
That all said, I would recommend using #Url.Content as it fits best with MVC paradigms
UrlHelper.Content() does the same thing as Control.ResolveUrl().
For Further References:
http://stephenwalther.com/archive/2009/02/18/asp-net-mvc-tip-47-ndash-using-resolveurl-in-an-html.aspx
You don't need to do this anymore in Razor v2.0/ASP.NET MVC 4.
Just use the "~" in a razor page and it will resolve it for you.
<link rel="stylesheet" href="~/Content/style.css" type="text/css" />
Source
In my case, I find #Href not being enough in the way it deals with query strings in a URL. I prefer to wrap it inside the Raw method:
<script>
var isKendoWindow = false;
var myTimeOut;
clearTimeout(myTimeOut);
var sessionTimeout = (#Session.Timeout * 60000) - 5;
function doRedirect() {
if (!isKendoWindow)
window.location.href = '#Html.Raw(Href("~/Logon.aspx?brandid=" + SessionController.LandingBrandId + "&errCode=5055"))';
}
myTimeOut = setTimeout('doRedirect()', sessionTimeout);
</script>
Or you can create your own version like this:
public static IHtmlString ResolveUrl(this HtmlHelper htmlHelper, string url)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
return htmlHelper.Raw(urlHelper.Content(url));
}
Another way to solve this issue:
Resolve the url in a code block at the top of the page or in code behind.
#page
#model IndexModel
#{
ViewData["Title"] = "Home page";
Layout = "~/Pages/Shared/_IndexLayout.cshtml";
String img1 = Url.Content("~/img/people11.jpg");
}
Then use the variable in the html.
<div class="col-12 col-lg-8" style="background-image: url('#img1');"> </div>
Server.MapPath() //returna full path
or
url.content()
try using Server.MapPath().

Resources