无法在剃刀页面中保存表单详细信息,如 Pluralsight 基础课程中所示
Unable to save form details in razor page as demonstrated in Pluralsight Fundamentals course
我一直在关注 Scott Allen 的 ASP.NET Pluralsight 核心基础课程,并且一直在使用我自己为项目创建的程序来学习它。到目前为止,我的代码与视频中的代码非常相似,除了我使用自己的 class object 而不是示例中的餐厅 class。
我遇到的问题出现在课程第 4 个模块的模型绑定视频中。当我 运行 程序并在浏览器中编辑会议 Space object 之一时,它会保存 empty/null object 而不是使用表单中的输入.我对包含 Update 方法的 MeetingSpaceData class 进行的单元测试按预期工作,这让我相信我在负责这些编辑的 Edit razor 页面中犯了一个错误。
编辑:在 Update 方法(在 Edit.cshtml.cs 中调用)中接收和使用的 MeetingSpace object 是默认 MeetingSpace。所以问题是输入表单不用于编辑新创建的 object.
以下是一些相关内容。让我知道是否需要更多详细信息。我是一个相当缺乏经验的程序员,并且是使用 ASP.NET 的新手,所以如果有任何不清楚的地方,我们深表歉意。
会议Space资料Class
public class InMemoryMeetingSpaceData : IMeetingSpaceData
{
public List<MeetingSpace> meetingSpaces;
public InMemoryMeetingSpaceData()
{
meetingSpaces = new List<MeetingSpace>()
{
new MeetingSpace { Id = 1, Name = "Meeting Room 1", Location = "The Building", Capacity = 8},
new MeetingSpace { Id = 2, Name = "Meeting Room 2", Location = "The Building", Capacity = 4},
new MeetingSpace { Id = 3, Name = "Meeting Room 3", Location = "The Building", Capacity = 6},
new MeetingSpace { Id = 4, Name = "Meeting Room 4", Location = "The Building", Capacity = 8},
new MeetingSpace { Id = 5, Name = "Meeting Room 1", Location = "Second Building", Capacity = 7}
};
}
public MeetingSpace Add(MeetingSpace newMeetingSpace)
{
if (newMeetingSpace != null)
{
meetingSpaces.Add(newMeetingSpace);
newMeetingSpace.Id = meetingSpaces.Max(m => m.Id) + 1;
}
return newMeetingSpace;
}
public IEnumerable<MeetingSpace> GetAll()
{
return from m in meetingSpaces
orderby m.Name
select m;
}
public MeetingSpace Update(MeetingSpace updatedMeetingSpace)
{
var meetingSpace = meetingSpaces.SingleOrDefault(m => m.Id == updatedMeetingSpace.Id);
if (meetingSpace != null)
{
meetingSpace.Name = updatedMeetingSpace.Name;
meetingSpace.Location = updatedMeetingSpace.Location;
meetingSpace.Capacity = updatedMeetingSpace.Capacity;
}
return meetingSpace;
}
public int Commit()
{
return 0;
}
public MeetingSpace GetById(int id)
{
return meetingSpaces.SingleOrDefault(m => m.Id == id);
}
}
}
Edit.cshtml
@page "{meetingSpaceId:int}"
@model BookingApp.Pages.MeetingSpaces.EditModel
@{
ViewData["Title"] = "Edit";
}
<h2>Editing @Model.MeetingSpace.Name</h2>
<form method="post">
<input type="hidden" asp-for="MeetingSpace.Id" />
<div class="form-group">
<label asp-for="MeetingSpace.Name"></label>
<input asp-for="MeetingSpace.Name" class="form-control" />
<span class="text-danger" asp-validation-for="MeetingSpace.Name"></span>
</div>
<div class="form-group">
<label asp-for="MeetingSpace.Location"></label>
<input asp-for="MeetingSpace.Location" class="form-control" />
<span class="text-danger" asp-validation-for="MeetingSpace.Location"></span>
</div>
<div class="form-group">
<label asp-for="MeetingSpace.Capacity"></label>
<input asp-for="MeetingSpace.Capacity" class="form-control" />
<span class="text-danger" asp-validation-for="MeetingSpace.Capacity"></span>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
Edit.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BookingApp.Core;
using BookingApp.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace BookingApp.Pages.MeetingSpaces
{
public class EditModel : PageModel
{
private readonly IMeetingSpaceData meetingSpaceData;
[BindProperty]
public MeetingSpace MeetingSpace { get; set; }
public EditModel(IMeetingSpaceData meetingSpaceData)
{
this.meetingSpaceData = meetingSpaceData;
}
public IActionResult OnGet(int meetingSpaceId)
{
MeetingSpace = meetingSpaceData.GetById(meetingSpaceId);
if (MeetingSpace == null)
{
return RedirectToPage("./NotFound");
}
return Page();
}
public IActionResult OnPost()
{
MeetingSpace = meetingSpaceData.Update(MeetingSpace);
meetingSpaceData.Commit();
return Page();
}
}
}
MeetingSpace.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookingApp.Core
{
public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
//private static int classCount = 3; //TODO: Change to 0 default when database implemented
public string Name;
public string Location;
public int Capacity;
public override void EditDetails()
{
throw new NotImplementedException();
}
public bool Equals(MeetingSpace other)
{
if (Name == other.Name
&& Location == other.Location
&& Capacity == other.Capacity)
{
return true;
}
else
{
return false;
}
}
public override int GenerateNewId()
{
throw new NotImplementedException();
}
public override void GetAll()
{
throw new NotImplementedException();
}
}
}
BookingEntityBase.cs
MeetingSpace 继承了这个 class
的 id 字段
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookingApp.Core
{
public abstract class BookingEntityBase
{
public int Id { get; set; }
}
}
我测试了您的代码并能够通过修改您的 MeetingSpace class 来解决问题。它包含字段而不是属性,我认为这就是它搞乱数据绑定的原因。
所以改变这个:
public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
public string Name;
public string Location;
public int Capacity;
...
对此:
public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
public string Name { get; set; }
public string Location { get; set; }
public int Capacity { get; set; }
...
并且数据绑定应该可以正常工作。
我一直在关注 Scott Allen 的 ASP.NET Pluralsight 核心基础课程,并且一直在使用我自己为项目创建的程序来学习它。到目前为止,我的代码与视频中的代码非常相似,除了我使用自己的 class object 而不是示例中的餐厅 class。
我遇到的问题出现在课程第 4 个模块的模型绑定视频中。当我 运行 程序并在浏览器中编辑会议 Space object 之一时,它会保存 empty/null object 而不是使用表单中的输入.我对包含 Update 方法的 MeetingSpaceData class 进行的单元测试按预期工作,这让我相信我在负责这些编辑的 Edit razor 页面中犯了一个错误。
编辑:在 Update 方法(在 Edit.cshtml.cs 中调用)中接收和使用的 MeetingSpace object 是默认 MeetingSpace。所以问题是输入表单不用于编辑新创建的 object.
以下是一些相关内容。让我知道是否需要更多详细信息。我是一个相当缺乏经验的程序员,并且是使用 ASP.NET 的新手,所以如果有任何不清楚的地方,我们深表歉意。
会议Space资料Class
public class InMemoryMeetingSpaceData : IMeetingSpaceData
{
public List<MeetingSpace> meetingSpaces;
public InMemoryMeetingSpaceData()
{
meetingSpaces = new List<MeetingSpace>()
{
new MeetingSpace { Id = 1, Name = "Meeting Room 1", Location = "The Building", Capacity = 8},
new MeetingSpace { Id = 2, Name = "Meeting Room 2", Location = "The Building", Capacity = 4},
new MeetingSpace { Id = 3, Name = "Meeting Room 3", Location = "The Building", Capacity = 6},
new MeetingSpace { Id = 4, Name = "Meeting Room 4", Location = "The Building", Capacity = 8},
new MeetingSpace { Id = 5, Name = "Meeting Room 1", Location = "Second Building", Capacity = 7}
};
}
public MeetingSpace Add(MeetingSpace newMeetingSpace)
{
if (newMeetingSpace != null)
{
meetingSpaces.Add(newMeetingSpace);
newMeetingSpace.Id = meetingSpaces.Max(m => m.Id) + 1;
}
return newMeetingSpace;
}
public IEnumerable<MeetingSpace> GetAll()
{
return from m in meetingSpaces
orderby m.Name
select m;
}
public MeetingSpace Update(MeetingSpace updatedMeetingSpace)
{
var meetingSpace = meetingSpaces.SingleOrDefault(m => m.Id == updatedMeetingSpace.Id);
if (meetingSpace != null)
{
meetingSpace.Name = updatedMeetingSpace.Name;
meetingSpace.Location = updatedMeetingSpace.Location;
meetingSpace.Capacity = updatedMeetingSpace.Capacity;
}
return meetingSpace;
}
public int Commit()
{
return 0;
}
public MeetingSpace GetById(int id)
{
return meetingSpaces.SingleOrDefault(m => m.Id == id);
}
}
}
Edit.cshtml
@page "{meetingSpaceId:int}"
@model BookingApp.Pages.MeetingSpaces.EditModel
@{
ViewData["Title"] = "Edit";
}
<h2>Editing @Model.MeetingSpace.Name</h2>
<form method="post">
<input type="hidden" asp-for="MeetingSpace.Id" />
<div class="form-group">
<label asp-for="MeetingSpace.Name"></label>
<input asp-for="MeetingSpace.Name" class="form-control" />
<span class="text-danger" asp-validation-for="MeetingSpace.Name"></span>
</div>
<div class="form-group">
<label asp-for="MeetingSpace.Location"></label>
<input asp-for="MeetingSpace.Location" class="form-control" />
<span class="text-danger" asp-validation-for="MeetingSpace.Location"></span>
</div>
<div class="form-group">
<label asp-for="MeetingSpace.Capacity"></label>
<input asp-for="MeetingSpace.Capacity" class="form-control" />
<span class="text-danger" asp-validation-for="MeetingSpace.Capacity"></span>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
Edit.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BookingApp.Core;
using BookingApp.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace BookingApp.Pages.MeetingSpaces
{
public class EditModel : PageModel
{
private readonly IMeetingSpaceData meetingSpaceData;
[BindProperty]
public MeetingSpace MeetingSpace { get; set; }
public EditModel(IMeetingSpaceData meetingSpaceData)
{
this.meetingSpaceData = meetingSpaceData;
}
public IActionResult OnGet(int meetingSpaceId)
{
MeetingSpace = meetingSpaceData.GetById(meetingSpaceId);
if (MeetingSpace == null)
{
return RedirectToPage("./NotFound");
}
return Page();
}
public IActionResult OnPost()
{
MeetingSpace = meetingSpaceData.Update(MeetingSpace);
meetingSpaceData.Commit();
return Page();
}
}
}
MeetingSpace.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookingApp.Core
{
public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
//private static int classCount = 3; //TODO: Change to 0 default when database implemented
public string Name;
public string Location;
public int Capacity;
public override void EditDetails()
{
throw new NotImplementedException();
}
public bool Equals(MeetingSpace other)
{
if (Name == other.Name
&& Location == other.Location
&& Capacity == other.Capacity)
{
return true;
}
else
{
return false;
}
}
public override int GenerateNewId()
{
throw new NotImplementedException();
}
public override void GetAll()
{
throw new NotImplementedException();
}
}
}
BookingEntityBase.cs MeetingSpace 继承了这个 class
的 id 字段using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BookingApp.Core
{
public abstract class BookingEntityBase
{
public int Id { get; set; }
}
}
我测试了您的代码并能够通过修改您的 MeetingSpace class 来解决问题。它包含字段而不是属性,我认为这就是它搞乱数据绑定的原因。
所以改变这个:
public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
public string Name;
public string Location;
public int Capacity;
...
对此:
public class MeetingSpace : MeetingObjectsBaseClass, IEquatable<MeetingSpace>
{
public string Name { get; set; }
public string Location { get; set; }
public int Capacity { get; set; }
...
并且数据绑定应该可以正常工作。