在我的MVC项目中,我将货币列表传递到下拉列表中的视图。但是,一旦我尝试发布视图,我会得到以下异常:
具有键“FromCurrencyId”的ViewData项是类型 'System.Int32'但必须是'IEnumerable'类型。
货币控制器
namespace Project.Controllers
{
public class CurrencyController : Controller
{
[HttpGet]
// GET: Currency
public ActionResult Index()
{
CurrenciesClient Cur = new CurrenciesClient();
var listCurrency = Cur.findAll().ToList();
Currencies model = new Currencies();
model.FromCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
model.ToCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
return View(model);
}
[HttpPost]
public ActionResult Index(Currencies cur)
{
if (ModelState.IsValid)
{
if (cur.FromCurrencyId == cur.ToCurrencyId)
{
//do something if same currecnies and return.
ModelState.AddModelError("CurrencyCountry", "Can't make the conversion for the same value");
}
else
{
some code .....
}
}
return View(cur);
}
}
}
货币VM
namespace Project.ViewModels
{
public class Currencies
{
public int Id { get; set; }
[Required]
public int FromCurrencyId { get; set; }
public SelectList FromCurrencies { get; set; }
[Required]
public int ToCurrencyId { get; set; }
public SelectList ToCurrencies { get; set; }
public string CurrencyName { get; set; }
public string CurrencyCountry { get; set; }
[Required]
public decimal ConversionRate { get; set; }
public decimal Value { get; set; }
public SelectList AvailableCurrencies { get; set; }
}
}
CurrencyClient Web服务VM
namespace Project.ViewModels
{
public class CurrenciesClient
{
private string base_Url = "http://localhost:51646/api/";
public IEnumerable<Currencies> findAll()
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(base_Url);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("currencies").Result;
if (response.IsSuccessStatusCode)
{
var resposeData = response.Content.ReadAsStringAsync().Result;
var Currency = JsonConvert.DeserializeObject<List<Currencies>>(resposeData);
return Currency;
}
return null;
}
catch
{
return null;
}
}
}
}
索引视图
model Project.ViewModels.Currencies
@{
ViewBag.Title = "Index";
}
@using (Html.BeginForm("Index", "Currency", FormMethod.Post))
{
@Html.TextBoxFor(m => m.ConversionRate, new { @size = "5" })
@Html.DropDownListFor(m => m.FromCurrencyId, Model.FromCurrencies as IEnumerable<SelectListItem>)
@Html.DropDownListFor(m => m.ToCurrencyId, Model.ToCurrencies as IEnumerable<SelectListItem>)
<button type="submit" class="btn btn-primary">Convert</button>
}
答案 0 :(得分:1)
这个问题是因为您从下拉列表中传递 null 值。您没有选择任何值。检查如果你将从下拉列表中传递一些值,它将正常工作。要解决此问题,您需要添加相同的 代码
Currencies model = new Currencies();
model.FromCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
model.ToCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
在你的控制器索引发布方法中。因为如果selectListitem为null,则将执行以下代码
IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
if (selectList == null)
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
MvcResources.HtmlHelper_WrongSelectDataType,
name, o.GetType().FullName, "IEnumerable<SelectListItem>"));
}
哪会抛出异常。 (如果你使用
会更好 ViewBag.FromCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
这里给出了更好的描述:
此链接也提供了整个解释,例如此代码如何工作。
答案 1 :(得分:0)
您还必须在帖子控制器中设置Dropdown数据,否则它将无法找到ViewBag值,因此在发布后操作后它会调用Index视图ViewBag.FromCurrencies
和ViewBag.ToCurrencies
将是null
,这显然是我们不想要的。
要修复错误,您必须将后期操作更改为:
[HttpPost]
public ActionResult Index(Currencies cur)
{
if (ModelState.IsValid)
{
if (cur.FromCurrencyId == cur.ToCurrencyId)
{
//do something if same currecnies and return.
ModelState.AddModelError("CurrencyCountry", "Can't make the conversion for the same value");
}
else
{
some code .....
}
}
CurrenciesClient Cur = new CurrenciesClient();
var listCurrency = Cur.findAll().ToList();
Currencies model = new Currencies();
model.FromCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
model.ToCurrencies = new SelectList(listCurrency, "Id", "CurrencyName");
return View(cur);
}
答案 2 :(得分:0)
您不应该从POST操作返回视图,否则会遇到很多问题。这是问题所在:
Index
。您的http帖子的正文中会包含一堆Currencies
项。因此,MVC会使用Index
参数将表单提交到您的Currencies cur
方法。 因此,除了使用AJAX之外,您应该始终返回重定向,而不是从POST返回视图。
在这种情况下,如果一切顺利,您可能希望将用户发送到成功页面或其他页面,因此您应该这样做:
return RedirectToAction("YourActionName", "YourControllerName");
此模式称为PRG模式。这样做是这样的: