Пользовательский связыватель модели, asp.net mvc 2 rtm 2, синтаксический анализ ID для ComplexModel - PullRequest
0 голосов
/ 11 июня 2010

У меня возникли небольшие проблемы, и я думаю, что связыватель пользовательской модели - это то, что нужно.

Моя модель домена выглядит следующим образом, я имею в виду стандартную страницу и шаблон.Страница имеет шаблон в качестве ссылки.Так что по умолчанию asp.net mvc Binder, не знает, как его связать, поэтому мне нужно сделать некоторые правила для него.(Пользовательская привязка модели)

public class PageTemplate
{
    public virtual string Title { get; set; }
    public virtual string Content { get; set; }
    public virtual DateTime? Created { get; set; }
    public virtual DateTime? Modified { get; set; }
}



public class Page
{
    public virtual string Title { get; set; }
    public virtual PageTemplate Template { get; set; }
    public virtual string Content { get; set; }
    public virtual DateTime? Created { get; set; }
    public virtual DateTime? Modified { get; set; }
}

Итак, я зарегистрировал ModelBinder в globals.asax

ModelBinders.Binders.Add(typeof(Cms.Domain.Entities.Page),
                        new Cms.UI.Web.App.ModelBinders.PageModelBinder(
                                new Services.GenericApplicationService<Cms.Domain.Entities.Page>().GetEntityStore()
                            )
                        );

Моя страница ModelBinder содержит пареметр, ведь мой репозиторий - это место, где я получаю все свои сущности(Страница, Шаблон)

Мой Контроллер для Страницы выглядит следующим образом.Я разместил в Create Controler, на данный момент это не имеет значения, если это был метод обновления.Так как в этом случае у меня есть раскрывающийся список, представляющий шаблон, я получу идентификатор в своей коллекции форм.

Затем я вызову: TryUpdateModel, и я получил удар по моему PageModelBinder.

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Create(FormCollection form)
{
    Page o = new Page();

    string[] exclude = new { "Id" }
    if (base.TryUpdateModel<Page>(o, string.Empty, null, exclude, form.ToValueProvider()))
    {
        if (ModelState.IsValid)
        {
            this.PageService.Add(o);
            this.CmsViewData.PageList = this.PageService.List();
            this.CmsViewData.Messages.AddMessage("Page is updated.", MessageTypes.Succes);
            return View("List", this.CmsViewData);
        }
    }

    return View("New", this.CmsViewData);
}

Итак, я заканчиваю работу с моделью Binder.У меня есть поиск в интернете для информации, но я на складе.

Мне нужно получить идентификатор из коллекции FormCollection и проанализировать его в Model из моего IEntityStore.Но как ?

public class PageModelBinder : IModelBinder
{

    public readonly IEntityStore RepositoryResolver;

    public PageModelBinder(IEntityStore repositoryResolver)
    {
        this.RepositoryResolver = repositoryResolver;
    }

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }

        if (modelType == typeof(Cms.Domain.Entities.Page))
        {
            // Do some magic 
            // Get the Id from Property and bind it to model, how ??
        }
    }

}

// Деннис

Надеюсь, мой проблом ясен.

1 Ответ

0 голосов
/ 19 июня 2010

нашёл обходной путь. Я скачиваю исходный код для asp.net r2 rtm 2

И скопировал весь код для ModelBinder по умолчанию, и код, который ему нужен. Сделали небольшие изменения, небольшие взломы.

обходной путь делает небольшой взлом в этом методе:

[SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)",
        Justification = "The target object should make the correct culture determination, not this method.")]
    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
        Justification = "We're recording this exception so that we can act on it later.")]
    private static object ConvertProviderResult(ModelStateDictionary modelState, string modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)
    {
        try
        {
            object convertedValue = valueProviderResult.ConvertTo(destinationType);
            return convertedValue;
        }
        catch (Exception ex)
        {
            try
            {
                // HACK if the binder still fails, try get the entity in db.
                Services.GenericApplicationService<Cms.Domain.Entities.PageTemplate> repo;
                repo = new Services.GenericApplicationService<Cms.Domain.Entities.PageTemplate>();
                int id = Convert.ToInt32(valueProviderResult.AttemptedValue);
                object convertedValue = repo.Retrieve(id);
                return convertedValue;
            }
            catch (Exception ex1)
            {
                modelState.AddModelError(modelStateKey, ex1);
                return null;
            }
        }
    }

Этот вопрос закрыт.

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