SORU
19 HAZİRAN 2011, Pazar


multi-adım kayıt süreci sorunları ASP.NET mvc (parçalı viewmodels, tek model)

Bir ben varmulti-adım kayıt sürecibir tarafından desteklenmektediretki alanı katman tek nesnedoğrulama kuralları özellikleri tanımlanmış olan ,

Nasıl etki çok görüş arasında bölünmüş olduğunda etki alanı nesne doğrulamak Gerekir ve mutlaka nesne kısmen ilk görünümünde kurtarmak zorundayım?

Seans ama Bu mümkün değil kullanma sürecinin uzun olduğunu ve veri miktarı yüksek diye düşündüm, oturum kullanmak istemiyorum.

Düşündüm tasarrufu tüm veri bir ilişkisel bellek db (aynı şema olarak ana db)ve daha sonra kızarma verilere ana db ama sorunlar ortaya neden gereken yol arasında hizmetleri (talep manzaraları) olan çalışma ile ana db ve bellek db.

Ben zarif ve temiz bir çözüm arıyor (daha doğrusu en iyi yöntem).

GÜNCELLEME VE Açıklama:

@Darin düşünceli Cevabınız için Teşekkür ederim. Bu şimdiye kadar yaptığım tam olarak buydu. Ama bu arada birçok ekleri hangi bir istek var, ben bu belgeleri yükleyebilir ki Step2View örneğin, zaman uyumsuz olarak tasarım , ama bu ekleri önce Step1View kaydedilmiş olması gereken bir tablo için başvuru ile ilgili olarak bir tablo kaydedilmesi gerekir.

Step1 etki alanı nesnesi (kısmen) kurtarmak isterdim, Ama yapamam böylece, kısmen dönüştürülmüş gelen sahne olmadan kaydedilemez Adım 1 Bir ViewModel eşlenmiş destekli Çekirdek Etki alanı nesnesi Step2ViewModel neden.

CEVAP
19 HAZİRAN 2011, Pazar


İlk görüşleriniz herhangi bir etki alanı nesneleri kullanarak olmamalıdır. Görünüm modelleri kullanıyor olması gerekir. Her görünüm model verilen görüntülemek için gerekli olan tek özellikleri doğrulama bu verilen görüntülemek için belirli nitelikleri de içerir. Eğer öyleyse 3 adım sihirbazı varsa bu 3 görünüm modelleri, her adım için bir olması anlamına gelir:

public class Step1ViewModel
{
    [Required]
    public string SomeProperty { get; set; }

    ...
}

public class Step2ViewModel
{
    [Required]
    public string SomeOtherProperty { get; set; }

    ...
}

ve benzeri. Tüm bu görünüm modelleri ana görünüm Sihirbazı modeli tarafından desteklenen olabilir:

public class WizardViewModel
{
    public Step1ViewModel Step1 { get; set; }
    public Step2ViewModel Step2 { get; set; }
    ...
}

o zaman denetleyici eylemleri Sihirbazı sürecinin her aşamasını oluşturma ve görüntüleme WizardViewModel ana geçirilmesi olabilir. Denetleyicisi eylem içinde ilk adım ne zaman Step1 özelliği başlatmak olabilir. Daha sonra içindeki Görünüm form kullanıcı Adım 1 hakkında özelliklerini doldurmak için izin oluşturur. Form gönderildiğinde denetleyicisi eylem Adım 1 için doğrulama kuralları geçerlidir

[HttpPost]
public ActionResult Step1(Step1ViewModel step1)
{
    var model = new WizardViewModel 
    {
        Step1 = step1
    };

    if (!ModelState.IsValid)
    {
        return View(model);
    }
    return View("Step2", model);
}

Şimdi adım 2 görünüm içinde form içinde gizli bir alan (Eğer isterseniz bir görünüm durumu sıralama) Adım 1 seri hale getirmek için MVC vadeli Html.Serialize helper kullanabilirsiniz:

@using (Html.BeginForm("Step2", "Wizard"))
{
    @Html.Serialize("Step1", Model.Step1)
    @Html.EditorFor(x => x.Step2)
    ...
}

adım 2 ve SONRASI eylemi içinde:

[HttpPost]
public ActionResult Step2(Step2ViewModel step2, [Deserialize] Step1ViewModel step1)
{
    var model = new WizardViewModel 
    {
        Step1 = step1,
        Step2 = step2
    }

    if (!ModelState.IsValid)
    {
        return View(model);
    }
    return View("Step3", model);
}

Ve böylece WizardViewModel tüm veri ile dolu olacak son adıma kadar. Sonra bir etki alanı modeli görünüm modeli göster ve işlem için servis katmanına geçirir. Servis katmanı herhangi bir doğrulama kuralları kendisi ve yapabilecekleri ...

Ayrıca başka bir alternatif var: javascript kullanarak ve aynı sayfada. tüm koyarak Sihirbazı işlevleri (Stepy güzel olanıdır) sağlamak jquery plugins insan var. Temelde ve bu durumda artık adımlar arasında devlet ısrar endişelenmenize gerek istemci div gösterme ve gizleme meselesi.

Ama seçtiğiniz ne olursa olsun her zaman görünüm modelleri kullanmak ve bu görünüm modelleri üzerinde doğrulama gerçekleştirmek. Etki alanı modelleri veri açıklama doğrulaması öznitelikleri sokuyorsun sürece etki modelleri görünümleri uyum olarak çok zor bir mücadele olacak.


GÜNCELLEME:

TAMAM, benim cevabım açık olmadığı sonucuna çiziyorum çok sayıda yorum nedeniyle. Ve kabul etmeliyim. Bu yüzden beni daha da benim örnek ayrıntılı etmeye çalışayım.

Tüm görünüm modelleri adım uygulanması gereken bir arayüz (sadece işaretleyici arayüzü) tanımlayabiliriz:

public interface IStepViewModel
{
}

sonra her adım elbette ilgili doğrulama özniteliklerinin yanı sıra gerekli özellikleri içerir nerede sihirbaz için 3 adımları tanımlayın:

[Serializable]
public class Step1ViewModel: IStepViewModel
{
    [Required]
    public string Foo { get; set; }
}

[Serializable]
public class Step2ViewModel : IStepViewModel
{
    public string Bar { get; set; }
}

[Serializable]
public class Step3ViewModel : IStepViewModel
{
    [Required]
    public string Baz { get; set; }
}

biz bir sonraki adımları ve bir adım geçerli bir dizin oluşur: ana Sihirbazı görünüm model tanımlayın

[Serializable]
public class WizardViewModel
{
    public int CurrentStepIndex { get; set; }
    public IList<IStepViewModel> Steps { get; set; }

    public void Initialize()
    {
        Steps = typeof(IStepViewModel)
            .Assembly
            .GetTypes()
            .Where(t => !t.IsAbstract && typeof(IStepViewModel).IsAssignableFrom(t))
            .Select(t => (IStepViewModel)Activator.CreateInstance(t))
            .ToList();
    }
}

Sonra denetleyicisi geçiyoruz:

public class WizardController : Controller
{
    public ActionResult Index()
    {
        var wizard = new WizardViewModel();
        wizard.Initialize();
        return View(wizard);
    }

    [HttpPost]
    public ActionResult Index(
        [Deserialize] WizardViewModel wizard, 
        IStepViewModel step
    )
    {
        wizard.Steps[wizard.CurrentStepIndex] = step;
        if (ModelState.IsValid)
        {
            if (!string.IsNullOrEmpty(Request["next"]))
            {
                wizard.CurrentStepIndex  ;
            }
            else if (!string.IsNullOrEmpty(Request["prev"]))
            {
                wizard.CurrentStepIndex--;
            }
            else
            {
                // TODO: we have finished: all the step partial
                // view models have passed validation => map them
                // back to the domain model and do some processing with
                // the results

                return Content("thanks for filling this form", "text/plain");
            }
        }
        else if (!string.IsNullOrEmpty(Request["prev"]))
        {
            // Even if validation failed we allow the user to
            // navigate to previous steps
            wizard.CurrentStepIndex--;
        }
        return View(wizard);
    }
}

Bu kumanda ile ilgili açıklamalar:

  • Endeks SONRASI eylemi MvcContrib NuGet yüklediğinizden emin olun Microsoft Vadeli kütüphane [Deserialize] öznitelikleri kullanır. Bu görünüm modelleri [Serializable] özniteliği ile donatılmış olmalıdır nedeni budur
  • Dizin POST eylem bu özel model binder lazım mantıklı olarak değişken IStepViewModel bir arayüz alır.

İşte ilgili model cilt:

public class StepViewModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var stepTypeValue = bindingContext.ValueProvider.GetValue("StepType");
        var stepType = Type.GetType((string)stepTypeValue.ConvertTo(typeof(string)), true);
        var step = Activator.CreateInstance(stepType);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, stepType);
        return step;
    }
}

Bu bağlayıcı özel bir alanı her adım somut türünü içeren ve her istek gönder verdiğimiz StepType denilen kullanır.

Bu model binder Application_Start kaydedilir:

ModelBinders.Binders.Add(typeof(IStepViewModel), new StepViewModelBinder());

Bulmacanın son kayıp bit görünümleri vardır. İşte ~/Views/Wizard/Index.cshtml ana görünüm:

@using Microsoft.Web.Mvc
@model WizardViewModel

@{
    var currentStep = Model.Steps[Model.CurrentStepIndex];
}

<h3>Step @(Model.CurrentStepIndex   1) out of @Model.Steps.Count</h3>

@using (Html.BeginForm())
{
    @Html.Serialize("wizard", Model)

    @Html.Hidden("StepType", Model.Steps[Model.CurrentStepIndex].GetType())
    @Html.EditorFor(x => currentStep, null, "")

    if (Model.CurrentStepIndex > 0)
    {
        <input type="submit" value="Previous" name="prev" />
    }

    if (Model.CurrentStepIndex < Model.Steps.Count - 1)
    {
        <input type="submit" value="Next" name="next" />
    }
    else
    {
        <input type="submit" value="Finish" name="finish" />
    }
}

Ve bu çalışmayı yapmak için gereken tüm. Eğer istersen tabii görünümünü kişiselleştirmek ve özel bir editör tanımlayarak bazı veya sihirbazın tüm adımları hissediyorum şablon olabilir. Mesela, adım 2 için yap. Biz ~/Views/Wizard/EditorTemplates/Step2ViewModel.cshtml kısmi tanımlayın:

@model Step2ViewModel

Special Step 2
@Html.TextBoxFor(x => x.Bar)

Yapısı gibi görünüyor:

enter image description here

Tabii ki iyileşme için bir oda var. Endeks SONRASI eylemi s..t gibi görünüyor. Çok fazla kod var. Daha da basitleştirilmesi dizin, geçerli dizin yönetimi, sihirbaz, geçerli adım kopyalama gibi tüm altyapı şeyleri hareket halinde yer alacağı, ... başka bir model haline binder. Son olarak karşımıza bu yüzden:

[HttpPost]
public ActionResult Index(WizardViewModel wizard)
{
    if (ModelState.IsValid)
    {
        // TODO: we have finished: all the step partial
        // view models have passed validation => map them
        // back to the domain model and do some processing with
        // the results
        return Content("thanks for filling this form", "text/plain");
    }
    return View(wizard);
}

hangi POST eylemleri gibi görünmelidir nasıl. Bir dahaki sefere bu gelişme gidiyorum :-)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • HBO

    HBO

    17 Mayıs 2006
  • hytchme

    hytchme

    9 Mart 2014
  • Qmusic Romania

    Qmusic Roman

    8 Temmuz 2011