我是ASP.NET MVC的新手,基本上与网络相关。对不起,如果这是nooby,但我正在尝试这样做:
我有一个具有复杂属性的ViewModel(此处导航):
public class Request
{
public virtual BaseRequestData RequestData { get; set; }
}
BaseRequestData是抽象的,但有一些继承自它的类,它们有其他类似的属性:
public class AcceleratorRequestData : BaseRequestData
{
[Display(Name="Downside amount")]
[Range(-100,0,ErrorMessage = "Downside participation must be between 0 and -100")]
[Required]
public decimal PutNotional { get; set; }
[Display(Name="Upside strike")]
[Range(1, 2, ErrorMessage = "Upside strike must be between 100% and 200%")]
public decimal CallPercentStrike { get; set; }
}
在我的主'创建'视图中,我绑定到我的Request模型,但是我希望通过用户从下拉列表中选择它来根据其类型(例如,AcceleratorRequestData)为我的BaseRequestData创建部分视图。 我尝试过的是使用一些jQuery调用控制器并根据下拉列表呈现局部视图。这是我的部分视图之一,它是一堆表单组:
@model Synapse.Models.AcceleratorRequestData
@Html.ValidationSummary(true,"",new {@class = "text-danger"})
<div class="form-group">
@Html.LabelFor(m => Model.PutNotional, new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.PutNotional, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.PutNotional, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => Model.CallPercentStrike, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CallPercentStrike, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CallPercentStrike, "", new { @class = "text-danger" })
</div>
</div>
在我的主视图中替换了我的占位符<div>
:
@using (Html.BeginHorizontalForm())
{
@Html.AntiForgeryToken()
<hr/>
@Html.ValidationSummary(true, "", new {@class = "text-danger"})
<div id="accelRequestPh" style="display: none;"></div>
<input type="submit" value="Create" class="btn btn-default" />
}
但是这里我的验证属性和绑定失败了(显然,因为我的BaseRequestData对象没有绑定到我的Request对象的实例)。我怎样才能做到这一点?我应该使用编辑器模板吗?如果我这样做,我的主视图模型将如何知道它们?
答案 0 :(得分:0)
将AcceleratorRequestData
添加到Request
班级:
public class Request
{
public virtual BaseRequestData RequestData { get; set; }
public AcceleratorRequestData acceleratorRequestData { get; set; }
}
然后更改部分视图的模型:
@model Synapse.Models.Request.AcceleratorRequestData
答案 1 :(得分:0)
所以我放弃了下拉列表渲染不同的html元素,而我只是将下拉列表移动到上一页,以便它将具体的子类传递给视图。像这样:
我的下拉列表调用此控制器:
/// <summary>
/// Get the correct view depending on the dropdown
/// </summary>
/// <param name="productType"></param>
/// <returns></returns>
[HttpGet]
public ActionResult Create(string productType)
{
Request request = new Request();
switch (productType)
{
case "Accelerator":
request.RequestData = new AcceleratorRequestData();
request.ColloquialType = ColloquialType.Accelerator;
return View(request);
case "BarrierAccelerator":
request.RequestData = new BarrierAcceleratorRequestData();
request.ColloquialType = ColloquialType.BarrierAccelerator;
return View(request);
default:
return RedirectToAction("Index", "Requests");
}
}
返回父视图:
@using (Html.BeginHorizontalForm())
{
@Html.AntiForgeryToken()
<hr/>
@Html.ValidationSummary(true, "", new {@class = "text-danger"})
@Html.EditorFor(x => x.RequestData)
<input type="submit" value="Create" class="btn btn-default"/>
}
我在这里为每个BaseRequestData的孩子使用编辑器模板。这是一个:
@model Synapse.Models.AcceleratorRequestData
@Html.Hidden("ModelType", Model.GetType())
@Html.ValidationSummary(true,"",new {@class = "text-danger"})
<div class="form-group">
@Html.LabelFor(m => Model.PutNotional, new {@class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.PutNotional, new {htmlAttributes = new {@class = "form-control"}})
@Html.ValidationMessageFor(model => model.PutNotional, "", new {@class = "text-danger"})
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => Model.CallPercentStrike, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CallPercentStrike, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CallPercentStrike, "", new { @class = "text-danger" })
</div>
</div>
隐藏的html助手来自此链接:ViewModel with List<BaseClass> and editor templates
我还必须编辑我的global.cs
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
ModelBinders.Binders.Add(typeof(BaseRequestData), new BaseRequestDataModelBinder());
}
}
public class BaseRequestDataModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
ValueProviderResult typeValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ModelType");
Type type = Type.GetType(
(string)typeValue.ConvertTo(typeof(string)),
true
);
object model = Activator.CreateInstance(type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
return model;
}
}
希望这有助于某人!