How do you show your asp.net app version? - asp.net

Setting the scene:
My asp.net web application carries a version number which is incremented during every release. We're releasing every week internally for our test team and after four weeks or so to our client.
The question:
I want to include the version number on our application. What methods have you used so that your web app carries the version number? meta tag? simply added it to the footer?

If you are in contact with the client a lot (for bug fixes or changes) you should keep the version number in a place that is easy to find (such as the footer). You will find yourself asking the client what version they are running, if they cannot find it it is frustrating for both the client and the support staff.
Make sure your footer is a user control or that the version is stored in either a database table or a resource file so that you update once rather then going through each page updating. My recommendation is a user control and if you want to track versioning store the version numbers in a database and read it into your user control.
You can take the MS route of doing a help->about given a menu and displaying the version number in say a js popup or on another page.
If for some reason you do not like the version number on a footer or even a help menu popup and you do not deal with the client regularly you can put it as meta data or in the source code of your HTML.

I've seen a lot web applications (and websites) I've seen that add the version number as a comment within the generated HTML. The BBC is one of them - view the source and you'll see <!-- Barlesque v34.8 --> in the header. (Barlesque is the BBC's layout system.)

We have some information page where we display the version number (SaaS application).
But seriously, with web software version numbers are irrelevant. It is the point of migrating to the web - so that the users finally forget about those versions, updates, service packs etc. Otherwise the idea of a constantly updated web application (perpetual beta) is not really grasped by either party.

In some Projects we added the Version number to the footer. We displayed the Assembly (any of our Assemblies) Version number.
With that method we did not have to care about the text in the footer as long we incremented the Assembly Version.
Assembly Version was extracted with Reflection.

Check out the code posted here. It will gather and display the .NET Framework version info. Anytime you need the version information of the current assembly, you can use
Assembly.GetExecutingAssembly().GetName().Version
Similarly, to get the version info for a particular assembly, you can either reflect directly on the assembly, or simply use a class in the assembly
typeof(ClassKnownToBeInTheTargetAssembly).Assembly.GetName().Version
where ClassKnownToBeInTheTargetAssembly is a class declared in the assembly you want the version info for.
BTW, these comments assume that the assemblies are signed.

Related

Business Central Identifying Object form vs Extension Form

I'm also one of many who has begun development work in Business Central. I'm currently in-charge of migrating C/SIDE to AL. My question is, is there a way to identify whether something is in Object form or Extension form? The documentation I have from a third-party vendor says:
"All of company XYZ's products are available in both Object form and in Extension form. Existing customers who want to migrate from the Object version of a solution to the App version will need to go through a migration...."
First a little clarification:
Object form means that the modifications have been done through C/Side.
Extension form means that the modifications are isolated within their own package with one or more dependencies to other extensions. These are not visible in the C/Side Object Designer.
When modifications are done through C/Side the system generates symbols to simulate the extension interface. This provides the needed features to extend C/Side objects.
The easiest way to determine if a modification is in Object or Extension form is to check which extensions are installed on the system. This is can be done in two ways:
In the Business Central client go the the Extension Mangement page. Here all installed extensions will be listed (apart from a few hidden Microsoft extensions that you need not worry about).
Run the command Get-NAVAppInfo through PowerShell. This will list all installed extensions on the requested tenant.

Need to get the XML of a component's that version which is published

We are iterating the components in a folder in Tridion 2011 and creating our custom XML to be used on CDS on the basis of the publishing status of component. I am giving below example to make you understand the problem.
Supppose we have 10 components in a folder which are all published and we publish our XML then the XML gets generated for 10 items.
Now we make change in one of the component and don't publish it.
After modification of component, we publish the XML again. then the XML get updated for the modified component also. So it creates the difference between the published version of that component and the that is in our XML.
So I want to publish the custom XML in such a way that it should only contain that data which is in sync with published version of component.
So you want to:
determine the XML of the Component that was last published
determine the changes between that XML and the current XML of the Component
only publish the changes
Tridion doesn't keep track of the version that was published (on the Content Manager at least). So the closest you can do is find out when the Component was last published and retrieve the XML of that time. This question is a great starting point for more information on that approach. Based on that XML you can then do steps 2 and 3 above.
Alternatively you can keep a snapshot of the XML that you published "somewhere" (for example in Application Data) when you're rendering the Component. Then when the Component gets published next time, you can retrieve that XML and do steps 2 and 3 above.
Note that with any of those solutions you should really wonder if you should be implementing it to begin with. You are overriding some of Tridion's default rendering behavior and circumventing part of its architecture (a clear, explicit disconnect between Content Management and Content Delivery, with the former knowing "nothing" about the latter) and anything you do will come back to haunt you in time. In this use-case you have to wonder what will happen when the CDS and TCM get out of sync. Simply republishing the content suddenly won't be good enough anymore, since your code will be in there deciding that "nothing changed since last publish, so we'll publish nothing".
Please forgive me if I jump to conclusions, but I strongly feel this question has arisen from a lack of understanding of Tridion. Publishing in Tridion does more than just raise a flag to indicate the item is 'published', in other words ready to be shown to the outside world. I know this is how some (many) content management systems operate (which may explain why you are asking this question).
In Tridion, however, publishing means that the item is actually - physically - transferred from the content management environment to the content delivery environment. This environment always contains versions of your content that represent the state when the item was last published - simply because it was the very act of publishing that created them.
In my opinion, what you are really asking is how to rebuild this publishing functionality. This is never a good idea. Instead, you should take Bart's comment seriously and look at one of the content delivery APIs that Tridion has on offer (the broker API or the OData web service). Optionally you might want to look into DD4T, which is built on top of the broker and exposes the full Tridion data model.
Then your solution is to
Write an event handler on the Publish Transaction Save event
Which saves the publish info (version data) to Application Data of the published Component
I'm mentioning the Publish Transaction Save event because from there you can ensure that the publish info is only saved when the transaction is successfull.
Also be aware that this publish info can go out of sync when the event handler fails to execute, and you might loose all of the application data when moving to another environment.
So when this information is absolutely crucial I would save it to a separate database, and not to Application Data.

Better way to handle page that links to hundreds of binaries?

I've struggled with a better solution for the following setup. I'm not actively working on this, but know some that might appreciate other ways of handling this.
Setup:
Tridion-managed page has a single "linked list" component Linked list
Single component has component links to other components in Tridion
Linked-to components often link to multimedia component (mm)
An XSLT component template (XSLT CT) renders XML with above content and with links to PDF
XSL document() function used to grab embedded (linked-to) content, all content converted to XML nodes and attributes
TCMScriptAssistant namespace with publishBinary() publishes related PDF and other media
Page template just outputs the result of the CT
Business requirements:
improved publishing (last I worked on this, some of these files created a 2GB publishing transaction because of the PDFs)
published XML content file must reference the associated PDFs; hyperlinks work but identifiers might not help because of...
no Tridion content delivery APIs, mainly for independence from the storage database but also to avoid Tridion-specific code on the presentation server (loosely coupled setup and less training for developers)
The biggest issue is the huge transport package during publishing. The second problem is publishing any of the linked-to PDFs will cause the page to republish.
How could this setup be improved or re-engineered, preferably without too many changes to the existing templates, though modular templating could be considered.
Dynamic component presentations could possibly work, but would need to be published to the file system and not use dynamic linking or broker objects (e.g. no criteria filters, binary metadata, etc).
There are indeed 2 questions. I will handle them in reverse order.
To prevent the page from being republished when you publish a binary, you can use the event system in older versions of Tridion (pre-2011) to turn off link resolving, or with newer versions you can use a custom resolver to prevent this. There is an article by Nuno which explains this(http://nunolinhares.blogspot.com/2011/10/tridion-publisher-and-custom-resolvers.html)
Your second one is a bit tougher, in no small part because of your criteria for not using the SDL Tridion CD APIs. I would have suggested publishing the binaries separately (this would keep the file size down of your transaction package), and using Binary Linking to resolve the paths at request time.
Given this is not an option, I think the only was I would approach it would be to still use dynamic component presentations, and then use predictable unique file names for the PDfs (i.e. use something like 317-12345.pdf based on the URI), and use one directory for all the binaries. That way you could enter the paths to the binary using your XSLT template, as you know where the binaries will be located later. You could then use a custom resolver to publish the binaries when you publish the main list component or page.
Hope that helps
Chris

How to detect if ASP.NET is enabled in IIS 7

The challenge is to determine whether ASP.NET is enabled within IIS7 in a reliable and correct way.
Enabling/Disabling is done in this case by going into:
Server Manager ->
Roles ->
Web Server (IIS) ->
Remove Role Services ->
Remove ASP.NET
The natural place to determine this should be within the applicationHost.config file. However, with ASP.NET enabled or disabled, we still have the "ManagedEngine" module available, and we still have the isapi filter record in the tag.
The best I can find at the moment is to check if the <isapiCgiRestriction> tag includes the aspnet_isapi.dll, or that the ASPNET trace provider is available.
However these aren't detecting the presence of the ASP.NET config directly, just a side effect that could conceivably be reconfigured by the user.
I'd rather do this by examining the IIS configuration/setup rather than the OS itself, if possible, although enumerating the Roles & Services on the server might be acceptable if we can guarantee that this technique will always work whenever IIS7 is used.
Update
Thanks for the responses. Clarifying exactly what I want to do, I'm pulling settings from a variety of places in the server's configuration into a single (readonly) view to show what the user needs to have configured to allow the software to work.
One of the settings I need to bring in is this one:
The one highlighted in red.
I don't need to manipulate the setting, just reproduce it. I want to see whether the user checked the ASP.NET box when they added the IIS role to the server, as in this example they clearly didn't.
I'd like to do this by looking at something reliable in IIS rather than enumerating the role services because I don't want to add any platform specific dependencies on the check that I don't need. I don't know if it will ever be possible to install IIS7 on a server that doesn't have the Roles/Services infrastructure, but in preference, I'd rather not worry about it. I also have a load of libraries for scrubbing around IIS already.
However, I'm also having trouble finding out how to enumerate the Roles/Services at all, so if there's a solution that involves doing that, it would certainly be useful, and much better than checking the side effect of having the ASPNET trace provider lying around.
Unfortunately, if you don't check the ASP.NET button, you can still get the ManagedEngine module in the IIS applicationHost.config file, so it's not a reliable check. You can also have ASP.NET mapped as an isapi filter, so checking them isn't enough. These things are especially problematic in the case where ASP.NET was installed but has been removed.
It looks like the best solution would be to examine the Role Services. However, API information on this is looking pretty rare, hence the cry for help.
The absolute way to know if they checked that or not is to search the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Components
In there you should see two values set to 1, ASPNET and NetFxEnvironment and NetFxExtensibility. This registry key is the IIS Setup key that contains all the components that have been enabled in IIS.
Determining if asp.net is even an installed feature (prerequisite for enabling it) can be done through PowerShell, which implies there is .net api out there for it if you dig hard enough. The PowerShell methods:
Import-Module servermanager
Get-WindowsFeature web-asp-net
Which will return an object of type Microsoft.Windows.ServerManager.Commands.Feature. The installed property is boolean and indicates whether or not the feature is installed.
So do you want the easy way? Make a nice pretty .aspx page that displays as HTML with an error block in a div in a placeholder saying "You need to install ASP.NET" and have it change on ASP.NET being installed to instead say "ASP.NET is installed" and then just have the tool launch this webpage in the default browser after copying it to the directory identified in IIS as the *:80 site (or create the directory mapping in IIS programmatically by altering the XML and then removing it later)
May not be the most elegant but it does ensure that testing shows what features are truly installed versus what's in an XML file.
Because that will scream "do it the lazy ignorant way" I'll remind you that the only way for me to know in javascript what features I can use is to test them before I try to use them, or assume they're there and watch it blow up. My point is, it doesn't matter what gets reported in a file, it matters what you can actually use. Just because C:\Windows\Micrsoft.Net\Framework\v3.xxxxxxxx exists and has files doesn't mean the dll's are registered in the GAC, does it?

Can Microsoft Code Contracts be used with an ASP.NET Website?

I'm currently using Microsoft Code Contracts in an ASP.NET MVC application without any issues but I can not seem to get it quite running in a basic ASP.NET Web site. I'm not entirely sure it was made to work with this type of project (although it shouldn't matter) so I wanted to bring it up to everyone.
I can compile the contracts just fine but the code skips over them since I'm assuming it hasn't been enabled through the Properties Page like you would do in other project types (ie ASP.NET MVC). I've gone to the property page of the project (which displays a dialog instead of the typical properties page) in my ASP.NET web site but it does not yield the same menu options and as such, doesn't have a section devoted to Code Contracts.
Also, I have Microsoft Code Contracts properly enabled within a class library project that I use to separate my business logic from the web site. The contracts compile fine but when a contract is violated, it throws a rather uninformative "Exception of type 'System.ExecutionEngineException' was thrown" error with no inner exception. My contract specifies a message to display upon violation but it is nowhere within the exception. It simply halts the execution of the process (which I believe is the default functionality for Microsoft Code Contracts).
I can't find anywhere that explicitly states that a particular project type can or can't (or shouldn't) be used with Contracts so I just wanted to see if anyone has had this issue.
Thanks for any help!
I had the same problem and this is how I solved it:
In the Referenced Class Libraries, right click -> properties -> code contracts.
Make sure "perform contract checking" is checked. I had mine set to "Full"
Contract Reference Assembly: make sure it is set to "Build"
Save your changes.
In the Referenced Class Libraries that have no contracts in their code, set the Contract Reference Assembly to "Do Not Build".
Then in the MVC project, have the Code Contracts "perform contract checking" checked. I had mine set to "Full".
Hope that helps somebody.
This sounds less like a Contracts and more like a build/config issue. Have you tried to deploy a prebuilt website? Are you sure that your website code sees the contracts code? Is the ASP.NET runtime using the CLR 4.0, or does it see the earlier Microsoft.Contracts.dll? Etc.

Resources