我正在开发一个在ASP.NET MVC中使用Spring.NET IoC功能的演示。这有点像在www.asp.net网站上的双编程视频教程中提供的MyBlog应用程序。我已经使用Microsoft的Unity框架完成了相同的演示,现在想要试用Spring容器。 为此,我实现了一个简单的IControllerFactory,它首先创建Spring对象工厂:
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;
}
(出于简化目的而剥离错误处理)。
现在在我的HomeController的某处,我有这样的动作:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddEntry([Bind] BlogEntry entry, int id) {
entry.EntryDate = DateTime.Now;
....
这是AddEntry.aspx视图的一部分,它定义了entry参数的编辑器(非常基本的东西):
<form method="post" action="/Home/AddEntry/<%= ViewData["id"] %>">
<table>
<tr>
<td><label for="Title">Title</label></td>
<td><input name="entry.Title" type="text"/></td>
</tr>
<tr>
<td><label for="Text">Content</label></td>
<td><input name="entry.Text" type="text"/></td>
</tr>
</table>
<br />
<input type="submit" value="Add entry" />
<input type="button" value="Cancel" onclick="history.back(-1);" />
</form>
现在这是交易: 当我使用Unity IoC时,它就像一个魅力。 “entry”参数从我的表单中反序列化,就像它应该和行
一样entry.EntryDate = DateTime.Now;
完成没有问题。
然而,当我切换到Spring.NET对象工厂(如上所述)时,事情开始变得疯狂。首先,参数“entry”变为null,因此抛出异常。 为了跟踪我可能出现的问题,我实现了一种自定义的IModelBinder:
public class BlogEntryBinder : IModelBinder {
public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
return result;
}
}
当我使用Unity框架来到这里并从bindingContext向下钻取到HttpRequest时,我看到Request.HttpMethod是“POST”并且Request.Form被正确填充。当我使用Spring.NET执行相同操作时,方法为“GET”,Request.Form为空。 然而,当我走到我的控制器操作(AddEntry)并在两种情况下深入查询请求时,我看到Request.HttpMethod和Request.Form具有正确的值。
现在问题是我如何使用Spring.NET修复版本,以便它像使用Unity框架的那样工作?
答案 0 :(得分:4)
我找到了答案!
我的对象定义看起来像这样:
<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
<property name="BlogService" ref="BlogService" />
<property name="BlogEntryService" ref="BlogEntryService" />
<property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>
没关系正在设置的属性它实际做的是每次我使用
请求此对象时返回相同的实例IController result = context.GetObject(controllerName) as IController;
所以当我把定义改为
时<!-- 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>
一切都开始了。
祝你好运, 马提亚。
答案 1 :(得分:2)
只是澄清这种行为的另一个注释:ASP.NET MVC框架将控制器视为原型,但Spring默认为单例模式。因此,您需要在容器配置中将对象明确标记为非单例。即将推出的Spring MVC集成模块将负责这一点,因此您不会遇到这种情况。
HTH, 埃里希