【发布时间】:2020-04-11 03:19:50
【问题描述】:
我是 .Net Core(和 Blazor)的新手,我刚刚按照教程配置了一个使用最新版本的 .net core (3.1.xxx) 的项目并检查了 Microsoft Docs。
我的项目中有几个实体,我可以使用 API 保存由简单属性(原始类型)组成的实体。但是当我尝试对具有其他实体作为属性(因此嵌套对象)的实体进行相同操作时,我遇到了一个问题。
我得到的错误根本没有帮助,它抱怨从 Char 到 String 的转换,正如您在下面的堆栈跟踪中看到的那样:
失败:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] 执行请求时发生未处理的异常。 System.InvalidCastException:无法将“System.Char”类型的对象转换为“System.String”类型。 在 System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(对象值) 在 System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(对象值,ValidationContext 验证上下文) 在 System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(对象值,ValidationContext 验证上下文) 在 Microsoft.AspNetCore.Mvc.DataAnnotations.DataAnnotationsModelValidator.Validate(ModelValidationContext 验证上下文) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.ValidateNode() 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitSimpleType() 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata 元数据,字符串键,对象模型) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy 策略) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata 元数据,字符串键,对象模型) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy 策略) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy) 在 Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata 元数据,字符串键,对象模型)
这只发生在嵌套实体中。这是我应该编写自定义模型绑定类的情况吗?
我的代码是这样的:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace src.Data.Entities
{
[Table("Screening")]
public class Screening
{
public Screening()
{
this.Beneficiary = new Beneficiary();
}
public int ScreeningId { get; set; }
public DateTime ScreeningDate { get; set; } = DateTime.Now;
public virtual Beneficiary Beneficiary { get; set; }
public int BeneficiaryId { get; set; }
public virtual SimpleEntity ActionTaken { get; set; }
public int ActionTakenId { get; set; }
public virtual SimpleEntity ReasonForVisit { get; set; }
public int ReasonForVisitId { get; set; }
}
}
控制器类
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using src.Data;
using src.Data.Entities;
using src.Data.DTO;
using src.Helpers;
using System.Linq;
namespace src.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ScreeningController : ControllerBase
{
private readonly ApplicationDbContext context;
public ScreeningController(ApplicationDbContext context)
{
this.context = context;
}
[HttpGet]
public async Task<ActionResult<List<Screening>>> Get([FromQuery] PaginationDTO pagination)
{
var queryable = context.Screenings.AsQueryable().OrderBy(x => x.ScreeningDate);
await HttpContext.InsertPaginationParameterInResponse(queryable, pagination.RecordsPerPage);
return await queryable.Paginate(pagination).ToListAsync();
}
[HttpGet("{id}", Name = "GetScreening")]
public async Task<ActionResult<Screening>> Get(int id)
{
return await context.Screenings.FirstOrDefaultAsync(x => x.ScreeningId == id);
}
[HttpPost]
public async Task<ActionResult> Post(Screening screening)
{
context.Add(screening);
await context.SaveChangesAsync();
return new CreatedAtRouteResult("GetScreening", new { id = screening.ScreeningId }, screening);
}
[HttpPut]
public async Task<ActionResult> Put(Screening screening)
{
context.Entry(screening).State = EntityState.Modified;
await context.SaveChangesAsync();
return NoContent();
}
[HttpDelete("{id}")]
public async Task<ActionResult> Delete(int id)
{
var screening = new Screening { ScreeningId = id };
context.Remove(screening);
await context.SaveChangesAsync();
return NoContent();
}
}
}
观看次数
筛选表单组件
@inject HttpClient http
<RadzenCard>
<EditForm Model="@Screening" OnValidSubmit="@OnValidSubmit">
<DataAnnotationsValidator/>
<div class="from-field">
<label>Screening date:</label>
<div>
<RadzenDatePicker @bind-Value="Screening.ScreeningDate"/>
</div>
</div>
<div class="from-field">
<label>Client name:</label>
<div>
<RadzenTextBox Style="margin-bottom: 20px" @bind-Value="@Screening.Beneficiary.FirstName"/>
</div>
</div>
<div class="from-field">
<label>Client surname:</label>
<div>
<RadzenTextBox Style="margin-bottom: 20px" @bind-Value="@Screening.Beneficiary.Surname"/>
</div>
</div>
<div class="from-field">
<label>Reason for visit:</label>
<div>
<RadzenDropDown
AllowClear="true"
TValue="int"
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
AllowFiltering="true"
Data="@ReasonForVistList"
TextProperty="Description"
ValueProperty="SimpleEntityID"
Style="margin-bottom: 20px" />
</div>
</div>
<div class="from-field">
<label>Action taken:</label>
<div>
<RadzenDropDown
AllowClear="true"
TValue="int"
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
AllowFiltering="true"
Data="@ActionTakenList"
TextProperty="Description"
ValueProperty="SimpleEntityID"
Style="margin-bottom: 20px" />
</div>
</div>
<hr/>
<button type="submit" class="btn btn-success">
Create
</button>
</EditForm>
</RadzenCard>
@code {
[Parameter] public Screening Screening{get;set;}
[Parameter] public string ButtonText{get;set;} = "Save";
[Parameter] public EventCallback OnValidSubmit{get;set;}
IEnumerable<SimpleEntity> ReasonForVistList;
IEnumerable<SimpleEntity> ActionTakenList;
protected override async Task OnInitializedAsync()
{
var reasonForVisitType = "reason-for-visit";
var actionTaken = "screening-action-taken";
ReasonForVistList = await http.GetJsonAsync<SimpleEntity[]>($"api/simpleentity/type/?type={reasonForVisitType}");
ActionTakenList = await http.GetJsonAsync<SimpleEntity[]>($"api/simpleentity/type/?type={actionTaken}");
}
}
创建视图
@page "/screening/create"
@inject HttpClient http
@inject NavigationManager uriHelper
<h3>New Screening Process</h3>
<ScreeningForm ButtonText="Create" Screening="@screening" OnValidSubmit="@Save"/>
@code{
Screening screening = new Screening();
async Task Save()
{
await http.PostJsonAsync("api/screening", screening);
uriHelper.NavigateTo("screening");
}
}
【问题讨论】:
-
从您提供的代码中不清楚,但某处
char正在转换为string。很可能您在应该使用双引号的地方使用了单引号。一般来说,在代码中寻找明确处理char类型或使用单引号表示“字符串”的地方。 -
@ChrisPratt 感谢您的及时评论。但我没有在我的应用程序的任何地方处理
char,这就是为什么我对这个错误如此惊讶。我添加了视图代码,如果这有助于理解问题,请告诉我 -
您的异常说,您正在尝试将字符串分配给 char。所以,我会检查你的输入数据到数据库中期待 CHAR 的列
-
感谢大家帮助我。不幸的是,由于我的声誉,我可以发布答案,但我解决了我的问题。不确定我是否可以在 cmets 上分享这里
标签: c# asp.net-mvc asp.net-core blazor