0

I have a model with a collection

public class Model
{
     IEnumerable<ModelPart> Parts {get;set;}
}

public class Parts 
{
     public string Prop1 {get;set;}
     public string Prop2 {get;set;}
}

But the comming in url is quite nasty.

It has this form

dhxGridObj_d3BIc6JfDidc_1_0=&dhxGridObj_d3BIc6JfDidc_1_1=sssss&dhxGridObj_d3BIc6JfDidc_1_2=ssssss& dhxGridObj_d3BIc6JfDidc_2_0=&dhxGridObj_d3BIc6JfDidc_2_1=aaaa&dhxGridObj_d3BIc6JfDidc_2_2=aaaaa

It has three parts separated with underscore

dhxGridObj_d3BIc6JfDidc_2_1

  1. Some id dhxGridObj_d3BIc6JfDidc
  2. Row id 2
  3. Cell id 1

I'm wondering what would be the best way bind this to my model.

I was thinking of renaming this dhxGridObj_d3BIc6JfDidc_2_1 to model[2].Prop1 Where would be the best place to do this ?

2 Answers 2

2

Oh yeah, that's a hell of an ugly request string. A custom model binder is the way to parse this beast until you find a real solution to this problem which of course is fixing the system sending this crap to conform to the default model binder syntax.

And here's an example of some scratch code that might put you on the right track:

public class MyModelBinder : DefaultModelBinder
{
    private const string Prefix = "dhxGridObj_d3BIc6JfDidc";

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = base.BindModel(controllerContext, bindingContext) as Model;
        var request = controllerContext.HttpContext.Request;
        model.Parts = request
            .Params
            .Keys
            .OfType<string>()
            .Select(key => Regex.Match(key, Prefix + "_([0-9]+)_([0-9]+)"))
            .Where(x => x.Success)
            .Select(x => new
            {
                Row = x.Groups[1].Value,
                Col = x.Groups[2].Value
            })
            .GroupBy(x => x.Row)
            .Select(x => new Parts
            {
                Prop1 = request[string.Format("{0}_{1}_{2}", Prefix, x.Key, x.ElementAt(0).Col)],
                Prop2 = request[string.Format("{0}_{1}_{2}", Prefix, x.Key, x.ElementAt(1).Col)],
            });
        return model;
    }
}

which will be registered in Application_Start:

ModelBinders.Binders.Add(typeof(Model), new MyModelBinder());
Sign up to request clarification or add additional context in comments.

5 Comments

Forgot to mention there is also some validation going on on the Parts class. I've had a look at the defaultmodelbinder class.There're couple of methods to override. Could you give a hint which one would be the best for this ?
@user256034, you derive from DefaultModelBinder and override the BindModel method where you perform the logic of parsing those ugly query string parameters and binding them to their corresponding property values.
Wow this awesome. Works like a charm. But I guess I have to do the validation by myself, don't I ?
@user256034, what kind of validation do you need? You could decorate your model properties with the necessary attributes.
Yes , I meaned DataAnnotations. I have on some properties of the Parts class some attributes. But I don't see the place where the validation should happen.
0

You should not use query string parameters in url of your MVC application. the best for this is Url routes. you can find a good article for routes in MVC here :

http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx

1 Comment

but this is big hole in MVC Application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.