ASP.NET MVC сохранить новую запись стихи обновить существующие соглашения записи - PullRequest
1 голос
/ 20 сентября 2010

Я работаю над своим первым приложением ASP.NET MVC (бета-версия для версии 3) (использующим EF4) и немного борюсь с некоторыми соглашениями о сохранении новой записи и обновлении существующей.Я использую стандартное сопоставление маршрутов.

Когда пользователь переходит на страницу / сеанс / оценку, он может ввести новую запись и сохранить ее.У меня есть действие, определенное так:

[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(EvaluteSessionViewModel evaluatedSession)
{
}

Когда они сохраняются, я беру сущность из модели представления, присоединяю ее к своему контексту и сохраняю.Все идет нормально.Теперь я хочу, чтобы пользователь мог редактировать эту запись через url / session / Evaluate / 1, где '1' - это идентификатор записи.

Редактировать: моя сущность EF присоединена как свойство к представлениюМодель.

Если я добавлю перегруженный метод, как этот (чтобы я мог получить часть '1' автоматически).

[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(ID, EvaluteSessionViewModel evaluatedSession)
{
}

Я получаю сообщение об ошибке «Текущий запрос действия« Оценить »для типа контроллера« SessionsController »является неоднозначным между следующим действием».Я не уверен, почему они неоднозначны, так как они выглядят уникальными для меня.

Я решил, что сейчас собираюсь пропустить эту проблему и посмотреть, смогу ли я получить ее для обновления существующей записи, поэтому я закомментировал EvaluateSave, у которого не было параметра ID.

Я хотел бы сделать следующее:

// Load the original entity from EF
// Rebind the postback so that the values posted update the entity
// Save the result

Поскольку сущность заполняется как параметр (оценочный сеанс), повторное связывание происходит слишком рано.Но когда я посмотрел на подход, который хотел бы использовать, я понял, что он открывает мой код для взлома (поскольку пользователь может добавлять поля на опубликованную заднюю страницу, и они могут переопределять значения, которые я установил в сущности).

Так что мне кажется, что мне приходится вручную проверять каждое поле, чтобы увидеть, изменилось ли оно и, если оно есть, обновить его.Примерно так:

if (evaluatedSession.MyEntity.myField <> savedSession.myField)
   savedSession.myField = evaluatedSession.MyEntity.myField;

Или сохраните копию сущности и убедитесь, что ни одна из не редактируемых пользователем не изменилась.Гадость.

Итак, два вопроса:

Первый: как избавиться от перегруженных методов?

Второе: есть ли лучший способ обработки обновления ранее сохраненной записи?

Редактировать: Я думаю, я мог бы использовать что-то вроде Automapper ...

Редактировать 9/22/ 2010 - ОК, похоже, это должно работать с комбинацией двух элементов: вы можете контролировать, какие поля связывать (и, в частности, исключать некоторые из них), с помощью атрибута [Bind (Exclude = "field1, field2")] либона уровне класса или как часть метода, выполняющего сохранение, напр.

public ActionResult EvaluateSave([Bind(Exclude="field1")] EvaluateSessionViewModel evaluatedSession)

С точки зрения EF вы должны иметь возможность использовать метод ApplyCurrentValues ​​() из контекста, например.

context.ApplyCurrentValues(savedEval.EntityKey.EntitySetName, evaluatedSession);

Конечно, это не такПохоже, работать на меня.Я продолжаю получать «Объект с ключом, который совпадает с ключом предоставленного объекта, не может быть найден в ObjectStateManager. Убедитесь, что значения ключа предоставленного объекта соответствуют значениям ключа объекта, к которому должны быть применены изменения».

Я попытался присоединить исходную сущность, которую только что загрузил, на тот случай, если она по какой-то причине не была присоединена к контексту (до ApplyCurrentValues):

context.AttachTo(savedEval.EntityKey.EntitySetName, savedEval);

По-прежнему происходит сбой.Я предполагаю, что это как-то связано с типом объекта сущности EF, который создает MVC (возможно, он недостаточно заполнен, чтобы EF4 что-то с ним сделал?).Я надеялся включить .NET Framework, чтобы пройтись по нему, чтобы посмотреть, что он пытается сделать, но, похоже, EF4 не является частью сделки.Я посмотрел на него с помощью Reflector, но мне немного сложно представить, что происходит.

1 Ответ

1 голос
/ 20 сентября 2010

Ну, как это работает, вы можете иметь только одно имя метода на httpverb. Поэтому самый простой способ - создать новое имя действия. Что-то вроде «Создать» для новых записей и «Редактировать» для существующих записей.

Вы можете использовать AntiForgeryToken (http://msdn.microsoft.com/en-us/library/dd492767.aspx) для проверки данных. Это не останавливает все попытки взлома, но это дополнительное преимущество.

Дополнительно

Причина, по которой вы можете иметь только одно имя действия на httpverb, заключается в том, что связыватели модели пытаются только связать модель и на самом деле не зависят от типа. Если у вас было два метода с одним и тем же именем действия и двумя различными типами параметров, он не может просто попытаться найти наилучшее совпадение, потому что ваше намерение может быть однозначным, а программа видит только какое-то наилучшее совпадение. Например, у вас может быть параметр Id и модель, содержащая идентификатор свойства, и он может не знать, какой из них вы собираетесь использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...