You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor服务端复用数据访问接口实现文件导入数据库的问题

Fixing Null Reference for IPermitData in TextFileParser

Hey there! Let's sort out that null reference exception you're hitting with IPermitData in your TextFileParser class. The core issue is that you're declaring IPermitData _db; but never assigning a valid instance to it—luckily, since you're already using dependency injection (DI) in your Blazor Server app, we can reuse that system to get the instance we need.

Step 1: Update TextFileParser to Use Constructor Injection

Instead of declaring _db inside the method, we'll inject it directly through the class constructor. This lets the DI container automatically pass in the registered IPermitData instance when creating a TextFileParser. We'll also fix the async handling since InsertPermit is an asynchronous method.

Here's the revised TextFileParser code:

public class TextFileParser
{
    private readonly IPermitData _db;

    // Inject IPermitData via constructor
    public TextFileParser(IPermitData db)
    {
        _db = db;
    }

    // Change to async Task instead of void for proper async handling
    public async Task InsertTextFileData(string filePath)
    {
        string errMessage = string.Empty;
        FileInfo file = new FileInfo(filePath);
        
        if (!File.Exists(file.FullName))
        {
            errMessage = "File not found!";
            // Consider logging this error instead of just storing it
            return;
        }
        if (file.Length == 0) // Fixed your condition here (>=0 will always be true)
        {
            errMessage = "File has no data!";
            return;
        }

        string delimiter = "\t";
        using StreamReader fileReader = new StreamReader(filePath);
        int header = 1;

        while (!fileReader.EndOfStream)
        {
            string vText = fileReader.ReadLine();
            if (string.IsNullOrEmpty(vText)) continue; // Skip empty lines

            if (header == 1)
            {
                header++;
                // Optional: Validate header columns here if needed
                continue;
            }

            string[] vString = vText.Split(delimiter, StringSplitOptions.None);
            // Create a new PermitModel for each record to avoid reference issues
            PermitModel permitRecord = new PermitModel();
            
            // Map your columns (same as before)
            permitRecord.PD_ParcelID = vString[0];
            permitRecord.PD_Situs1 = vString[1];
            permitRecord.PD_Owner = vString[2];
            permitRecord.PD_Addr1 = vString[3];
            permitRecord.PD_Addr2 = vString[4];
            permitRecord.ADDR_3 = vString[5];
            permitRecord.PD_City = vString[6];
            permitRecord.PD_State = vString[7];
            permitRecord.PD_Zip = vString[8];
            permitRecord.Type_Construction = vString[9];
            permitRecord.Estimated_Cost = vString[10];
            permitRecord.Permit_Issue_Date = vString[11];
            permitRecord.Permit_Type = vString[12];
            permitRecord.Property_Type = vString[13];
            permitRecord.Permit_NO = vString[14];
            permitRecord.Completion_Date = vString[15];
            permitRecord.Percent_Complete = vString[16];
            permitRecord.Modified_Date = vString[17];
            permitRecord.Note = vString[18];
            permitRecord.Note_Date = vString[19];
            permitRecord.Submission_Date = vString[20];
            permitRecord.Submitter = vString[21];
            permitRecord.Submitter_Phone = vString[22];
            permitRecord.Submitter_Email = vString[23];
            permitRecord.Land_AV = vString[24];
            permitRecord.Impr_AV = vString[25];
            permitRecord.Sec_Location = vString[26];

            try
            {
                await _db.InsertPermit(permitRecord); // Use await for async method
            }
            catch (Exception ex)
            {
                // Log the exception instead of just continuing—helps with debugging
                // Example: Logger.LogError(ex, "Failed to insert permit record {ParcelId}", permitRecord.PD_ParcelID);
                continue;
            }
        }
    }
}

Key fixes here:

  • Constructor injection for IPermitData ensures _db is always a valid instance
  • Changed InsertTextFileData to async Task to properly handle the asynchronous InsertPermit method
  • Fixed the file length check (original >=0 would never trigger the "no data" message)
  • Created a new PermitModel per record to avoid accidental overwriting of data
  • Added a check for empty lines to prevent index errors

Step 2: Register TextFileParser with the DI Container

Now that TextFileParser has a dependency on IPermitData, you need to register it in your Startup.cs (or Program.cs if using .NET 6+) so the DI container can resolve its dependencies.

Add this line to your ConfigureServices method:

// Use the same lifetime as your IPermitData registration (likely Scoped)
services.AddScoped<TextFileParser>();

Step 3: Inject and Use TextFileParser in Your Razor Page

Instead of injecting IPermitData directly if you're using the parser, inject TextFileParser and call its method:

@inject TextFileParser textFileParser

<!-- Your UI here, e.g., a file input or button to trigger processing -->
<button @onclick="ProcessSampleFile">Process File</button>

@code {
    private async Task ProcessSampleFile()
    {
        string filePath = "path/to/your/file.txt"; // Replace with actual path
        await textFileParser.InsertTextFileData(filePath);
        // Add success feedback here if needed
    }
}

Extra Notes

  • Async Best Practices: Avoid using void for async methods (except event handlers) because it can lead to unobserved exceptions. Using async Task ensures exceptions can be caught properly.
  • Error Logging: Add a logger (inject ILogger<TextFileParser> via constructor) to log failed inserts—this will save you a lot of time debugging issues with bad data.
  • File Path Handling: In Blazor Server, be careful with file paths—ensure the app has permission to read the file, and consider using a file upload component to let users select files instead of hardcoding paths.

内容的提问来源于stack exchange,提问作者Jason Garner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:32:31