So, I have a search form in my website which posts Search.Value as a parameter where in the project there is a class called Search with a property Value which is an object. When the value is bound by the model binder, object is always System.String[] regardless if I pass in a single number, a single word or anything else.
Can someone explain to me why that is, or if I can make it stop doing that?
Here’s the code:
// Search.cs
public sealed class Search {
private object _Value = null;
public object Value {
get {
return this._Value;
}
set {
if (value != null) {
this._Value = value;
this.IsInt32 = (this._Value is Int32);
this.IsString = (this._Value is String);
};
}
}
public bool IsInt32 { get; set; }
public bool IsString { get; set; }
}
// SearchController.cs
[HttpPost]
public ActionResult List(
[Bind(Prefix = "Search", Include = "Value")] Search Search) {
return this.View();
}
// Form HTML
<form action="/Administration/Search" method="post">
@Html.TextBox("Search.Value", Model.Search.Value, new { type = "search", placeholder = "Search", size = 48, required = string.Empty })
<input type="submit" value="⌕" />
</form>
UPDATE
Per @Darin’s suggestion and example I’ve made a custom binder and it seems to be working so far. Here’s the code if anyone else runs into this, modify as needed of course:
public class SearchModelBinder : DefaultModelBinder {
public override object BindModel(
ControllerContext ControllerContext,
ModelBindingContext BindingContext) {
if (BindingContext == null) {
throw new ArgumentNullException("BindingContext");
};
ValueProviderResult ValueResult = BindingContext.ValueProvider.GetValue(BindingContext.ModelName + ".Value");
if (ValueResult == null) {
return (null);
};
string Value = ValueResult.AttemptedValue;
if (String.IsNullOrEmpty(Value)) {
return (null);
};
int Int;
if (int.TryParse(Value, out Int)) {
return new Search {
Value = Convert.ToInt32(Value)
};
};
long Long;
if (long.TryParse(Value, out Long)) {
return new Search {
Value = Convert.ToInt64(Value)
};
};
return new Search {
Value = Value
};
}
}
No idea what you are trying to achieve, why are you using
object, … but you could write a custom model binder for thisSearchmodel. This model binder will assign directly the parameter that is sent in the request to theValueproperty:which you could register in
Global.asax: