I have an ASP.NET MVC 2 app targeting .NET 4 that needs to be able to resize images on the fly and write them to the response.
I have code that does this and it works. I am using System.Drawing.dll.
However, I want to enhance my code so that not only am I resizing the image, but I am dropping it from 24bpp down to 4bit grayscale. I could not, for the life of me, find code on how to do this with System.Drawing.dll.
But I did find a bunch of WPF stuff. This is my working/sample code (runs in LinqPad).
// Load the original 24 bit image
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri(#"C:\Temp\Resized\18_appa2_015.png", UriKind.Absolute);
//bitmapImage.DecodePixelWidth = 600;
bitmapImage.EndInit();
// Create the destination image
var formatConvertedBitmap = new FormatConvertedBitmap();
formatConvertedBitmap.BeginInit();
formatConvertedBitmap.Source = bitmapImage;
formatConvertedBitmap.DestinationFormat = PixelFormats.Gray4;
formatConvertedBitmap.EndInit();
// Encode and dump the image to disk
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(formatConvertedBitmap));
using (var fileStream = File.Create(#"C:\Temp\Resized\18_appa2_015_s2.png"))
{
encoder.Save(fileStream);
}
It uses System.Xaml.dll, WindowsBase.dll, PresentationCore.dll, and PresentationFramework.dll. The namespaces used are: System.Windows.Controls, System.Windows.Media, and System.Windows.Media.Imaging.
Is there any problem using these namespaces in my web application? It doesn't seem right.
If anyone knows how to drop the bit depth without all this WPF stuff (which I barely understand, BTW) I would be thrilled to see that too.
No problem. You can easily use WPF for image manipulation from within an ASP.NET web site. I've used WPF behind the scenes within a web site several times before, and it works great.
The one issue I did run into is that many parts of WPF insist the calling threads be STA threads. If your web site uses MTA threads instead you will get an error telling you that WPF needs STA threads. To fix this, use the STAThreadPool class I posted in this answer.
My understanding (and I can't find a citation right now) is that this is officially not supported. However, in practice, it seems to work pretty well and you would not be alone in using these libraries in a Web app. Also, even if you can find a way of doing this with System.Drawing, I believe that officially that's not supported in the Web environment either -- though it is more widely used in that environment than WPF, which gives you an extra level of reassurance.
Related
(TLDR? Skip to the last couple of paragraphs for the questions...)
I have a classic ASP.Net site which was originally built around a data access layer consisting of static methods wrapping around ADO.Net. More recently, we've been introducing abstraction layers separated by interfaces which are glued together by StructureMap. However, even in this new, layered approach the repository layer still wraps around the old static ADO.Net classes (we weren't prepared to take on the task of implementing an ORM whilst simultaneously reorganising our application architecture).
This was working fine - until today. Whilst investigating some unexpected performance issues we've been having lately we noticed a couple of things about our data access classes:
Our SqlDataConnection instances aren't always being closed.
The connection objects are being stored in static variables.
Both of the above are bad practice and likely to be significantly contributing to our performance problems. The reason why the connections were being set in static variables was to share them across data access methods which is a good idea in theory - it's just a terrible implementation.
Our solution is to convert the static data access classes/methods into objects - with our core DataManager class being instantiated once at the beginning of a request and disposed once at the end (via a new PageBase class in the web layer - much of our code is not yet separated into layers). This means we have one instance of the data access class which gets used for the entire life cycle of the request and therefore only one connection.
The problem starts now when we get to the areas of the site using the newer layered architecture. With the older code, we could just pass a reference to the DataManager instance directly to the data access layer from the code behinds but this doesn't work when the layers are separated by interfaces and only StructureMap has knowledge of the different parts.
So, with all of the background out of the way here's the questions:
Is it possible for StructureMap to create instances by passing previously instantiated objects as dependencies - within the context of a single ASP.Net Page lifecycle?
If it is possible, how is this achieved? I haven't seen anything obvious in my searching and haven't had to do this in the past.
If it is not possible, what might be an alternative solution to the problem I've described above?
NOTE: This may or may not be relevant: we're calling ObjectFactory.BuildUp( this ) in a special base page for those pages which have been converted to use the new Architecture - ASP.Net doesn't provide a good access point.
Okay, this wasn't so hard in the end. Here's the code:
var instantiatedObject = new PropertyType();
ObjectFactory.Configure( x =>
{
x.For<IPropertyType>().Use( () => instantiatedObject );
x.SetAllProperties( p => p.OfType<IPropertyType>() );
}
);
We just put this in our PageBase class before the ObjectFactory.BuildUp( this ) line. It feels slightly dirty to be putting IoC configuration in the main code like this - but it's classic ASP.Net and there aren't many alternatives. I guess we could have provided some abstraction.
For many years I have had an objective of moving out of ASP/VBScript to a "better" language - my preference would be C# as I have skills in C - but I would consider other languages too (including PHP etc. so not just DotNet)
Objective is to have the code base in a language which does more for us. I hate the lack of data typing in VBScript, I would like a number of different "container objects" - rather than just a Dictionary Object, and so on - in fact I wonder why, having moved from Basic to C in the 80's, and then C++ a while after that, I managed to move "back" to Basic in to 00's.
(I could program the container objects in VBScript, but my instinct is that they would be slow in operation; we have a significant cache of "snippets" of HTML used in the rendering of the page, the ASP Application Object is a pretty blunt instrument!)
My ASP/VBScript is a single large application that is basically an "engine" to deliver web content.
It has been many years in the making, and now the ASP code changes seldom. (So I do need to justify moving it at all, or just living with VBScript "for ever")
It is driven from data in an MS SQL database.
There is only one .ASP page (made up of several include files).
Based on the query string parameters Skin and CMS templates for the page are loaded from database and suitable database Sprocs are run to acquire data which is merged into the CMS templates.
Data about the page (methods to use, etc.) is also retrieved from the database, along with details of access permissions and so on.
From what I have read some these things may make migration easier:
ASP sessions are not used - a session cookie is used to retrieve session data from the DB (so I could easily share a session half-and-half with ASPX
The VBScript uses OPTION EXPLICIT throughout, so all variables are predefined.
All output is via Response.Write (in fact most content is merged into a single variable and then output). There is no mix of HTML and <% server code %>.
I have some VBScript classes, but not many.
I have lots of VBScript functions, and a few Subroutines.
I have a test suite. This catches screen shots from the browser and graphically compares them with master images - thus I have the ability to do a regression test.
I don't have the resource to do a complete rewrite; maintenance of the existing code needs to continue during migration; but having said that 99% of our work is in CMS or SQL Sprocs, so the changes to ASP code are infrequent.
I have read of MS's utility to migrate ASP code to VB.NET. Given that my code is 100% VBScript and no mix of HTML/Script I would appreciate opinions on whether this would help me a lot or a little?
I would be happy to refactor STAYING IN VBscript with a view to making the migration to DotNet easier later on (but I'd need to know what my objectives were in doing that :) ). I could, for example, move some/all the functions to a COM object, and could probably do that piecemeal?
Thanks for your help
I have a large ASP classic intranet that I was maintaining until last year, and it was getting old, but new pieces were still being added in ASP classic because there was so much library code invested already. You already have a good setup if you are not changing the ASP code often and have some form of testing in place. (I have to admit it's the first time I have heard of the screenshot approach). If everything is driven off the DataBase and working. don't break it.
PHP will give you same problem of variant types, but will give you a world of options and choices that makes ASP classic seem like a childs toy. Out the box PHP does everything I've ever needed to do.
ASP.net is a BIG framework. Understanding it properly and fully is not an easy task, and it surprises me very often. it tries to do things for developers coming from a forms environment automatically that get very obtrusive when you come from a very precise rendering methodology like you sound you have. I found myself fighting the technology all the time, until ASP.net MVC came around. It fit my mind better because of how it worked and did what I asked it to, and nothing more. C# is an awesome language, with brilliant features and the DOT.net framework lets you do anything, if you can just find the right pieces. There is so much of it you will find yourself occasionally writing something that has been done in the framework already, only to find it just after finishing your own implementation.
Actually migrating could lead to some interesting problems. Even though you CAN run a ASP.net page much like an ASP classic page, you will loose many of the benefits of the environment as it is intended. That being said, I did do some test towards looking at migrating the site in question to ASP.net and managed to find ways around most of the stumbling blocks and reached the conclusion that such a migration would in fact be "mere work". The sheer quantity of man-hours it would take to do such a migration though made the undertaking infeasible.
Personally I would not suggest such a migration unless you have a few ASP.net projects under you belt successfully and are aware of the gotchas that asp.net brings with-it.
I have not seen the ASP to ASP.net conversion tool you speak of, but would love to get a link to it.
If you are staying in VBScript and are not aware of the AXE (ASP Xtreme Evolution) project here I can highly suggest looking into it for inspiration on getting past/around several of the ASP classic "limitations" and for the library of functionality it provides.
If you are looking for a way to justify the project to management, it will become increasingly more difficult to find classic ASP developers to continue maintaining the application. Any developer that has a choice would probably not choose to maintain an application built using VBScript. Developers that do take the job might consider it temporary and continue to look for other work.
Although I haven't heard anything from Microsoft, it can't be too many years before they decide to retire classic ASP entirely.
We have an application that makes heavy use of the RDS.Dataspace.
As in :
set objDS = CreateObject("RDS.DataSpace")
set objJB = objDS.CreateObject("JBdbio.dbio","http://<%=Request.ServerVariables("SERVER_NAME")%>")
To instantiate and then:
NewQry 2,"QryUpdtItem" ' To set the name of the stored procedure
AddParam 255,"ISBN",200,txtISBN.value 'params
AddParam 255,"Titl",200,Title.value
m = objJB.UpdateQry(arrPrm) 'do the call to execute the stored procedure
Some do updates, some selects, etc
With RDS now obsolete for a number of years. How can I keep my asp code and have a Dataspace to attach to my business object (JBDBIO).
Essentially we just pass all of our params and stored procedure to this business object and then just dish up the results.
And if I were to move this to .net - how could I do the same without ajaxing it -- this is all vbscript code that runs, in effect an application within IE
Its time for a complete redesign. VBScript in IE is just not something that you want to be taking forward.
If you still want to use the browser as a means of delivering an inhouse UI then consider ASP.NET-MVC. If you want to attempt to make the UI smooth in the browser then inclusion of AJAX is the direction you need to take.
OTH in your case it may be worth you considering the delivery of the UI in a non-browser medium. For example a Silverlight3 using Ria services may be a way forward, XBAP or Click-once installs may also be an option.
No matter what choice you make its going to be a steep learning curve to move away from ancient RDS/VBScript in the client. You may as well take the opportunity to re-visit the UI behaviour as well.
You said it "flickers" on postbacks in the page your guy had rewritten to ASP.NET, didn't the old version "flicker" on postback (submit)? And wow did the .NET code look like if you have not already found any .NET replacement for the database code?
Or have I not understood right, is the VBScript you are talking about client side VBScript? In that case you can actually use the old client side VBScript in the .NET page as well (just as you can run JavaScript on the client side).
If this does not point in any direction to a sollution, I think you might have to provide some more details with code examples, and what you want to acheive.
I'm implementing some objects which will have about an equal amount of richness on both the client-side and server side.
In this particular case, I'll be building a (hopefully) little class library to deal with search tokens. So as a pseudo-code example, I'll want to be able to do the equivalent of the following in both Javascript and on the server (C# in my case).
s = new SearchTokenList();
s.Add(new SearchToken(field, value, negation));
What design strategies will help avoid creating a big ball of mud for a library which must span C# and Javascript?
Update: Looking for more of strategies than mechanics. But I'll take any guidance I can get from those who have previously done similar things.
Take a look at Script# by Nikhil Kothari, might help you out. It is a C# to JavaScript compiler.
I think you should check out my C# to JavaScript compiler out at http://jsc.sourceforge.net/
Unlike Script# my jsc compiler works on MSIL level.
WPF Example: AvalonExampleGallery
Contact me if you have any specific questions.
If performance is not critical, you could load the data in JSON or XML and pass it back to server-side and do the processing. I think WCF can generate JavaScript interface out of the box. See .NET by Example: Calling a WCF service from Javascript.
You should be able to run some Javascript code on your .NET server using Microsoft's JScript.NET -- compile it with /target:library and make sure it's CLS-compliant and that you declare that fact with
[assembly:System.CLSCompliant(true)]
or other variants of CLS compliance declarations. Once you've gotten this to work, you could run (a bit of) JS code on both the server (calling it from C#) and the client (calling it from other JS) and more easily ensure equal functionality on both sides.
Can a flash front end talk to a .net backend?
Yes.
We use Adobe Flex to talk to .Net XML web services.
Be careful with complex serialised .Net types (for instance DataSets) - ActionScript can't handle them.
Instead produce simple XML with primitive types.
See also: Flex and ADO.NET Data Services...anyone done it?
<mx:WebService id="myDataService" showBusyCursor="true">
<mx:operation name="WebMethodName" resultFormat="object" result="functionFiredOnComplete();"></mx:operation>
</mx:WebService>
public function load():void
{
myDataService.loadWSDL( "web method's wsdl" );
myDataService.WebMethodName.send( params );
}
public function functionFiredOnComplete():void
{
// get data
var myData:Object = myDataService.WebMethodName.lastResult;
...
Flash can also talk to the hosting page via JavaScript.
you could also try AMF.NET, a .NET implementation of Flash Remoting using ActionScript Messaging Format (AMF)
http://amfnet.openmymind.net/overview/default.aspx
Yes
Best keywords to search for are Flash .net and Flex
In the old days there was another tool but with Flex its all been simplified.
If you are de/serializing a lot of objects (which Flash/Flex isn't particularly fast at), or more complex types, then you might want to take a look at WebOrb. It's a free object broker, which might sound scary, but it basically handles translation between the native object types of the two technologies. It pretty much "just works", and can increase performance quite significantly in some situations.
It also comes with a code generation tool if all you want is CRUD and stored procedure access for a SQL database, which is quite nice.
I would recomend FluorineFX we use that at work and its great. The only downside is that we end up with a lot of value objects that are only used to transfer data between .net and flex. And the fact that the standard C# naming style and the flex naming style has some minor differences makes value objects a bit ugly in either flex or .net.
My older brother and I developed several methods for Flash/.Net communication. I've seen web services mentioned above (which is a great way of doing it), but we also used simple .aspx pages and had stuff passed via querystring (poor man's way of doing things), using Flashvars to get data TO Flash, but my favorite - Using .Net and a repeater control to build xml files which were then consumed by Flash. We created some pretty cool stuff doing that!