我有一个ASP .Net Core 1.1 MVC网络应用程序。该应用程序与Web API后端进行通信,以便将数据读/写到数据存储中。
在网络应用程序中,我有一个编辑页面,您可以在其中编辑特定对象的记录。记录中的一个字段是下拉列表(即HTML标记)。我的问题是我不知道如何从下拉列表(在视图中)中将所选选项返回到控制器。
为了向您提供简要背景,房地产经纪人将使用此网络应用程序来管理其属性。简单来说,目前该物业有一个基本结构 - 一个ID,一个地址和一个“物业类型”(房屋,公寓,办公室等)
所以我有这两个模型:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace InspectionsData.Models
{
public partial class PropertyType
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string PropertyTypeName { get; set; } // e.g. house, flat, office, etc.
}
}
和
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace InspectionsData.Models
{
[Table("property")]
public class Property
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int? Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string Country { get; set; }
public int? PropertyTypeId { get; set; }
[ForeignKey("PropertyTypeId")]
public PropertyType PropertyType { get; set; }
}
}
然后我创建了一个ViewModel,以便我可以将以上两个模型都提供给视图:
using InspectionsData.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace InspectionsTestClient.ViewModels
{
public class PropertyIndexViewModel
{
public Property Property { get; set; }
public SelectList PropertyTypes { get; set; }
}
}
然后我有一个控制器来填充视图:
// GET: Property/Edit/5
public async Task<ActionResult> Edit(int id)
{
string apiUrl = "http://localhost:50082/api/";
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//Read property from Web API
string url = apiUrl + "Properties/" + id.ToString();
HttpResponseMessage responseMessage = await client.GetAsync(url);
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
var prop = Newtonsoft.Json.JsonConvert.DeserializeObject<Property>(responseData);
if (prop == null)
{
return NotFound();
}
List<PropertyType> propertyTypes = null;
url = apiUrl + "PropertyTypes";
responseMessage = await client.GetAsync(url);
if (responseMessage.IsSuccessStatusCode)
{
responseData = responseMessage.Content.ReadAsStringAsync().Result;
propertyTypes = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PropertyType>>(responseData);
}
PropertyIndexViewModel vm = new PropertyIndexViewModel()
{
Property = prop,
PropertyTypes = new SelectList(propertyTypes, "Id", "PropertyTypeName")
};
return View(vm);
}
return View("Error");
}
我知道在对API进行两次调用时效率很低 - 一次获取属性,一次获取属性类型列表 - 稍后我会对此进行改进,但现在就是这样...... 和观点:
@model InspectionsTestClient.ViewModels.PropertyIndexViewModel
@{
ViewData["Title"] = "Edit";
}
@{
Layout = "_Layout";
}
<h2>Edit</h2>
@Html.ValidationSummary();
<form asp-action="Edit">
<div class="form-horizontal">
<h4>Property</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Property.Id" />
<div class="form-group">
<label asp-for="Property.Street" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Property.Street" class="form-control" />
<span asp-validation-for="Property.Street" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Property.City" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Property.City" class="form-control" />
<span asp-validation-for="Property.City" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Property.Region" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Property.Region" class="form-control" />
<span asp-validation-for="Property.Region" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Property.Country" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Property.Country" class="form-control" />
<span asp-validation-for="Property.Country" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Property.PropertyType" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="Property.PropertyType" asp-items="@Model.PropertyTypes"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
当用户单击表单上的SAVE按钮时,它会回发到另一个控制器操作:
// POST: Property/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(int id, Property prop)
{
try
{
if (ModelState.IsValid)
{
string apiUrl = "http://localhost:50082/api/";
string url = apiUrl + "properties/" + id.ToString();
string jsonInString = JsonConvert.SerializeObject(prop);
HttpContent content = new StringContent(jsonInString, Encoding.UTF8, "application/json");
HttpResponseMessage responseMessage = await client.PutAsync(url, content);
if (responseMessage.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
}
return View();
}
catch
{
return View();
}
}
因此,此控制器操作会将更新的属性发布到Web API。问题是,一切都工作100%,直到它到达最终控制器操作 - 如果我检查“prop”参数,它包含所做的所有修改,但它不包含选定的PopertyType - 如何返回选定的PropertyType从视图回到控制器? 感谢...