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;
}