Lijin John Lijin John - 3 months ago 21
C# Question

How to create MVC Extension Method for Dynamic type

I want to create Extension methods for dynamic type, but for some or the other reason i get error while compiling the code. below is my code sample
The method which i am using is

public List<State> getStates()
{

return new List<State>(){
new State{StateID="1",StateName="Tamil Nadu"},
new State{StateID="2",StateName="Assam"},
new State{StateID="3",StateName="Andra"},
new State{StateID="4",StateName="bihar"},
new State{StateID="5",StateName="Bengal"},
};
}


and my extension method is

public static class helper
{
public static IEnumerable<SelectListItem> getIntoDropDownState(this List<dynamic> data,string textField,string valueField)
{
return data.Select(x => new SelectListItem
{
Text = x.textField,
Value = x.valueField
});
}
}


My compilation error which i get is


Compiler Error Message: CS1928:
'System.Collections.Generic.List'
does not contain a definition for 'getIntoDropDownState' and the best
extension method overload
'LearnAuthentication.Controllers.helper.getIntoDropDownState(System.Collections.Generic.List,
string, string)' has some invalid arguments


I want to use the Extension method like this, and I am facing error

@Html.DropDownListFor(x => x.StateID, new LearnAuthentication.Controllers.Address().getStates().getIntoDropDownState("StateName", "StateID"), "Select State", 0)


can anyone help

Answer

That extension method in your example is not going to do what you describe. You could use reflection and generics.

public static class helper {
    public static IEnumerable<SelectListItem> getIntoDropDownState<T>(this List<T> data, string textField, string valueField) where T : class {
        var type = typeof(T);

        var textPropertyInfo = type.GetProperty(textField);
        var valuePropertyInfo = type.GetProperty(valueField);

        return data.Select(x => new SelectListItem {
            Text = (string)textPropertyInfo.GetValue(x),
            Value = (string)valuePropertyInfo.GetValue(x)
        });
    }
}

Here is a unit test for the extension method

[TestClass]
public class MyTestClass {
    [TestMethod]
    public void MyTestMethod() {
        //Arrange
        var data = getStates();

        //Act
        var result = data.getIntoDropDownState("StateName", "StateID");

        //Assert
        Assert.IsNotNull(result);
        var first = result.First();
        Assert.AreEqual(data[0].StateName, first.Text);
        Assert.AreEqual(data[0].StateID, first.Value);
    }

    public List<State> getStates() {

        return new List<State>(){
             new State{StateID="1",StateName="Tamil Nadu"},
             new State{StateID="2",StateName="Assam"},
             new State{StateID="3",StateName="Andra"},
             new State{StateID="4",StateName="bihar"},
             new State{StateID="5",StateName="Bengal"},            
        };
    }

    public class State {
        public string StateID { get; set; }
        public string StateName { get; set; }
    }
}

Or you could forego reflection and use System.Web.Mvc.SelectList which does the heavy reflection lifting for you

public static class helper {
    public static IEnumerable<System.Web.Mvc.SelectListItem> getIntoDropDownState<T>(this List<T> data, string textField, string valueField) where T : class {

        return new System.Web.Mvc.SelectList(data, valueField, textField);

    }
}
Comments