Difficulty with conditional databinding - c#

I've been struggling to find some way to do my required conditional binding.
I want to use Eval("products_image") in conditional binding in such a way that if product_image exists in images directory then it's ok, otherwise it should display "noimage.jpg".
I tried to do it this way:
<%# (File.Exists(("ProductImages/"+Convert.ToString(Eval("products_image"))))) ? ("ProductImages/"+Convert.ToString(Eval("products_image"))) : "ProductImages/noimage_small.jpg" ; %>
I have tried other ways as well, but every time, I mess up with a bunch of errors.
Can anyone guide me the right way to do this?

<%# (File.Exists(("ProductImages/"+Convert.ToString(Eval("products_image"))))) ? ("ProductImages/"+Convert.ToString(Eval("products_image"))) : "ProductImages/noimage_small.jpg" ; %>
Quite long and unreadable, isn't it?
I'd suggest adding a method to your code behind or in a <script> tag
// returns the imageFile parameter if the file exists, the defaultFile parameter otherwise
string ImageFileExists(string imageFile, string defaultFile) {
if (File.Exists(Server.MapPath(imageFile)))
return imageFile;
else
return defaultFile;
}
And then you'd simply use
<%# ImageFileExists("ProductImages/" + Eval("products_image").ToString(), "ProductImages/noimage_small.jpg") %>
Note that I've added a Server.MapPath call to the method so that File.Exists will actually look in the right place.

I just moved the whole <script> tag and System.IO namespace inside the usercontrol .ascx file itself and it did it.
Thanks a ton configurator for help :)

Related

asp.net mvc razor foreach loop adding id to div

I am trying to add dynamic id to div inside a foreach loop concatenated with value of variable i. It throws syntax errors. What might be the issue. Can we achieve this solution without using a for loop ?
#{int i=1;}
#foreach (var or in Model.Names)
{
<div oid="#or.Id" mode="0" oids="#or.Id" id="tr"+i>
#or.Name
</div>
i++;
}
You want to construct ID in C# segment of code. One option is to do whole construction with string format:
<div oid="#or.Id" mode="0" oids="#or.Id" id="#string.Format("tr{0}",i)">
Or id="#("tr"+i)" or id="tr#(i)"
Note that you can't do just id="tr#i" because the Razor syntax parser ignores "text#text" as it looks like a normal email address.
You can't append like this:
id="tr"+i>
It must be:
id="tr#i">
You need the #.. since it won't be able to deduce between markup and Razor at that point.
in the newly C# 6 you can directly use id="#($"tr{i}")"
for myself, none of this solutions worked but adding my #i first did work, id="#i+AnyText"
after building it, and inspecting ill get id="1+AnyText", for the
next one id="2+AnyText" and so on (im using 2013vs)..
hope that helps anyone, have a nice day.
After struggling with this for a while I found that id="#("tr"+i)" did the job for me

URL getting Appended when using Response.Redirect

I have a URL say /Registration/GetName.aspx/?language=English
When i click on a Asp.net Button on the same Page and say Response.Redirect("CheckLoginName.aspx");
It gives me a weird URL
/Registration/GetName.aspx/CheckLoginName.aspx
What should i do
Please Help?
You should use "~/" inside your Redirect
So your code will look something like this
Response.Redirect("~/CheckLoginName.aspx");
Hope this helps
You should remove the trailing / before the query string, since it serves no purpose. Your URL should be /Registration/GetName.aspx?language=English. Another option is to have Response.Redirect("../CheckLoginName.aspx"); This should also work.
I think a solution using a relative path is better, since it is location independant. If you move these two files to another URL, there will be no need for code changes.

Using Razor Templates to produce a .aspx page

I am trying to use a Razor template to produce a .aspx page as output. I'm not having luck looking in the documentation for how to do this. The Page and namespace declarations are breaking the template:
<%# Page Language="C#" Title="#Page.Metadata.browser_title" %>
<%# Import Namespace="System.Xml" %>
These are causing this error:
TemplateCompileException: CS1501: No overload for method 'Write' takes 0 arguments Line 27 Column 1: Write();
I assume this is because Razor templates using C# syntax makes the two conflict, since the declarations above use "#". Is there a way to get them to work together so a Razor template can produce an output with C# in the rendered product after the template is run? The example above also shows how the value for "Title" needs to be rendered out of the template.
The #s in the <% are invalid Razor syntax.
You need to escape them by writing <%##.
If you like Razor, maybe you should check out DD4T (http://code.google.com/p/dynamic-delivery-4-tridion/). It allows you to build a web site using ASP.Net MVC with Razor views.
You could write a C# TBB to add the tags after all your Razormediator templates or even better if you could add after the Default Finish Actions(if you're using one).
Quick and dirty sample code...
Item OutputItem = package.GetByName(Package.OutputName);
string OutputText = OutputItem.GetAsString();
// Page tag declaration..
string pagePretags = #"<<TWO LINES OF DECLARATIONs..>>"
string FinalOutputText = pagePretags + OutputText ;
OutputItem.SetAsString(FinalOutputText);
Hope this helps..

Replace asp:Image relative path (../../images) with absolute path on another server

i have a web application and all of its images are relative path,
for example '../../images/logo.png',
i need to change all of the images in the application to another domain,
for example : 'static.domain.com/images/logo.png'
is there a fast way to change all the data ?
of course the long option is to iterate all images and change them manually,
Replace all occurrences manually
Use custom image class, inherited from System.Web.UI.WebControls.Image, to make possible configuration of behavior regarding image path
In general you should encapsulate relative paths to resources in a code block, like this (using an ASP.NET MVC example as my classic ASP.NET skills are gettting rusty):
<%= Url.Content( "~/images/logo.png" ) %>
To map them to a different path than the default, you can either define a custom route that matches all *.png files (and any other used formats) or introduce your own helper extensions so that you can rewrite the above to something like this:
<%= Url.Static( "~/images/logo.png" ) %>
The easiest is like #TBohnen.jnr said
Why don't you do a find and replace
(ctrl + H) and replace "../../images/"
with 'static.domain.com/images/' risky
but should be the easiest?
you can write a httmhandler for handling .png files, and change their address there.
another way is to press ctrl+f and find and replace ../../ with your new address in entire solutions which takes a minute.

ASP.NET: dynamicly generating HTML, how to?

I've been doing ASP.NET a little bit (on and off) over the last year, but I've never come upon this challenge: I'm building a website right now which is quite simple, mostly based in HTML and Javascript. However, on one page, I need to read an XML file off the server, parse it, create HTML from values contained in the XML file, and output it as the response. I am going to use ASP.NET with C# for this. I understand how to parse the XML and generate the HTML code in C#, but how do I write the HTML code into the response/into the page? The generated dynamic HTML is only in one big div in the page, and the rest of the page is static. What is the best way to do this? As I've never done anything like this before, I'm guessing that one way to do it would be to clear the whole HTML source of the page and use Response.Write() in the Page_Load event to write in the whole HTML of the page, with the XML values already inserted. Is this the correct method, and if so, could you give me a few lines of code as an example to make sure that I'm doing it right? Thanks!
Also, as I've never had the opportunity to do this before, what is the best way of reading a file in ASP.NET C# that is located on your server?
UPDATE: Thank you for all the answers! I have found the solution to my problem, and yet all three answers provided are good ways of approaching this challenge. As you can guess, it's a tough choice who to give the accepted answer to, but I'm going to give it to this answer, by awe, because he clearly put a lot of effort into it, it's a quite elegant solution, and he answered both my questions. Thank you all for the wonderful answers!
Create a div that is accessible in server code:
<div runat="server" id="xmlGeneratedContent"></div>
In Page_Load:
xmlGeneratedContent.InnerHtml = parcedHtmlFromXml;
EDIT:
As answer to the last question: how to read a file on the server...
If the file is located under the web site, you can use Server.MapPath to get the physical disk location from the relative url:
string filename = Server.MapPath("files/file.txt");
How to read it depends on what kind of file it is, and how you want to read it. If you want to read it as plain text, here are some methods:
Read all at once:
string content = System.IO.File.ReadAllText(filename);
Read all at once into string array containing the lines:
string[] content = System.IO.File.ReadAllLines(filename);
Read one line at a time:
System.IO.StreamReader sr = new System.IO.StreamReader(filename);
while (!sr.EndOfStream)
{
string line = sr.ReadLine(); // or other method reading a block
//Do something whith the line
}
sr.Close();
sr.Dispose();
In codebehind function:
public string getHML()
{
return "htmltext";
}
on Page:
<div><%=getHML()%></div>
Just to add to the diversity: My favorite solution is to use
<asp:Literal runat="server" ID="myLiteral" />
And then in code:
this.MyLiteral.Text = "Generated HTML goes here";
The advantage over a <div> is that this generates no extra HTML - so you can put it wherever you want and generate whatever you want.
Often I also set EnableViewState="false" on it, if I can easily regenerate the contents on every request. This cuts down on the ViewState size, because the myLiteral.Text is also saved in ViewState.
Well, your own suggestion would certainly work. Clear out all the html in the ASPX page, and in the Page_Load event you'll do this:
Response.Write(System.IO.File.ReadAllText(yourFilePath));
I don't think there's much more to it.

Categories