3

我正在做一个使用 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 视图的一部分,它定义了条目参数的编辑器(非常基本的东西):

<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”变为空,因此引发异常。为了跟踪可能出现的问题,我实现了一种自定义 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 时,我看到 Request.HttpMethod 和 Request.Form 具有它们正确的值。

现在的问题是如何使用 Spring.NET 修复该版本,使其与使用 Unity 框架的版本一样工作?

4

2 回答 2

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>

一切都开始工作得很好。

最好的问候,马蒂亚斯。

于 2008-12-29T21:35:41.057 回答
2

只是为了澄清这种行为的附加说明:控制器被 ASP.NET MVC 框架视为原型,但 Spring 默认为单例模式。因此,您需要在容器配置中将您的对象显式标记为非单例。即将推出的 Spring MVC 集成模块将处理此问题,因此您不会遇到此问题。

hth,埃里希

于 2009-01-04T17:47:28.430 回答