Может ли ASP .NET MVC помочь мне конвертировать идентификаторы в модели в моем действии? - PullRequest
0 голосов
/ 07 марта 2012

Рассмотрим HTML-форму, созданную следующим образом:

        <select name="schoolType">
            @foreach (SchoolType schoolType in Model.SchoolTypes)
            {
                <option value="@schoolType.Id">@schoolType.Name</option>
            }
        </select>

Теперь SchoolType - это модельный класс. Он разработан в моем EDMX для Entity Framework.

В приведенном выше сценарии мой метод действия выглядит следующим образом:

    public ActionResult CreateSchool(int schoolType)
    {
        ...
        SchoolType myType = container.SchoolTypeSet.FirstOrDefault(t => t.Id == schoolType);
        ...
    }

Можно ли запрограммировать какого-нибудь помощника, чтобы MVC автоматически знал, как преобразовать целое число в класс Model с таким идентификатором, как, например, следующая сигнатура метода действия?

    public ActionResult CreateSchool(SchoolType schoolType)
    {
        ...
    }

Ответы [ 2 ]

2 голосов
/ 07 марта 2012

Вы можете использовать ModelBinder для этого:

public ActionResult CreateSchool([ModelBinder(typeof(SchoolTypeBinder))] SchoolType schoolType)
{
    ...
}

Где выглядит ваша модель Binder:

public class SchoolTypeBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        SchoolType output = null;

        int id;
        ValueProviderResult parameter = bindingContext.ValueProvider.GetValue("id");
        if (parameter != null)
        {
            id = (int)parameter.ConvertTo(typeof(int));
            output = container.SchoolTypeSet.FirstOrDefault(t => t.Id == id);
        }
        return output;
    }
}

Вы также можете связать связыватели с типами глобально при запуске:

protected void Application_Start()
{
    ...
    ModelBinders.Binders.Add(typeof(SchoolType), new SchoolTypeBinder());
}

в результате вы получили красивое, чистое действие:

public ActionResult CreateSchool(SchoolType schoolType)
{
    ...
}
0 голосов
/ 11 марта 2012

Я обычно оборачиваю его в некоторую абстракцию под названием DataSource, которая отображает текущее значение и текущий идентификатор.Поскольку первичные ключи часто имеют одинаковый тип во всем решении (int, Guid), вы можете зарегистрировать связыватель модели для источника данных.Вы можете использовать какой-нибудь помощник, как показано ниже, чтобы вывести его на экран:

    public static SelectList ToSelectList<T, T1>(this DataSource<T, T1> dataSource)
    {
        return dataSource == null
            ? new SelectList(Enumerable.Empty<string>()) 
            : new SelectList(dataSource, "Key", "Value", dataSource.CurrentValue);
    }

И в шаблоне вашего редактора вы можете использовать просто @ Html.DropDownListFor (model => model, Model.ToSelectList ())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...