View 获取从视图选择回控制器的选定选项
我有一个ASP.NETCore1.1MVCWeb应用程序。该应用程序与web API后端对话,以向数据存储读取/写入数据 在web应用程序中,我有一个编辑页面,您可以在其中编辑特定对象的记录。记录中的一个字段是dropdownlist,即HTML标记。我的问题是,我不知道如何从视图中的dropdownlist将所选选项返回控制器 为了向您简要介绍背景,房地产代理将使用此web应用程序管理其物业。简单地说,目前房产有一个基本结构——身份证、地址和房产类型房屋、公寓、办公室等 所以我有两个模型:View 获取从视图选择回控制器的选定选项,view,controller,asp.net-core-mvc,viewmodel,View,Controller,Asp.net Core Mvc,Viewmodel,我有一个ASP.NETCore1.1MVCWeb应用程序。该应用程序与web API后端对话,以向数据存储读取/写入数据 在web应用程序中,我有一个编辑页面,您可以在其中编辑特定对象的记录。记录中的一个字段是dropdownlist,即HTML标记。我的问题是,我不知道如何从视图中的dropdownlist将所选选项返回控制器 为了向您简要介绍背景,房地产代理将使用此web应用程序管理其物业。简单地说,目前房产有一个基本结构——身份证、地址和房产类型房屋、公寓、办公室等 所以我有两个模型: u
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.
}
}
及
然后,我创建了一个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");
}
@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");}
}
然后我有一个填充视图的控制器:
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");
}
@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");}
}
我知道对API进行两次调用是低效的——一次是获取属性,另一次是获取属性类型列表——我稍后会对此进行改进,但现在情况就是这样。。。
以及以下观点:
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");
}
@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");}
}
当用户单击表单上的“保存”按钮时,它将发回另一个控制器操作:
// 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从视图返回控制器?
谢谢
谢谢你,mvermef