我正在使用ajax发布web api的帖子。但是ApiController并没有获得价值。我的ViewModel为null。在Startup.cs中,我已经使用Automapper管理viewmodel与实体的映射,应用程序的其他部分正在以相同的方式完成。可能是非常愚蠢的事情,但目前我无法找到错误的位置。
更新: 我试图用邮递员来模拟发布web api,即使在那里我也无法发帖。所以我从中可以理解的是下一个问题:它只能在接下来的两件事中成为控制器或视图模型。如果我错了,请纠正我。
[Produces("application/json")]
[Route("/api/v1/items")]
public class SparePartApiController : Controller
{
private IRepository<SparePart> _repoSparePart;
public SparePartApiController(IRepository<SparePart> repoSparePart)
{
_repoSparePart = repoSparePart;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody]SparePartViewModel viewModel)
{
if (ModelState.IsValid)
{
var newItem = Mapper.Map<SparePart>(viewModel);
newItem.CreateDate = DateTime.Now;
var exist = _repoSparePart.SearchByName(w => string.Equals(w.InternalCode, viewModel.InternalCode, StringComparison.CurrentCultureIgnoreCase));
if (exist != null)
{
TempData["items"] = "Spare Part already exist.";
}
else
{
_repoSparePart.Insert(newItem);
if (await _repoSparePart.SaveChangesAsync())
{
TempData["items"] = "Spare Part successfully created";
return Created($"items/{newItem.InternalCode}", Mapper.Map<SparePart>(viewModel));
}
}
}
return BadRequest("Failed to save.");
}
Index.cshtml
@{
ViewData["Title"] = "Items";
}
<br />
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">Add New Item</button><br /><br />
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
@*<button type="button" class="close" data-dissmiss="modal"><span aria-hidden="true">×</span></button>*@
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title" id="myModalLabel">Add Employee</h4>
</div>
<div class="modal-body">
<form id="item-form">
<div class="form-group">
<label for="Id">Id</label>
<input type="text" class="form-control" id="id" placeholder="Id" disabled="disabled" />
</div>
<div class="form-group">
<label for="InternalCode">Internal Code</label>
<input type="text" class="form-control" id="internalCode" placeholder="Internal Code" />
</div>
<div class="form-group">
<label for="Description">Description</label>
<input type="text" class="form-control" id="description" placeholder="Description" />
</div>
<div class="form-group">
<label for="NameOnFolder">Name On Item</label>
<input type="text" class="form-control" id="nameOnFolder" placeholder="Name On Folder" />
</div>
<div class="form-group">
<label for="Enter">Enter</label>
<input type="number" step="0.01" class="form-control" id="enter" placeholder="Enter" />
</div>
<div class="form-group">
<label for="Exit">Exit</label>
<input type="number" step="0.01" class="form-control" id="exit" placeholder="Exit" />
</div>
<div class="form-group">
<label for="Thickness">Thickness</label>
<input type="number" step="0.01" class="form-control" id="thickness" placeholder="Thickness" />
</div>
<div class="form-group">
<label for="Band">Band</label>
<input type="text" class="form-control" id="band" placeholder="Band" />
</div>
<div class="form-group">
<label for="Color">Color</label>
<input type="text" id="color" class="form-control" placeholder="Color" />
</div>
<div class="form-group">
<label for="Elastic">Elasitc</label>
<input type="checkbox" id="elastic" class="form-control" />
</div>
<div class="form-group">
<label for="MachineType">Machine Type</label>
<select id="machineType" class="form-control">
<option class="form-control" value="0">-- Select --</option>
</select>
</div>
<div class="form-group">
<label for="SpareType">Spare Type</label>
<select id="spareType" class="form-control">
<option class="form-control" value="0">-- Select --</option>
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="btnAdd" onclick="AddItem()">Add</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="rows">
</div>
@section Scripts{
<script src="~/js/spare-part.js"></script>
}
function AddItem() {
var item = {
internalCode: $("#internalCode").val(),
description: $("#description").val(),
nameOnFolder: $("#nameOnFolder").val(),
enter: $("#enter").val(),
exit: $("#exit").val(),
thickness: $("#thickness").val(),
band: $("#band").val(),
color: $("#color").val(),
elastic: $("#elastic").is(":checked"),
machineType: $("#machineType").val(),
spareType: $("#spareType").val()
}
$.ajax({
url: '/api/v1/items',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(item),
dataType: 'json',
success: function (data) {
LoadItems();
window.location.reload();
$('#myModal').modal('hide');
}, error: function (errorMessage) {
console.log(errorMessage.responseText);
console.log(item);
}
});
}
SpartPartViewModel.cs
public class SparePartViewModel
{
public Int64? Id { get; set; }
public DateTime CreateDate { get; set; }
[Required]
[StringLength(100)]
public string InternalCode { get; set; }
[StringLength(4096)]
public string Description { get; set; }
[StringLength(255)]
public string NameOnFolder { get; set; }
public decimal? Enter { get; set; }
public decimal? Exit { get; set; }
public decimal? Thickness { get; set; }
public string Band { get; set; }
public string Color { get; set; }
public bool Elastic { get; set; }
[Required]
public virtual MachineType MachineType { get; set; }
[Required]
public virtual SpareType SpareType { get; set; }
}
答案 0 :(得分:0)
不确定这是否是问题。我对api控制器执行类似的ajax调用,以检查子域名是否可用。我在你的代码和我的代码之间看到的唯一区别是:
var data = {
Guid: '@Model.Guid',
UrlName: $(this).val()
};
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
type: "POST",
url: '/api/ValidateUrlName',
data: JSON.stringify(data),
dataType: "json",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"RequestVerificationToken": token
},
...
[HttpPost]
[ValidateAntiForgeryToken]
[Route("ValidateUrlName")]
public JsonResult ValidateUrlName([FromBody]ValidateEventUrlName data)
{
您不应该需要“var token”和RequestVerificationToken标头,这是在控制器上使用[ValidateAntiForgeryToken]时的