MVC3显示来自一个数据源的下拉列表并保存到另一个数据源

时间:2011-10-17 17:03:04

标签: asp.net-mvc-3 data-binding razor

经过3个月的休整后,我又回到了MVC3项目。我需要显示一个从数据库A中提取的下拉列表,但是保存到数据库B.我需要保留的属性是NAICS / SIC代码。现在我只是向用户提供一个文本框来键入自由格式文本。所以,我有这种机制。但它应该只提供源数据库中有效的代码列表。

棘手的是我正在使用自定义模型绑定器动态生成我的ViewModel,所以我没有一个独特的.cshtml文件来自定义。

[Serializable]
    public class Step4ViewModel : IStepViewModel
    {
        public Step4ViewModel()
        {


        }


        //load naics codes from somewhere

        [Display(Name = "Describe the nature of your business.")]
        public String NatureOfBusiness { get; set; }


        [Display(Name="NAICS/SIC CODE")]
        public String BusinessTypeCode { get; set; }

Tricky ViewModel

@using Microsoft.Web.Mvc;
@using Tangible.Models;

@model Tangible.Models.WizardViewModel 

@{ 
    var currentStep = Model.Steps[Model.CurrentStepIndex];
    var progress = ((Double)(Model.CurrentStepIndex) / Model.Steps.Count) * 100;
} 
<script type="text/javascript">
    $(function () {
        $("#progressbar").progressbar({
            value: @progress
        });
    });

</script> 

<div id="progressbar" style="height:20px;">
<span style="position:absolute;line-height:1.2em; margin-left:10px;">Step @(Model.CurrentStepIndex + 1) out of @Model.Steps.Count</span> 
</div>
    @Html.ValidationSummary()
@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="Save &amp; Continue" name="next"  /> 
    }
    else
    { 
        <input type="submit" value="Finish" name="finish" /> 
    }

         @*<input type="submit" value="Save" name="Save" />*@
}

控制器

[HttpPost]
        public ActionResult Index([Deserialize] WizardViewModel wizard, IStepViewModel step)
        {


            wizard.Steps[wizard.CurrentStepIndex] = step;
            if (ModelState.IsValid)
            {

                    //Always save.
                    var obj = new dr405();

                    //wire up to domain model;
                    foreach (var s in wizard.Steps)
                    {
                        Mapper.Map(s,obj,s.GetType(), typeof(dr405));
                    }

                    using (var service = new DR405Service())
                    {
                        //Do something with a service here.
                        service.Save(db, obj);
                    }


                if (!string.IsNullOrEmpty(Request["next"]))
                {
                    wizard.CurrentStepIndex++;
                }
                else if (!string.IsNullOrEmpty(Request["prev"]))
                {
                    wizard.CurrentStepIndex--;
                }
                else
                {
                    return View("Upload", obj);

                }
            }
            else if (!string.IsNullOrEmpty(Request["prev"]))
            {
                wizard.CurrentStepIndex--;
            }

            return View(wizard);


        }

WizardViewModel

 [Serializable]
    public class WizardViewModel
    {

        public String AccountNumber { get; set; }
        public int CurrentStepIndex { get; set; }
        public Boolean IsInitialized { get { return _isInitialized; } }

        public IList<IStepViewModel> Steps { get; set; }

        private Boolean _isInitialized = false;

        public void Initialize()
        {
            try
            {
                Steps = typeof(IStepViewModel)
                    .Assembly.GetTypes().Where(t => !t.IsAbstract && typeof(IStepViewModel).IsAssignableFrom(t)).Select(t => (IStepViewModel)Activator.CreateInstance(t)).ToList();
                _isInitialized = true;
                //rewrite this.  get the profile and wire them up or something.
                this.AccountNumber = Tangible.Profiles.DR405Profile.CurrentUser.TangiblePropertyId;

            }
            catch (Exception e)
            {

                _isInitialized = false;
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

您可以通过在字段中添加UIHint属性,为视图模型上的特定属性指定模板。由于您的视图在模型上调用EditorFor,因此它将使用您使用UIHint指定的模板。

BusinessTypeDropdown.ascx - (置于Views / Shared / EditorTemplates

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% var businessTypes = ViewData["businessTypes"] as IEnumerable<string>; %>
<%= Html.DropDownListFor(m => m , new SelectList(businessTypes, Model))%>

在您的视图模型中

[Serializable]
public class Step4ViewModel : IStepViewModel
{
    public Step4ViewModel()
    {


    }


    //load naics codes from somewhere

    [Display(Name = "Describe the nature of your business.")]
    public String NatureOfBusiness { get; set; }


    [Display(Name="NAICS/SIC CODE")][UIHint("BusinessTypeDropdown")]
    public String BusinessTypeCode { get; set; }

然后在您的控制器中,只需将ViewData["businessTypes"]设置为您的业务类型列表。

答案 1 :(得分:0)

如果不了解您的“棘手”视图模型代码,很难提出有用的建议。

然而,这里应该没有太多问题。您需要以某种方式在yoru视图中创建下拉列表,并从控制器传递的数据中填充它。

所有工作都在您的控制器中进行。填充您的列表或IEnumerable或您的第一个数据库中的任何数据源,然后在您的帖子处理程序中将选择保存到您的第二个数据库(第二部分应该与您已有的不同)。