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

3

我正在开发一个演示项目,其中使用了Spring.NET IoC技术在ASP.NET MVC中实现。它有点像www.asp.net网站上的配对编程视频教程中介绍的MyBlog应用程序。我已经使用了微软的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个回答

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>

一切都正常地开始工作了。
最好的祝福, 马蒂亚斯。

2

这里有一点需要澄清的是:ASP.NET MVC框架将控制器视为原型,而Spring默认为单例模式。因此,您需要在容器配置中显式将对象标记为非单例。即将推出的Spring MVC集成模块将解决此问题,届时您就不会遇到此类问题。

希望对你有所帮助, Erich


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接