Hugo Delsing
Hugo Delsing

Reputation: 14173

C# MVC Bind variables in a string to model

In C# MVC you can use model binding to automatically parse variables to a model.

public class RegistrationForm {
 string Name {get;set;}
 string Address {get;set;} 
}

public ActionResult Register(RegistrationForm register) {
...
}

If I pass the Name and Address variables they are directly available in the register object.

Is it possible to call this binding manually if you have the variables in a string? EG:

var s = "name=hugo&address=test";

//dosomething to get RegistrationForm register

//register.Name == hugo

I know I can get a NameValueCollection with HttpUtility.ParseQueryString(s); and then use reflection to get the properties of RegistrationForm and check if the values exists, but I was hoping I could use the actually binding method MVC uses.

Upvotes: 1

Views: 2268

Answers (4)

Hugo Delsing
Hugo Delsing

Reputation: 14173

@Malcolm's anwser is what I requested, so he gets the credits. But I still ended up doing it with reflection, because it looks a lot cleaner in my opinion and easier to understand what is going on.

var result = HttpUtility.ParseQueryString(strResponse);
Type myType = GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
    try
    {
        prop.SetValue(this,
            Convert.ChangeType(result[prop.Name], prop.PropertyType, CultureInfo.InvariantCulture),
            null);
    }
    catch (InvalidCastException)
    {
        //skip missing values
    }
    catch (Exception ex)
    {
        //something went wrong with parsing the result
        new Database().Base.AddErrorLog(ex);
    }
}

Disclaimer This works for me because I only get strings and decimals and nothing is required. This is nothing like the MVC model binder.

Upvotes: 0

Mathias F
Mathias F

Reputation: 15931

You could mock the HttpContext passed into Modelbinding like here

http://www.jamie-dixon.co.uk/unit-testing/unit-testing-your-custom-model-binder/

var controllerContext = new ControllerContext();
//set values in controllerContext  here
var bindingContext = new ModelBindingContext();
var modelBinder = ModelBinders.Binders.DefaultBinder;
var result = modelBinder.BindModel(controllerContext, bindingContext)

Upvotes: 1

Rupesh
Rupesh

Reputation: 555

You can convert the string to JSON object and then you can parse JSON object to your Model by using a Serializer.

Upvotes: 0

teo van kot
teo van kot

Reputation: 12491

MVC binding working based on Property Names of your ViewModel (RegistrationForm class).

So you absolutely right, if you use GET HTTP Method to bind your property from string you can write this directly:

http://yourSite.com/YourController/Register?Name=hugo&Address=test

It's case sensitive, be carefull.

Or if you use Razor to generate links you can write it more clear way:

@Url.Action("Register", new { Name = "hugo", Address = "test"})

Upvotes: 1

Related Questions