Custom Server Control and Image Handling - asp.net

I am currently trying to create a custom server control in asp.net c# and am using VS2010.
I am trying to create a custom server control that can load images straight into a separate web project. E.g. Custom Server Control and a separate web project where I can drag and drop my control onto it with minimal installation and config. The point being it can be re used anywhere on other web projects.
I have created a basic custom control, but I need to be able to load images directly through the custom server control and display them in my separate web project. The images will be coming from a static location for the time being.
So basically I have an image, I want to load and pass that image into the control and then display it on a webpage where the custom control is placed. I have investigated image handlers, and having separate generic handlers but am not having any luck.
Image location --> Custom Control --> Web page displaying image that has been passed into custom control.
Anyone have any idea how to do this, or go about this?
UPDATE:
I am sorry I was not clear enough first time round.
I have two projects, one custom control project, and one asp.net website project. The first project (Custom Control) takes a byte stream from a webservice and converts it to an Image object. At this point I want the control to add that image to a webpage in the website. The custom control is then registered with the asp.net website and the controls I have added are rendered to the page. However I want to render the image I have recovered from the buffer, then converted to a file locally onto the web page.
I have no problem getting the image from the bytestream, and storing the image in a directory. The issue I am having is that I want the image to be rendered on the webpage, without having the image stored in the web project at first. I have thought about storing the image in a web directory so when I run the project I can set an image url to localhost/images/myimagefrombystream.jpg but am unsure whether this is the correct approach.
Any ideas?

We have a server controls library that contains some images that are reused across a number of other web projects.
The approach we took was to mark the each images build action as Embedded Resource. Then in the AssemblyInfo file we have lines like the following:
[assembly: WebResource("AssemblyName.SubDirectory.ImageName.png", "image/png")]
Where AssemblyName is the actual project name, the SubDirectory is the directory in the project the image(s) are located in, etc.
This project also emits CSS files; which are also Embedded Resources. The CSS files refer to these images using:
.someImage {
height: 85px;
background-image: url(<%=WebResource("AssemblyName.SubDirectory.Image.png") %>);
background-repeat: repeat-x;
margin: 0px;
padding: 0px;
}
In the class code, we'll refer to those css files like:
HtmlLink cssLink = new HtmlLink();
cssLink.Href = Page.ClientScript.GetWebResourceUrl(this.GetType(), "AssemblyName.css.SomeCssFile.css");
cssLink.Attributes.Add("rel", "stylesheet");
cssLink.Attributes.Add("type", "text/css");
We could just as easily refer to the images directly using something like the above.
At this point the assembly is 100% portable. All of the CSS files and required images are embedded into it so you don't have to worry if the calling application has those same images at all.
Incidentally, this is how a number of control vendors do things; at least the better ones.

I don't know why you're complicating. Simply, add ImageUrl property (not public field) to your custom control, expect the client-code of your control to set it, and if not null, in CreateChildControls add an Image control to the control tree. Alternatively, add the image to control-tree always, but make it visible/invisible from within the setter of that property (or elsewhere you see fit). I didn't understand half of what you said related to your envisioned solution, to be honest - so, I hope I didn't miss the topic here :)

I'm not sure I understood the question, but let me try anyway.
As far as I understood you have two projects, in one you want to upload an image to a certain location, in the other one you want to show that image.
I would simply have a file upload control in the 1st application, and use it to upload the image to the desired location.
In the other application you can use a generic handler. The handler can get the image file name from the 1st application using query string parameters, then it will locate the image on disk and return a response with a proper header, for example:
response.ContentType = "image/jpeg";
response.OutputStream.Write(image, 0, (int)request.InputStream.Length);
response.Flush();
response.End();

I assume that you have created this custom control in a class library. of the image source is static (some fixed base url) and just that image name changes you can expose a ImageUrl property (string) and render a tag based on the attributes (all can be default) with the custom ImageUrl as the src attribute of the tag.
Hope that helps!

Related

How to access transformed html page in Custom Page Deployer?

Let's say we have to access the content of our published page in a Custom Deployer.
This part of the code is inside the processPage method that is in our CustomModule that extends PageDeploy class.
This way I will get the page that is being published, but content of that page will not be transformed (components that are in that page are not rendered).
public void processPage(Page page, File pageFile) throws ProcessingException {
File file = new File(pageFile.toString());
}
If I know that I can disable cleanup of the TransportPackages in cd_deployer.conf.xml, by changing the Cleanup to false: <WorkFolder Location="C:\tridion\work" Cleanup="false"/>,
I see that Tridion generates two versions of my page:
root\page.html (that has unrendered content, with path pageFile.ToString())
root\transformed\page.html (that has complete content - content that I want)
Why then when I create new File with the transformed page file path and read it, I get html code with even less content then the original html? Is this because in this phase of the deployment page is still not rendered and complete or...?
Thanks!
Is your page using Dynamic Component Presentations? If so, the Page-level HTML that is published and deployed will only contain an "include instruction" for the Component Presentation
<tcdl:ComponentPresentation ... />
The only thing that happens during deployment is that the "technology agnostic" language used during publishing/transport is translated into either a JSP tag or a ASP.NET server control include, in both cases it typically translated into something starting with tridion:ComponentPresentation.
The HTML fragment of the Dynamic Component Presentation itself will be published separately and stored as a separate item in the configured storage.
The complete HTML will only be composed when the page is requested (for serving to a visitor). At that stage the JSP tag library or ASP.NET server control will be invoked, read the HTML fragment for the Component Presentation from the storage and inject it into the HTML "wireframe" of the page.
With that knowledge, it indeed explains why you can't find the HTML fragment for the Dynamic Component Presentations in your Deployer extension: the merging of the DCP fragments into the Page shell only happens when the page is requested, not when it's deployed.

Captured Image & show it next page in Silverlight asp.net

I have an Web-application in which I capture Image using EdgeCamShots Sample Application
Saving Silverlight 4 Webcam
how can I use this capture image to be used in Next Page without saving Image.
A view model object reference (created from the application's MainPage) would be an object that both pages would have access to. Pass a reference to the pages on navigation changed event. That view model might make a good container for the stream and would give both pages access to the stream.
You can simply pass the stream (mentioned in the code example on the link you provided) to the next page using REST (adding the variable in the URL e.g. http://mysite/page2.aspx?stream=dstStream).
From there on, you can use the variable to show your picture.

Load image dynamically into asp:Image control

I'm using an asp:FileUpload control to give the user the chance to look for an image on the hard drive, once the user has chosen the image, after a button is pressed, I want to display the image in an asp:Image control.
I've been trying to get the full path of the file but I can't get it, I'm using Path.GetFullPath(FileUpload.FileName) but I'm getting a totally different path, not the path to the image that the user selected.
I was reading that I need to set the src attribute of the asp:Image control to be an aspx page which is going to return the image, and then I have to write the bytes from the image to the response but I'm not sure how to do this (I'm a newbie in web development), I don't know what should I put in my event, in the code behind, or what code should I place on the aspx page that will return the image, neither how to call the aspx page with the image from the event handler.
Can anyone show me a good example on how to achieve this please?
The issue here is the file being uploaded resides on the client computer where the asp:image control is looking for an image on the server computer.
What you should be doing is on the form submit/button click save the file into the application folder then reference that file with your asp:image control.
You can use the project mentioned below to preview the image before uploading. Working sample is also attached.
http://www.dotnetspider.com/resources/40858-Preview-Image-before-uploading-using.aspx
This uses AjaxControlToolKit's AsyncFileUploadControl and HTTPHandler to upload the image.

Compile web application project ascx into dll

Is it possible to compile a web application project .ascx (user control) into a dll?
I want to do the following:
Use the same control in multiple websites
Embed css and .js as resources into the control
Be able to update super easy. If the user control updates, I just want to update 1 .dll
I have successfully followed this article, http://msdn.microsoft.com/en-us/library/aa479318.aspx.
However, that uses web site projects, and I cannot embed js css as resources into web site projects.
Any ideas? Am I going about this wrong, should I change the approach?
Conversion is easy, and could even be fully automated. It simply requires changing a few settings and base classes in the DLL Project you want your ASCX controls embedded in.
1... For each UserControl, set the ASCX file's Build Action (under Properties) to "Embedded Resource", and delete its associated designer file.
2... Save the project.
3... Right click the project and choose "Unload Project".
4... Right click it again and choose the "Edit *.csproj" option.
Change sections that look like this (where the asterisk represents your class name):
<Compile Include="*.ascx.cs">
<DependentUpon>*.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
to look like this
<Compile Include="*.ascx.cs" />
That will cause the code-behind files to be compiled independently of the ASCX files.
5... Save changes, and right click the project and choose "Reload Project".
6... Open all your "*.ascx.cs" files and make them inherit from the following custom UserControl class, instead of the System.Web.UI.UserControl class (you may need to locate parent classes to complete this step).
public class UserControl : System.Web.UI.UserControl
{
protected override void FrameworkInitialize()
{
base.FrameworkInitialize();
string content = String.Empty;
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream( GetType().FullName + ".ascx" );
using (StreamReader reader = new StreamReader(stream))
content = reader.ReadToEnd();
Control userControl = Page.ParseControl( content );
this.Controls.Add( userControl );
}
}
This base class will take care of loading and parsing the embedded ASCX file.
7... Finally, you may need to place ASCX files in subfolders so that their resource names (automatically determined by folder path) match the full type name of their associated class (plus ".ascx"). Assuming your root namespace matches your project name, then a class named "ProjectName.Namespace1.Namespace2.ClassName" will need its ASCX file in a subfolder "Namespace1\Namespace2", so it gets embedded with the name "ProjectName.Namespace1.Namespace2.ClassName.ascx".
And that's it! Once you compile the DLL and include it in another project, you can instantiate instances of your user controls using the "new" operator, like any other class. As always, your control will be "caught up" to the current page event once added as a child control to the page or another control on the page.
It is difcult to use user controls in this way due to the markup ascx file. If you want to create reusable control libraries your are much better off creating custom controls.
Another way would be to convert user control to the custom control. There is an nice article on MSDN: Turning an .ascx User Control into a Redistributable Custom Control which describes exactly how to do that. Here is the summary:
Write your user control as you normally would, typically using the Visual Studio designer.
Test it using a simple page before trying to deploy it.
Deploy the application to precompile it.
Grab the user control's assembly produced by the deployment step,
and you're essentially done: You have your custom control.
Finally, use your custom control in other apps the same way as you
always use custom controls.
Hope this helps.
I had to do it once and I followed this article
http://www.codeproject.com/KB/user-controls/EmbeddedUserControl.aspx
It's based on the possibility of mounting a virtual file system on different places (an assembly, database, etc)
There are quite a few articles out there on how to do exactly that:
http://www.nathanblevins.com/Articles/Compile-a-Web-User-Control-into-a-DLL-.Net-c-.aspx
http://blogs.msdn.com/davidebb/archive/2005/10/30/487160.aspx
I know this is old, but yes its possible.. I do it all the time, see https://kocubinski.wordpress.com/2013/05/06/compile-asp-net-webforms-ascx-usercontrols-into-assembly-for-re-use/

Strange Problem with asp.net website

I've built an asp website and i have the following issues:-
i'm using a master page in it and have defined two contentplaceholders one in head one in content, and i've specified the page title in the top most directive at the #page directive but the page title doesn't show up. I have to manually add a tag for it.
Secondly when i create a content page from a master page it creates it and when i rename it, it doesn't rename it's class. It remains _Default, thus every page was having an inherit to _default.
Most importantly
I'm using a page to enter and view data to the database. I've used a boolean called isadmin which i set according to credentials at page load. and i'm added a panel where it's visible property is set to Visible = '<%#IsAdmin %>'. It works properly when i run it through the visual studio environment but when i publish it and run it doesn't work and the panel just comes and stays there. Why is it happening? Any idea?
Thanks
The Visible problem is fixed as i had to enable windows authentication on the server. Awaiting answers for the other two issues. Thanks
Try to add a <head runat=server> to the master page. Only then ASP.net can "see" the tag and modify it
It is not that bad that several aspx-pages have identical class names. ASP.NET 2.0 started to process every page as its own compiling unit or so. Pages cannot see each other. There is a special directive to make pages see each other and instanciate or manipulate them. So it should not do much harm
Maybe you did not test this correctly and are mistaken that it DOES work in Visual Studio??? But in any case I would suggest that you move your logic into OnInit, then it runs much earlier. I think the control tree is build before Page.OnLoad. What you do is data binding, that might run only if DataBind is called, I'm not sure
Or use the safe way: Make IsAdmin a property so that it initializes itself on first call and caches the result in a variable
Regarding question #2 - add your content pages via Project -> Add New Item, and name it appropriately there. That way the naming is consistent and correct throughout.
Regarding #3, what HTML is output when you run it from the server?
your first issue can be solved by filling out the title part of the #Page directive in your .aspx pages. The master page will display that text in the browsers title bar.
and prob #2 should be solved by adding the files using the file add option in visual studio.

Resources