Вопрос

Я работаю над демонстрацией, в которой используются возможности Spring.NET IoC в ASP.NET MVC.Это что-то вроде приложения MyBlog, представленного в видеоуроке по парному программированию на сайте www.asp.net.Я выполнил ту же демонстрацию, используя платформу 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, и углубляюсь от привязкиконтекста к HttpRequest, я вижу, что Request.HttpMethod имеет значение «POST», а Request.Form правильно заполнен.Когда я делаю то же самое, используя Spring.NET, метод «GET», а Request.Form пуст.Однако когда я перехожу к действию моего контроллера (AddEntry) и углубляюсь в запрос в обеих ситуациях, я вижу, что Request.HttpMethod и Request.Form имеют правильные значения.

Теперь вопрос в том, как исправить версию с Spring.NET, чтобы она работала так же, как та, которая использует платформу Unity?

Это было полезно?

Решение

Я нашел ответ!

Мое определение объекта выглядело так:

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

все стало работать нормально.

С уважением, Матиас.

Другие советы

просто дополнительное примечание для пояснения этого поведения:Платформа ASP.NET MVC рассматривает контроллеры как прототипы, но Spring по умолчанию использует одноэлементный режим.Поэтому вам необходимо явно пометить ваш объект как неодноэлементный в конфигурации контейнера.Об этом позаботится предстоящий модуль интеграции Spring MVC, так что вы с этим не столкнетесь.

HTH, Эрих

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top