4
\$\begingroup\$

I have a ASP.NET Web Forms project, and I want to build calls to .aspx pages in a strongly-typed fashion. I ended up rolling my own serializer that takes simple structs and saves them to/loads them from the query string. What do you think? Is my approach sane? Is there an accepted alternative I don't know about? Any feedback on the code?

Here's what building a call to a particular page looks like:

var fooParams= new FooPage.Parameters
{
 NodeID = nodeId,
 FooString = "the foo string"
};
string url = MyHelper.BuildCall(FooPage.URL, fooParams);
//url: ~/dir/FooPage.aspx?NodeID=5&FooString=the%20foo%20string

FooPage:

public partial class FooPage : System.Web.UI.Page
{
 public const string URL = "~/Dir/FooPage.aspx";
 public struct Parameters
 {
 public long? NodeID;
 public string FooString;
 public int? OtherParam;
 }
 protected Parameters Params;
 protected void Page_Load(object sender, EventArgs e)
 {
 Params = MyHelper.DeserializeFromNameValueCollection<Parameters>(Request.Params);
 //...
 //use Params.NodeID, Params.FooString, etc..
 }
}

Serialize/Deserialize to/from NameValueCollection:

public static void SerializeToNameValueCollection<T>(NameValueCollection nameValueCollection, T @object) where T : struct
{
 Type type = typeof(T);
 var fields = type.GetFields();
 foreach (var field in fields)
 {
 string key = field.Name;
 var value = field.GetValue(@object);
 if (value != null)
 nameValueCollection.Add(key, value.ToString());
 }
}
public static T DeserializeFromNameValueCollection<T>(NameValueCollection nameValueCollection) where T : struct
{
 T result = new T();
 Type type = typeof(T);
 var fields = type.GetFields();
 foreach (var field in fields)
 {
 string key = field.Name;
 string stringValue = nameValueCollection[key];
 if (stringValue != null)
 {
 object value;
 var baseType = Nullable.GetUnderlyingType(field.FieldType);
 if (baseType != null)
 {
 value = Convert.ChangeType(stringValue, baseType);
 }
 else
 {
 value = Convert.ChangeType(stringValue, field.FieldType);
 }
 field.SetValueDirect(__makeref(result), value);
 }
 }
 return result;
}

Format NameValueCollection into query string:

public static string BuildCall<T>(string url, T queryStringParams) where T : struct
{
 var queryStringBuilder = HttpUtility.ParseQueryString("");
 UrlHelper.SerializeToNameValueCollection(queryStringBuilder, queryStringParams);
 string queryString = queryStringBuilder.ToString();
 return url + "?" + queryString;
}
asked Mar 22, 2012 at 1:53
\$\endgroup\$
1
  • \$\begingroup\$ The line that parses an empty string seems a bit of a hack to get a NamveValueCollection. var queryStringBuilder = HttpUtility.ParseQueryString(""); Is there a reason for this? \$\endgroup\$ Commented Feb 8, 2016 at 17:52

1 Answer 1

2
\$\begingroup\$

One of my favorite patterns for handling URL parameters in WebForms is the WebNavigator - http://polymorphicpodcast.com/shows/webnavigator/

If you're going through these kinds of Strongly-typed interactions for passing parameters between pages, maybe it is time you check out ASP .NET MVC - your solution looks a lot like model-binding.

answered Mar 29, 2012 at 3:11
\$\endgroup\$
1
  • \$\begingroup\$ This is great, I didn't know about the WebNavigator pattern! I would LOVE to use MVC (and MVC did inspire this approach), but unfortunately the product I'm working on can't afford the time it'd take to do the switch. \$\endgroup\$ Commented Mar 29, 2012 at 4:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.