我发现自己遇到了一些问题,我认为自定义模型绑定器是可行的方法。
My Domain模型看起来像这样,读标准 我有一个页面和一个模板。页面将模板作为参考。 所以默认的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; }
}
所以我在globals.asax中注册了ModelBinder
ModelBinders.Binders.Add(typeof(Cms.Domain.Entities.Page),
new Cms.UI.Web.App.ModelBinders.PageModelBinder(
new Services.GenericApplicationService<Cms.Domain.Entities.Page>().GetEntityStore()
)
);
My ModelBinder tage a paremeter,witch是我的存储库,我获取所有实体(页面,模板)
我的页面控制器看起来像这样。 我已经发布了一个Create Controler,它现在没关系,如果它是Update方法。 由于我在这种情况下有一个下拉列表,代表模板,我将在我的表单集合中获得一个ID。
然后我调用: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中获取ID,并从IEntityStore将其解析为Model。 但是怎么样?
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 ??
}
}
}
//丹尼斯
我希望,我的问题很清楚。
答案 0 :(得分:0)
找到了解决方法。 我下载了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;
}
}
}
这个问题已经结束。