Sonic Soul
Sonic Soul

Reputation: 24919

preserving arrays across postbacks asp.net mvc, in comma delimited list

I am experimenting with the following scenario.

on the initial GET, my controller is returning a default model with a string[] property.

on the view, I show this property using a textbox:

@Html.TextBoxFor(model => model.MyProperty) 

The array is showing as comma delimited list. Great!

The problem is that when i postback, the list ends up as single string array with all items comma delimited within that string.

Is there a way I could provide a deserializer (maybe something equivalent of converter in WPF) that would make this go back to correct array?

I am aware that I can also use @Html.EditorFor(...), but this renders my array as a list of separate textboxes which I do not want.

Upvotes: 3

Views: 907

Answers (1)

mipe34
mipe34

Reputation: 5666

You can create custom model binder for binding string arrays like this:

public class StringArrayBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        string key = bindingContext.ModelName;
        ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (val != null && string.IsNullOrEmpty(val.AttemptedValue) == false)
        {
            bindingContext.ModelState.SetModelValue(key, val);
            string incomingString = ((string[])val.RawValue)[0];

            var splitted = incomingString.Split(',');
            if (splitted.Length > 1)
            {
                return splitted;
            }
        }
        return null;
    }
}

And then register it in global.asax on application startup:

ModelBinders.Binders[typeof(string[])] = new StringArrayBinder();

Or even simpler but less reusable approach would be:

public string[] MyStringPropertyArray { get; set; }

public string MyStringProperty
{
    get
    {
        if (MyStringPropertyArray != null)
            return string.Join(",", MyStringPropertyArray);
        return null;
    }
    set
    {
        if (!string.IsNullOrWhiteSpace(value))
        {
            MyStringPropertyArray = value.Split(',');
        }
        else
        {
            MyStringPropertyArray = null;
        }
    }
}

Here you would bind to MyStringProperty in the view. And then use MyStringPropertyArray (populated with values from MyStringProperty) in your business code.

Upvotes: 4

Related Questions