Reputation: 180878
I have a double-precision floating point field in my database that stores seconds past midnight. I have code in c# that can convert this number to the form HH:MM:SS.ffffff, where f is fractions of a second. I also have code that can parse this back into a double.
What I would like to do is modify the stock binder object in ASP.NET MVC so that it uses MY parsing and ToString() methods instead of the ones it would normally use from the double type, without having to write a complete custom binder.
Can I write a couple of extension methods in c#, or use a couple of well-placed attributes to let the binder object know about my parsing and ToString() methods?
Here is some more clarification.
if I provide a model such as a Linq to SQL class to the view, MVC can automatically wire up my fields to the underlying data model, provided I use the same names for the controls in my view as I have used in my data model. If I post my MVC view back to a controller method, I can write the user's changes back to the database by calling the UpdateModel method on my Controller class. I don't have to worry about wiring up my specific fields from the FormCollection to my Linq to SQL data class, because the binder has done that for me already.
I assume that, in order for the binder to work this magic on an ordinary numeric double, that it must first parse the input from the user (probably by calling double.parse), and pass this to the Linq to SQL class so that it can update the database.
I need to use my own custom parser, instead of the one that comes with the double data type, for one of the fields in my model. I don't want to have to assume responsibility for the remaining fields.
Upvotes: 2
Views: 2520
Reputation: 13679
This is a naive, quick and dirty example, but if you decide to go the model binder route, try something like:
// This goes in global.asax
ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
ModelBinders.Binders.Add(typeof(CustomDateType), new CustomDateBinder());
......
public class CustomDateType
{
public CustomDateType(string value)
{
}
public string GetText()
{
// I do fancy stuff
throw new NotImplementedException();
}
public decimal? GetValue()
{
// I do fancy stuff
throw new NotImplementedException();
}
}
public class CustomDateBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
try
{
string doubleDateValue = GetAttemptedValue(bindingContext);
if (doubleDateValue == "")
{
return null;
}
return new CustomDateType(doubleDateValue);
}
catch (Exception ex)
{
string message = string.Format("Unable to locate a valid value for query string parameter '{0}'",
bindingContext.ModelName);
throw new ApplicationException(message, ex);
}
}
private static string GetAttemptedValue(ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider[bindingContext.ModelName];
return value == null ? string.Empty : value.AttemptedValue;
}
}
Upvotes: 1
Reputation: 60664
Is it absolutely necessary to have the name be .ToString()
? It is easy if for example .ToCustomString()
is acceptable:
public static class DoubleExtensions
{
public static string ToCustomString(this double d)
{
return "my own";
}
}
Upvotes: 0