【问题标题】:ASP.NET MVC with Spring.NET and ModelBinder带有 Spring.NET 和 ModelBinder 的 ASP.NET MVC
【发布时间】:2012-07-13 16:23:52
【问题描述】:

我正在做一个使用 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.HttpMethod 和 Request.Form 具有它们的正确值。

现在的问题是如何使用 Spring.NET 修复版本,以便它像使用 Unity 框架的版本一样工作?

【问题讨论】:

    标签: asp.net-mvc unity-container spring.net


    【解决方案1】:

    我找到了答案!

    我的对象定义是这样的:

    <!-- 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>
    

    一切正常。

    最好的问候, 马蒂亚斯。

    【讨论】:

      【解决方案2】:

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

      hth, 埃里希

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 2018-01-28
        • 2010-10-21
        相关资源
        最近更新 更多