我有一个名为Entity
public class Entity
{
public string Name { get; set; }
public Location Place { get; set; }
}
和一个名为Location
public class Location
{
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
}
一个Entity
包含Location
,因此我想为Location
生成3个下拉列表。
我可以像
那样手动完成@Html.DropDownListFor(o => o.Country, new [] { new SelectListItem() { Text = "United States", Value="US" } })
<br />
@Html.DropDownListFor(o => o.State, new [] { new SelectListItem() { Text = "Some State", Value="SS" } })
<br />
@Html.DropDownListFor(o => o.City, new[] { new SelectListItem() { Text = "Some city", Value = "City" } })
但我的网站上有几个地方需要完全相同的3个下拉列表,例如Restaurant
,Hotel
以及其他也有Location
的类。我试图创建一个部分视图来启动一个新表单,但我得到一个例外:
传递到字典中的模型项的类型为“TestMVC3Razor.Controllers.Entity”,但此字典需要“TestMVC3Razor.Controllers.Location”类型的模型项,使用以下代码:
@model TestMVC3Razor.Controllers.Entity
@using (Html.BeginForm())
{
@Html.Partial("LocationSelector", Model.Place)
<br />
<input type="submit" value="Submit" />
}
部分视图是
@model TestMVC3Razor.Controllers.Location
@using (Html.BeginForm())
{
@Html.DropDownListFor(o => o.Country, new [] { new SelectListItem() { Text = "United States", Value="US" } })
<br />
@Html.DropDownListFor(o => o.State, new [] { new SelectListItem() { Text = "Some State", Value="SS" } })
<br />
@Html.DropDownListFor(o => o.City, new[] { new SelectListItem() { Text = "Some city", Value = "City" } })
}
这显然不应该奏效,但我想做类似的事情,像这样的帮手会很完美
@Html.LocationSelectFor(o => o.Location)
但我该如何做?我需要生成3 dropdowns
,当我发布操作时,我需要使用出价值来获取对象。
public ActionResult(Location loc)
{
var x = String.Format("{0}, {1} - {2}", loc.City, loc.Country, loc.State);
}
如何在发布时让这个助手创建 3下拉和绑定值?
答案 0 :(得分:1)
只需从HtmlHelper创建自己的扩展程序:
public static HtmlHelperExtensions {
public static MvcString LocationSelectFor<TModel, TProperty>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel,TProperty>> expression) {
// examine expression and build html
}
}
诀窍是看表情。这篇博客文章可以帮助您入门:http://geekswithblogs.net/Madman/archive/2008/06/27/faster-reflection-using-expression-trees.aspx
或者,您可以为Location类创建EditorTemplate。只需google for asp.net mvc editortemplate。 http://www.codecapers.com/post/Display-and-Editor-Templates-in-ASPNET-MVC-2.aspx
就个人而言,我会坚持使用EditorTemplates,因为您可以更改视图而无需重新编译。
答案 1 :(得分:0)
您可以按照此示例使用表达式和表达式主体
Get Custom Attributes from Lambda Property Expression
或者只使用字符串表达式并将其操作为http://www.joelscode.com/post/Use-MVC-Templates-with-Dynamic-Members-with-custom-HtmlHelper-Extensions.aspx
答案 2 :(得分:0)
在xixonia之后,我得到了我需要的东西。
@Html.EditorFor(o => o.Place, "LocationSelector",
new CreateLocation{ Country = "US", State = "A", City = "Y" })
我在
下有一个模板Views
|- Shared
|- EditorTemplates
LocationSelector.cshtml
@model TestMVC3Razor.Controllers.CreateLocation
@using TestMVC3Razor.Controllers
@Html.DropDownListFor(o => o.Country, Model.CountryList)
<br />
@Html.DropDownListFor(o => o.State, Model.StateList)
<br />
@Html.DropDownListFor(o => o.City, Model.CityList)
然后我做了
public class CreateEntity
{
[Required]
public string Name { get; set; }
public CreateLocation Place { get; set; }
}
public class CreateLocation
{
public CreateLocation(Location location = null)
{
if (location != null)
{
Country = location.Country;
State = location.State;
City = location.City;
}
}
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
public IEnumerable<SelectListItem> CountryList
{
get
{
var list = new[]
{
new SelectListItem() { Text = "US", Value = "US" },
new SelectListItem() { Text = "BR", Value = "BR" },
new SelectListItem() { Text = "ES", Value = "ES" },
};
var selected = list.FirstOrDefault(o => o.Value == Country);
if (selected != null)
{
selected.Selected = true;
}
return list;
}
}
public IEnumerable<SelectListItem> StateList
{
get
{
var list = new[]
{
new SelectListItem() { Text = "A", Value = "A" },
new SelectListItem() { Text = "B", Value = "B" },
new SelectListItem() { Text = "C", Value = "C" },
};
var selected = list.FirstOrDefault(o => o.Value == State);
if (selected != null)
{
selected.Selected = true;
}
return list;
}
}
public IEnumerable<SelectListItem> CityList
{
get
{
var list = new[]
{
new SelectListItem() { Text = "X", Value = "X" },
new SelectListItem() { Text = "Y", Value = "Y" },
new SelectListItem() { Text = "Z", Value = "Z" },
};
var selected = list.FirstOrDefault(o => o.Value == City);
if (selected != null)
{
selected.Selected = true;
}
return list;
}
}
}
我的控制器
public class HomeController : Controller
{
public ActionResult Index()
{
// can load data for edit
return View(new CreateEntity { Place = new CreateLocation(TempData["Location"] as Location) });
}
[HttpPost]
public ActionResult Index(Entity ent)
{
var loc = ent.Place;
var x = String.Format("{0} {1} {2}", loc.Country, loc.State, loc.City);
ViewBag.Result = x; // display selected values
TempData["Location"] = loc;
return Index();
}
}
我不知道这是否是最佳解决方案,但至少我可以致电
@Html.EditorFor(o => o.Place, "LocationSelector", obj)
来自任何地方,并在我的网站上有一个默认的地点选择器。