ConvertEmptyStringToNull 不起作用 .net 核心 Blazor 项目

Posted

技术标签:

【中文标题】ConvertEmptyStringToNull 不起作用 .net 核心 Blazor 项目【英文标题】:ConvertEmptyStringToNull does not work .net core Blazor project 【发布时间】:2021-06-18 16:05:08 【问题描述】:

在我的课堂上我有以下

 public int recordref  get; set; 

    [DisplayFormat(ConvertEmptyStringToNull = false)]
    [Required]
    public string disty  get; set; 

    [DisplayFormat(ConvertEmptyStringToNull = false)]
    [Required]
    public string country  get; set; 

    public int claim_year  get; set; 
    public int claim_month  get; set; 

    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string claim_no  get; set; 

    [DisplayFormat(ConvertEmptyStringToNull = false)]
    [Required]
    public string partner  get; set; 
    //[DisplayFormat(ConvertEmptyStringToNull = false)]
    public string sp_mdf_number  get; set; 
    public decimal original_claim_amount  get; set; 
    //[DisplayFormat(ConvertEmptyStringToNull = false)]
    public string description  get; set; 
    public DateTime date_created  get; set; 
    public string created_by  get; set; 
    public DateTime date_updated  get; set; 
    public string updated_by  get; set; 

我的 RAZOR 页面如下。

@page "/adddebtor/CurrentID"
@page "/adddebtor"
@using BlazorAppDashboard.Data
@inject DebtorService ObjDebtorService
@using Blazored.Typeahead;
@inject NavigationManager NavigationManager
 

<h3>Add Debtor</h3>

<EditForm Model="@objDebtor" OnValidSubmit="@SaveDebtor">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <table>
        <tr>
            <td>Disty</td>
            <td>
                <select @bind="@objDebtor.disty">
                    <option value="-1"></option>
                    @if (objDisties != null)
                    
                        @foreach (var disty in objDisties)
                        
                            <option value="@disty.disty_name">@disty.disty_name</option>
                        
                    

                </select>

            </td>
        </tr>
        <tr>
            <td>Country</td>
            <td>
                <select @bind="@objDebtor.country">
                    <option value="-1"></option>
                    <option value="AU">AU</option>
                    <option value="NZ">NZ</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>Claim Year</td>
            <td><input for="Name" @bind="@objDebtor.claim_year" /></td>
        </tr>
        <tr>
            <td>Claim Month</td>
            <td><input for="Name" @bind="@objDebtor.claim_month" /></td>
        </tr>
        <tr>
            <td>Claim No</td>
            <td><input for="Name" @bind="@objDebtor.claim_no" /></td>
        </tr>
        <tr>
            <td>Partner</td>
            <td>
                <input type="text" list="textsearch" @bind-value="@objDebtor.partner" @bind-value:event="oninput" @onkeyup="autoComplete" />
                <datalist id="textsearch">
                    @if (partners != null)
                    
                        @foreach (var pt in partners)
                        
                            <option value="@pt.partner">@pt.partner</option>
                        
                    
                </datalist>



            </td>
        </tr>
        <tr>
            <td>SP/MDF No</td>
            <td><input for="Name" @bind="@objDebtor.sp_mdf_number" /></td>
        </tr>
        <tr>
            <td>Original Claim Amount</td>
            <td><input for="Name" @bind="@objDebtor.original_claim_amount" /></td>
        </tr>
        <tr>
            <td>Description</td>
            <td><input for="Name" @bind="@objDebtor.description" /></td>
        </tr>
        <tr>
            <td></td>
            <td>
                <input type="submit" value="Save" /> <input type="button" @onclick="@CancelSave" value="Cancel" />
                @ErrorMessage
            </td>
        </tr>

    </table>

</EditForm>


@code 


    [Parameter]
    public string CurrentID  get; set; 
    public string ErrorMessage  get; set; 
    
    BlazorAppDashboard.Data.Debtors objDebtor = new BlazorAppDashboard.Data.Debtors();
    List<BlazorAppDashboard.Data.Disties> objDisties = new List<Disties>();

    string temp_partner = "";

    protected override async Task OnInitializedAsync()
    
        if (CurrentID != null)
        
            objDebtor = await Task.Run(() => ObjDebtorService.GetDebtorByRef(Convert.ToInt32(CurrentID)));
        
        objDisties = await Task.Run(() => ObjDebtorService.getDistyList());
    

    protected void SaveDebtor()
    
        ErrorMessage = "";
        ReturnData rd = new ReturnData();
        rd = ObjDebtorService.Create(objDebtor, Convert.ToInt32(CurrentID));

        if (rd.status == 1)
        
            NavigationManager.NavigateTo("debtorslist");
        
        else
        
            ErrorMessage = "Error.Unable to save." + rd.error;
        
    

    protected void CancelSave()
    
        NavigationManager.NavigateTo("debtorslist");
    

    //autofill partner code
    private List<Partner> partners;

    protected override void OnInitialized()
    
        DebtorService partnerdataservice = new DebtorService();
    

    private async Task<List<Partner>> autoComplete()
    
        DebtorService partnerdataservice = new DebtorService();
        partners = await Task.FromResult(partnerdataservice.getPartners(objDebtor.partner));
        return partners;
    
    //end autofill code


当我提交表单时,它不会将 null 值转换为空字符串并给我 SQL 错误。

我不希望在将参数传递给 SQL 时一一检查每个字段。我的参数如下。

        cmd.Parameters.AddWithValue("@disty", debtors.disty);
        cmd.Parameters.AddWithValue("@country", debtors.country);
        cmd.Parameters.AddWithValue("@claim_year", debtors.claim_year);
        cmd.Parameters.AddWithValue("@claim_month", debtors.claim_month);
        cmd.Parameters.AddWithValue("@claim_no", debtors.claim_no);
        cmd.Parameters.AddWithValue("@partner", debtors.partner);
        cmd.Parameters.AddWithValue("@status", "Pending");
        cmd.Parameters.AddWithValue("@sp_mdf_number", debtors.sp_mdf_number);
        cmd.Parameters.AddWithValue("@description", debtors.description);
        cmd.Parameters.AddWithValue("@original_claim_amount", debtors.original_claim_amount);
        cmd.Parameters.AddWithValue("@created_by", "User Name");

为什么我仍然收到以下错误

错误。无法保存。参数化查询“(@recordref int,@disty nvarchar(16),@country nvarchar(2),@claim_”需要参数“@claim_no”,但未提供该参数。

例如,在 blazor 视图中没有输入 @claim_no 字段(在框中没有输入值),它应该转换为空字符串?

【问题讨论】:

答案就在名称中 - ConvertEmptyStringToNull 将空字符串转换为 null,但它不会将 null 转换为空字符串:用户可以为字段值输入一个空字符串。使用 ConvertEmptyStringToNull 属性指定在数据库中更新数据字段时是否将空字符串值自动转换为 null。 - docs 当我说 ConvertEmptyStringToNull = false 时,如果用户在没有输入值的情况下将输入字段保持为空,那么应该在对象中传递一个空值并返回到数据库,然后参数值应该是空白(非空)? 该属性的目的是“如果你得到一个空字符串,将其转换为null”。您正在寻找相反的行为 - “如果值为 null,则将其转换为空字符串”。 所以ConvertEmptyStringToNull = false 的意思是“不要将空字符串转换为空字符串”,但它确实 not 表示“.. 但确实将空字符串转换为空字符串”。而且也不应该。那将是非常不直观的。你需要找到另一种方法来做你需要做的事情。也许查找属性的源代码,您可能会在那里找到一些指针。 【参考方案1】:

我不认为只做一个空检查有那么不方便。只多了 5 个字符,我认为调试会比在其他地方填充一些自动行为更容易:

方法一:空合并

如果您的 SQL 表的列不可为空,并且您确实想插入一个空字符串:

cmd.Parameters.AddWithValue("@claim_no", debtors.claim_no ?? ""); // null coalesce

方法二:向 SQL 提交 Null 值

如果您的列可以为空,但您不知道如何传递空值,请尝试类似的方法(您可能需要对其进行调整,我正在工作,无法测试 rn):

cmd.Parameters.AddWithValue("@claim_no", debtors.claim_no ?? DBNull.Value);

另外,我非常(非常!)强烈推荐使用 Dapper,这样您就可以在 new ID = debtors.ID, claim= . . . 中列出您想要的所有参数等等。我通常避免使用 NuGet 包,但如果您正在做任何数据库工作,我认为这是非常重要的。我在当前站点中使用了几十个查询,而 Dapper 可能为我节省了宝贵的时间。

【讨论】:

以上是关于ConvertEmptyStringToNull 不起作用 .net 核心 Blazor 项目的主要内容,如果未能解决你的问题,请参考以下文章