作为一个学习项目,我有一个 MVC & Typescript 项目和一个 Web 2.0 & 实体框架项目,MVC 项目试图与 Web 2.0 项目对话,但我有一个奇怪的错误。
这是我的 Web API 2.0 播放器控制器:
public class PlayerController : ApiController
{
// GET api/<controller>/5
public Player Get(int? id)
{
if (id == null || id == -1)
{
var player = new Player();
LeaderBoardContext.Current.Players.Add(player);
LeaderBoardContext.Current.SaveChanges();
return player;
}
return LeaderBoardContext.Current.Players.FirstOrDefault(x => x.PlayerId == id);
}
// PUT: api/Scores/5
[ResponseType(typeof(void))]
public IHttpActionResult PostPlayer(LearningCancerAPICalls.Models.Player player)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var model = LeaderBoardContext.Current.Players.FirstOrDefault(x => x.PlayerId == player.PlayerId);
LeaderBoardContext.Current.Entry<Player>(player).State = EntityState.Modified;
try
{
LeaderBoardContext.Current.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
}
return StatusCode(HttpStatusCode.NoContent);
}
}
到目前为止,它经历了几次迭代,有一次它在文件顶部初始化了自己的数据库上下文,但在发布期间它神秘地为空。所以现在我正在使用我们在其他项目中使用的样式,如下所示:
public static LeaderBoardContext Current
{
get
{
try
{
//added because 'HttpContext.Current.Items["_EntityContext"] ' was mysteriously comming back null....
if (HttpContext.Current.Items["_EntityContext"] == null)
{
HttpContext.Current.Items["_EntityContext"] = new LeaderBoardContext();
}
var obj = HttpContext.Current?.Items["_EntityContext"] as LeaderBoardContext;
return obj;
}
catch (Exception) //should only get here if using background task
{
return null;
}
}
}
所以第一个奇怪的是在帖子中上下文坚持为空,但通过上面复杂的方法强制它不为空并没有太大改善这种情况。请注意,我现在放入的第一个 EF 调用与 GET 基本相同:
var model = LeaderBoardContext.Current.Players.FirstOrDefault(x => x.PlayerId == player.PlayerId);
我已经以两种样式调用了 GET(使用 -1,使用有效 ID)并且它工作正常,但是 POST 到目前为止导致了这个错误:
我通常会将其与初始化错误的 EF 项目相关联,但 GET 有效!它确实做了它应该做的事情。我什至尝试过发布到具有不同型号的 EF 支架控制器并遇到同样的问题!
两者之间的主要区别(除了 GET/POST)是我调用它们的方式,这就是我使用 GET 的方式:
var playerId = -1;
var activeUser:Player;
function initPlayerOnGameStart() {
if (host === undefined) {
host = 'http://localhost:52316';
}
if (playerId === undefined) {
playerId = -1;
}
var uri = host + '/api/Player/' + playerId;
jQuery.getJSON(uri).done(data => {
activeUser = data;
playerId = activeUser.PlayerId;
});
}
在纯 Typescript Json 调用中。为了做 POST 我正在尝试使用 AJAX.Helper:
@model LearningCancerAPICalls.Models.Player
<a id="contact-us">Share Score!</a>
<div id="contact-form" class="hidden" title="Online Request Form">
@using (Ajax.BeginForm("", "", null, new AjaxOptions
{
HttpMethod = "POST", Url = "/api/Player",
OnSuccess ="OnSuccess",
OnFailure ="OnFailure"
}, new { id = "formId", name = "frmStandingAdd" }))
{
@Html.LabelFor(m => m.PlayerName);
@Html.TextBoxFor(m => m.PlayerName);
@Html.LabelFor(m => m.Email);
@Html.TextBoxFor(m => m.Email);
@Html.HiddenFor(m => m.PlayerId);
@Html.Hidden( "PlayerId");
<input type="submit" name="submit" value="Ok" />
}
</div>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script>
function OnSuccess() {
alert('Success');
}
function OnFailure(ajaxContext) {
alert('Failure');
}
</script>
我从打字稿中设置 PlayerID 的地方。这成功调用了帖子,但在第一次使用 EF 时崩溃。另一个奇特的事情是,如果我在帖子上进行调试。该模型似乎不正确,因为当我将鼠标悬停在它上面时,它显示为 Player 模型,没有铸造错误,但它不允许我扩展它的属性。如果我使用变量或即时窗口来检查变量,那么它们都很好。但我认为这值得一提。
稍后我将尝试一个纯 ajax 调用,看看它是否能解决它,但我不明白为什么 Ajax.helper 在这里会出错,它在技术上完成了它的工作,并且错误与我的模型无关可以看到。
更新 1 所以我尝试了纯 ajax 调用:
html:
Name: <input type="text" name="fname" id="userName"><br />
<button onclick="postJustPlayer()"> Ok </button>
打字稿
function postJustPlayer() {
let level = jQuery("#chooseGridLevel").val();
let name = jQuery("#userName").val();
let uri = host + '/api/Player';
let player: Player = <Player>{};
player.Email = "Testing";
player.PlayerName = name;
jQuery.post(uri, player);
}
这工作!??我不知道为什么纯 jQuery 可以工作,当然就 EF 而言,它确实做同样的事情?为什么 AJAX.helper 帖子会有所不同...