Asp.net mvc ASP.NET MVC与Spring.NET和ModelBinder
我正在制作一个演示,它利用ASP.NETMVC中的Spring.NETIOC功能。这有点像www.asp.net网站上结对编程视频教程中介绍的MyBlog应用程序。我已经使用微软的Unity框架完成了相同的演示,现在想试用Spring容器。 为此,我实现了一个简单的IControllerFactory,它首先创建Spring对象工厂,如下所示:Asp.net mvc ASP.NET MVC与Spring.NET和ModelBinder,asp.net-mvc,unity-container,spring.net,Asp.net Mvc,Unity Container,Spring.net,我正在制作一个演示,它利用ASP.NETMVC中的Spring.NETIOC功能。这有点像www.asp.net网站上结对编程视频教程中介绍的MyBlog应用程序。我已经使用微软的Unity框架完成了相同的演示,现在想试用Spring容器。 为此,我实现了一个简单的IControllerFactory,它首先创建Spring对象工厂,如下所示: IObjectFactory factory; (....) factory = new XmlObjectFactory(new FileSystem
IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
IController result = context.GetObject(controllerName) as IController;
return result;
}
public class BlogEntryBinder : IModelBinder {
public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
return result;
}
}
<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
<property name="BlogService" ref="BlogService" />
<property name="BlogEntryService" ref="BlogEntryService" />
<property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>
然后它从工厂得到控制器,如下所示:
IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
IController result = context.GetObject(controllerName) as IController;
return result;
}
public class BlogEntryBinder : IModelBinder {
public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
return result;
}
}
<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
<property name="BlogService" ref="BlogService" />
<property name="BlogEntryService" ref="BlogEntryService" />
<property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>
(为简化起见,删除了错误处理)
现在,在我的家庭控制器的某个地方,我有这样的动作:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddEntry([Bind] BlogEntry entry, int id) {
entry.EntryDate = DateTime.Now;
....
下面是AddEntry.aspx视图的一部分,它定义了条目参数的编辑器(真正的基本内容):
完全没有问题
然而,当我切换到Spring.NET对象工厂(如上所述)时,事情开始变得疯狂。首先,参数“entry”变为null,因此引发异常。
为了跟踪可能出现的问题,我实现了一种自定义IModelBinder,如下所示:
IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
IController result = context.GetObject(controllerName) as IController;
return result;
}
public class BlogEntryBinder : IModelBinder {
public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
return result;
}
}
<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
<property name="BlogService" ref="BlogService" />
<property name="BlogEntryService" ref="BlogEntryService" />
<property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>
当我使用Unity框架来到这里并从bindingContext深入到HttpRequest时,我看到Request.HttpMethod是“POST”,Request.Form是正确填写的。当我使用Spring.NET做同样的事情时,方法是“GET”,Request.Form是空的。
然而,在这两种情况下,当我转到控制器操作(AddEntry)并深入到请求时,我看到Request.HttpMethod和Request.Form都有其正确的值
现在的问题是,如何使用Spring.NET修复该版本,使其与使用Unity framework的版本一样工作?我找到了答案
我的对象定义如下所示:
IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
IController result = context.GetObject(controllerName) as IController;
return result;
}
public class BlogEntryBinder : IModelBinder {
public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
return result;
}
}
<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
<property name="BlogService" ref="BlogService" />
<property name="BlogEntryService" ref="BlogEntryService" />
<property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>
所以当我把定义改为
<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController" singleton="false">
<property name="BlogService" ref="BlogService" />
<property name="BlogEntryService" ref="BlogEntryService" />
<property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>
一切都很顺利
致以最良好的祝愿,
Matthias.只是澄清这种行为的一个补充说明:ASP.NET MVC框架将控制器视为原型,但Spring默认为单例模式。因此,您需要在容器配置中将对象显式标记为非单例对象。即将到来的SpringMVC集成模块将解决这个问题,因此您不会遇到这个问题 嗯,, 埃里克