Managing Urls in WebForms - asp.net

I have a large Webforms application. In many places throughout the application we set the navigation urls of hyperlinks in code behind. Hard coding string literals seems like a bad idea.
hlVideos.NavigateUrl = "/path/to/some/page.aspx";
This doesn't seem like a good idea either, since it could require me to have a constant string on every page that needs it:
private const string PathToSomePage = "/path/to/some/page.aspx";
hlVideos.NavigateUrl = PathToSomePage;
I've thought about a single class with a bunch of const strings in it that can be accessed. This seems like it would be an open/closed principle violation, requiring me to add another constant every time that I add a new page.
public class UrlManager
{
public const string PathToSomePage = "/path/to/some/page.aspx";
public const string PathToSomeOtherPage = "/path/to/some/other/page.aspx";
public const string PathToYetAnotherPage = "/path/to/yet/another/page.aspx";
}
How is everyone else handling this? Maybe I'm over complicating this, although I am dealing with a hundred urls or so with many pages referencing each url.

Consider using a resource file. That way you can maintain a consistent reference to pages, but it is easily maintainable in code and easily hot-fixed post-deployment if the situation requires.

You can try to write some T4 template to generate your UrlManager file class. Something like T4MVC. Look here for WebForms example T4Mvc web forms

Related

Thoughts on how to refer to web.config key names in code

When your web.config or app.config file has an appsettings entry, what is the best way to refer to its key in your code file?
Developers I have worked with have differing opinions on this. Some say to hard code the string and others suggest that there should be a file containing string constants and in your code, you use the constant as the appsettings key.
I would be interested in hearing other opinions on this. What do you do? Why is it the best?
String constants are better than nothing, but I'd initially vote for using a configuration class to provide strongly typed, intellisense friendly access to the config values. If I were stuck with using AppSettings for some reason.
In a more perfect world, I would vote for avoiding appSettings altogether and using custom configuration classes as they are much, much cleaner in the long run.
Skip the string constants, and create a configuration wrapper class instead.
class MyConfiguration
{
public static string SomeConfigValue
{
get
{
return WebConfigurationManager.AppSettings["SomeConfigValue"];
}
}
public static int SomeOtherConfigValue
{
get
{
return int.Parse(WebConfigurationManager.AppSettings["SomeOtherConfigValue"];
}
}
//..and so on
}
Then you could get it like this:
string s = MyConfiguration.SomeConfigValue;
int i = MyConfiguration.SomeOtherConfigValue;
(You might consider not going the static route if you want to remove dependencies on the configuration system while unittesting)
String Constants for the win.
Keeping common strings in string constants makes things easier to maintain. If a key in your config file changes names, you only have to change it in one spot rather than worrying about finding every instance of the hard-coded string throughout your application.
I've always been a fan of Rick Strahl's method.
As for static strings being unwieldy, break your class down into subclasses and properties if you need to. For example in an application I'm currently working on, I have App.Settings for general settings, App.EmailSettings for email settings, and App.EventSettings for event logging settings.

Remove field in wsdl in Asp.net webservice

I'm generating dto classes with a template engine and would like to exclude some properties in an asmx webservice, what, if possible, is the best way to do this?
Ex:
[WebMethod]
public ProductPackages GetPackages()
{
ProductPackages packages = new ProductPackages();
packages.Packages.add(new PackageDTO());
return packages;
}
The PackageDTO contains some properties that's not relevant for this service.
But as the class can be regenerated any time i can't apply [XmlIgnore] to the fields.
So I'm looking for a way to apply a "exclude list" without touching the actual class.
Above is just an example, the template engine generates dto's for all tables in a given project, and I would like to be able to use them in services without needing to maintain a big bunch of nearly identical classes.
Just hit the same problem. You can exclude fields by marking them as internal.
public class Order
{
public double OrderPrice;
internal double ProfitMargin;
internal string TheTruthAboutThisCustomer;
}
If you don't want to return a field or property, then don't have it in the object you return! It's as simple as that.

Flex How to organize embeded resources

How to avoid having embeded metadata everywhere in source code(.as or .mxml)?
I have found two approaches:
1. Embed everything in css. But it is kind of difficult to extract from there:
var soundCSSClassDec:CSSStyleDeclaration = StyleManager.getStyleDeclaration("MySound");
var MySoundClass:Class = (soundCSSClassDec.getStyle("url")) as Class;
var myEmbeddedSound:Sound = new MySoundClass() as Sound;
myEmbeddedSound.play()
Embed in resource files. It is easy to extract - resourceManager.getResource("sounds","mySound"). But I feel something wrong with this approach. As i understand resourceManager was desinged for localization.
Any other ideas?
Thanks, Aleksey
It's not wrong to use ResourceManager: in your case (non-localized app) you only support one language (special case of localization for N languages :).
Another approach is to load these resources over the network from some server. Of course, depending on how your application is bundled/used this approach may be inefficient.
Another option is to define an "AssetLibrary" class with lots of public static const typed to "Class"; then reference those either via binding in MXML or through simple assignment in ActionScript.
public class AssetLibrary {
[Embed(source='/assets/image_link.png')]
public static const IMAGE_LINK : Class;
}
Using ResourceManager is a totally valid approach too. It's actually good practice to externalize that from your application since it will make localizing it later on much easier.

ASP.NET Localized web site -- updating on the fly

I think I have a solution to this, but is there a better way, or is this going to break on me?
I am constructing a localized web site using global/local resx files. It is a requirement that non-technical users can edit the strings and add new languages through the web app.
This seems easy enough -- I have a form to display strings and the changes are saved with code like this snippet:
string filename = MapPath("App_GlobalResources/strings.hu.resx");
XmlDocument xDoc = new XmlDocument();
XmlNode xNode;
xDoc.Load(filename);
xNode = xDoc.SelectSingleNode("//root/data[#name='PageTitle']/value");
xNode.InnerText = txtNewTitle.Text;
xDoc.Save(filename);
Is this going to cause problems on a busy site? If it causes a momentary delay for recompilation, that's no big deal. And realistically, this form won't see constant, heavy use. What does the community think?
I've used a similar method before for a very basic "CMS". The site wasn't massively used but it didn't cause me any problems.
I don't think changing a resx will cause a recycle.
We did something similar, but used a database to store the user modified values. We then provided a fallback mechanism to serve the overridden value of a localized key.
That said, I think your method should work fine.
Have you considered creating a Resource object? You would need to wrap your settings into a single object that all the client code would use. Something like:
public class GuiResources
{
public string PageTitle
{
get return _pageTitle;
}
// Fired once when the class is first created.
void LoadConfiguration()
{
// Load settings from config section
_pageTitle = // Value from config
}
}
You could make it a singleton or a provider, that way the object is loaded only one time. Also you could make it smart to look at the current thread to get the culture info so you know what language to return.
Then in your web.config file you can create a custom section and set restartOnExternalChanges="true". That way, your app will get the changed when they are made.

Getting project web page names as an enumeration in asp.net

I know that in markup view Visual Studio will provide you with an enumeration of all the page names in your project (add an element and see what you get from Intellisense when specifying the ImageUrl attribute).
My question is: how do I get to that enumeration?
If that's not possible, what would be the best way in asp.net to get the names of your pages without having to hard code strings all over the place? E.g., I'd like to be able to do something like this:
Response.Redirect(PageNames.Default);
(Where PageNames is an enum of some sort)
Is this possible? Thanks in advance!
Here is one suggestion...
Define a class that includes the pages you want, either manually or by reading a Site Navigation file:
static class PageNames
{
public static string Default = "~/Default.aspx";
public static string Contact = "~/Contact.aspx";
public static string About = "~/About.aspx";
}
You can use the class by calling the property name:
Response.Redirect(PageNames.Default);
Another option, that I have looked at but not tried out yet (might next week tho'):
http://blog.devarchive.net/2008/01/auto-generate-strong-typed-navigation.html
Looks very cool, uses T4 templating to generate a strongly typed navigation hierarchy.

Resources