Статья PHP Best Practices - Различия между PHP на WIMP и PHP на LAMP
Некоторые различия, с которыми вы можете столкнуться при разработке с помощью PHP на Win / IIS против Linux / Apache.
Наиболее очевидным различием между WIMP и LAMP, безусловно, является производительность .
В течение многих лет было очевидное преимущество производительности LAMP над WIMP .
Только недавно у них даже есть шанс сократить этот разрыв.
В настоящее время реализуются 2 проекта, которые могут помочь.В настоящее время доступен IIS7, который, как сообщается, имеет встроенные улучшения производительности PHP в сотрудничестве с командой ZEND.
В будущих проектах участвуют инженеры Microsoft, работающие с инженерами PHP, чтобы получить следующую версию PHP (PHP5.3, которая еще не доступна в настоящее время), чтобы работать намного лучше в IIS. Это, несомненно, приведет к некоторому прогрессу в достижении WIMP производительности LAMP.
Насколько я понимаю, вам нужно больше контроля над своими правилами проверки. Вы можете вручную добавить правила валидации, как описано здесь: Доступна валидация клиента MVC 2.0 Это дает вам полный контроль над тем, как организовать валидацию, какие правила добавлять к каким действиям и т.д.
Если вы хотите использовать одну из нескольких платформ проверки для ASP.NET MVC (xVal, атрибуты аннотаций данных и т. Д.) И проверять только подмножество полей модели для определенного действия, Самое простое решение - использовать атрибут [Bind]
.
Хотя я, конечно, могу вспомнить случай, когда вы можете захотеть проверить только подмножество полей модели (например, в Create
action), я не могу вспомнить случай, когда вы бы хотели, чтобы проверки для конкретного поля были полностью разными для двух разных действий.
Вот простой пример, использующий объект модели Person в сочетании с атрибутами валидатора аннотаций к данным. Действие Создать
и Обновить
будет проверять на соответствие другому набору полей модели.
Модель :
public class Person
{
[Required]
Int32 Id { get; set; }
[Required]
String FirstName {get; set;}
[Required]
String LastName {get; set;}
}
Действия контроллера :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create( [Bind(Exclude = "Id")] Person person )
{
// this action will not perform any validation checks against the Id property of the model
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update( Person person )
{
// this action will perform validation checks against all model properties, including Id
}
В приведенном выше примере действие Create
полностью игнорирует атрибут Id
элемента ] Объект модели Person
. Он не будет пытаться связать это свойство и не будет пытаться выполнять какие-либо проверки для него. Поскольку человек не имеет идентификатора на момент создания, это именно то, что вам нужно. С другой стороны, действие Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить несколько дополнительных разрывов строк и пробелов, чтобы уменьшить некрасивость.
public class Person
{
[Required]
Int32 Id { get; set; }
[Required]
String FirstName {get; set;}
[Required]
String LastName {get; set;}
}
Действия контроллера :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create( [Bind(Exclude = "Id")] Person person )
{
// this action will not perform any validation checks against the Id property of the model
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update( Person person )
{
// this action will perform validation checks against all model properties, including Id
}
В приведенном выше примере действие Create
полностью игнорирует атрибут Id
объекта модели Person
. Он не будет пытаться связать это свойство и не будет пытаться выполнять какие-либо проверки для него. Поскольку человек не имеет идентификатора на момент создания, это именно то, что вам нужно. С другой стороны, действие Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить дополнительные разрывы строк и пробелы, чтобы уменьшить уродство.
public class Person
{
[Required]
Int32 Id { get; set; }
[Required]
String FirstName {get; set;}
[Required]
String LastName {get; set;}
}
Действия контроллера :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create( [Bind(Exclude = "Id")] Person person )
{
// this action will not perform any validation checks against the Id property of the model
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update( Person person )
{
// this action will perform validation checks against all model properties, including Id
}
В приведенном выше примере действие Create
полностью игнорирует атрибут Id
объекта модели Person
. Он не будет пытаться связать это свойство и не будет пытаться выполнять какие-либо проверки для него. Поскольку человек не имеет идентификатора на момент создания, это именно то, что вам нужно. С другой стороны, действие Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить дополнительные разрывы строк и пробелы, чтобы уменьшить уродство.
Create
полностью игнорирует атрибут Id
объекта модели Person
. Он не будет пытаться связать это свойство и не будет пытаться выполнять какие-либо проверки для него. Поскольку человек не имеет идентификатора на момент создания, это именно то, что вам нужно. С другой стороны, действие Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить дополнительные разрывы строк и пробелы, чтобы уменьшить уродство.
Create
полностью игнорирует атрибут Id
объекта модели Person
. Он не будет пытаться связать это свойство и не будет пытаться выполнять какие-либо проверки для него. Поскольку человек не имеет идентификатора на момент создания, это именно то, что вам нужно. С другой стороны, действие Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить дополнительные разрывы строк и пробелы, чтобы уменьшить уродство.
Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить несколько дополнительных разрывов строк и пробелов, чтобы уменьшить некрасивость.
Update
будет связывать и проверять на соответствие всем свойствам модели.
Тот факт, что атрибут Bind
указан в аргументе метода, может сделать код немного некрасивый. Однако, если список Exclude
становится длинным, вы всегда можете добавить дополнительные разрывы строк и пробелы, чтобы уменьшить уродство.
Если вы используете ASP.NET MVC 1, вы должны проверить расширение DataAnnotationsModelBinder. System.ComponentModel.DataAnnotations - очень полезная структура атрибутов проверки! И ASP.NET MVC 2 DefaultModebinder поддерживал его.
http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471
Вероятно, лучше всего использовать Validator Toolkit для ASP.NET MVC
Этот набор инструментов генерирует код проверки на стороне клиента и на стороне сервера.
Вот недавняя запись в блоге, которая сравнивает различные методы проверки и фреймворки .
Если вы используете jQuery, то стоит использовать подключаемый модуль проверки jQuery . Конечно, вам все равно придется написать свою собственную проверку на стороне сервера (или использовать для этого другую структуру).
Используйте библиотеку проверки, такую как FluentValidation или NHibernate Validators, для проверки. Переместите этот код в связыватель модели, чтобы при передаче модели выполнялась автоматическая проверка. Вы можете посмотреть следующую модель привязки, которая работает с FluentValidation
public class FluentValidationModelBinder : DefaultModelBinder {
private readonly IValidatorFactory _validatorFactory;
public FluentValidationModelBinder(IValidatorFactory validatorFactory) {
_validatorFactory = validatorFactory;
}
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) {
var model = bindingContext.Model;
base.OnModelUpdated(controllerContext, bindingContext);
IValidator validator = _validatorFactory.GetValidator(bindingContext.ModelType);
if (validator != null) {
var result = validator.Validate(model);
if (!result.IsValid) {
result.AddToModelState(bindingContext.ModelState, "");
}
}
}
}
Уточнение: я думаю, что это требует некоторого разъяснения, потому что ответы, похоже, не касаются вопроса.
Например,
Создать подтверждение личности, у которой есть имя, возраст и адрес электронной почты не используется. Удалить человека. Подтверждает, что данное лицо не является родителем. Бизнес-логика диктует, что Родители не могут быть исключены
Как мне использовать эти два разных сценария проверки?
«Инкапсулировать то, что меняется».
Один из способов добиться этого - использовать шаблон Command и применить вашу проверку к команде вместо сущности. Вот простой пример без использования какой-либо структуры проверки, но идея та же.
public class Blub
{
public int BlubId { get; set; }
public string Name { get; set; }
public bool SomeBlockingCondition { get; set; }
}
public class BlubEditController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Rename(int blubId)
{
var ctx = new DataContext();
var blub = ctx.Blubs.Single(o => o.BlubId==blubId);
return ShowRenameForm(blub);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Rename(int blubId, RenameCommand cmd)
{
var ctx = new DataContext();
var blub = ctx.Blubs.Single(o => o.BlubId==blubId);
cmd.Subject = blub;
if (cmd.Validate(ModelState, "cmd."))
{
cmd.Execute();
ctx.SubmitChanges();
return RedirectToAction("Show", new { blubId = blubId });
}
else
{
return ShowRenameForm(blub);
}
}
}
public class RenameCommand
{
public Blub Subject { get; set; }
public string Name { get; set; }
public bool Validate(ModelStateDictionary modelState, string prefix)
{
if (Subject.SomeBlockingCondition)
{
modelState.AddModelError(prefix + "SomeBlockingCondition", "No!");
return false; // Optional shortcut return to prevent further validation.
}
if (String.IsNullOrEmpty(this.Name))
{
modelState.AddModelError(prefix + "Name", "Seriously, no.");
}
return modelState.IsValid;
}
public void Execute()
{
Subject.Name = this.Name;
}
}
Я думаю, для этого случая просто напишите какой-нибудь код в доменной модели (BLL) DELETE, чтобы судить, можно ли удалить какое-то Человек, или напишите какой-нибудь код в sql или sp и верните значение, которое нужно вычесть, если удаление выполнено.