使用Spring.NET和ModelBinder的ASP.NET MVC

时间:2008-12-29 21:05:30

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

我正在开发一个在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框架的那样工作?

2 个答案:

答案 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, 埃里希