views:

1438

answers:

2

Hi all,

I'm working on a demo that makes use of Spring.NET IoC capability in ASP.NET MVC . It's kind of like the MyBlog application presented on pair programming video tutorial on www.asp.net site. I've completed the same demo using Microsoft's Unity framework and now want to try out the Spring container. To that end I've implemented a simple IControllerFactory that first creates the Spring object factory like that:

IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))

and next it gets the controller from that factory like that:

public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
 IController result = context.GetObject(controllerName) as IController;
 return result;
}

(error handling stripped for simplification purposes).

Now somewhere in my HomeController I have this kind of action:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddEntry([Bind] BlogEntry entry, int id) {
 entry.EntryDate = DateTime.Now;
....

And here's the part of AddEntry.aspx view that defines the editors for entry parameter (really basic stuff):

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

Now here's the deal: When I'm using the Unity IoC it works like a charm. "entry" parameter gets deserialized from my form like it should and the line

entry.EntryDate = DateTime.Now;

completes without problems.

However when I switch to Spring.NET object factory (like described above) things begin to go nuts. First of all the parameter "entry" turns null so an exception is thrown. To track the possible problem on my end I've implemented a sort of custom IModelBinder that looks like that:

public class BlogEntryBinder : IModelBinder {
 public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
  ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
  return result;
 }
}

When I come here using the Unity framework and drill down from bindingContext to HttpRequest I see that the Request.HttpMethod is "POST" and Request.Form is properly filled. When I do the same using Spring.NET the method is "GET" and Request.Form is empty. When however I step to my controller action (AddEntry) and drill down to the Request in both situations I see that the Request.HttpMethod and Request.Form have their proper values.

Now the question is how do I fix the version with Spring.NET so that it works just like the one that uses Unity framework?

Best regards, Matthias.

+3  A: 

I've found the answer!

My object definition looked like that:

<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
 <property name="BlogService" ref="BlogService" />
 <property name="BlogEntryService" ref="BlogEntryService" />
 <property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>

Nevermind the properties being set what it actually does is it returns the same instance every time I ask for this object using

IController result = context.GetObject(controllerName) as IController;

So when I've changed the definition to

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

everything started work just fine.

Best regards, Matthias.

Matthias Hryniszak
+2  A: 

Hi,

just an additional note for clarifying this behavior: Controllers are treated as prototypes by the ASP.NET MVC framework, but Spring defaults to singleton mode. Therefore you need to explicitly mark your object as non-singleton in the container configuration. The upcoming Spring MVC integration module will take care of this, so you won't run into this then.

hth, Erich

Erich Eichinger