在Razor页面的OnGetAsync中将值分配给另一个模型

时间:2018-08-11 17:43:15

标签: c# asp.net-core asp.net-core-2.1 razor-pages

我正在尝试将ModelOnGetAsync处的值从另一个Razor Page分配给Model进行一些数据验证,然后将它们分配回OnPostAsync上的实际NullReferenceException用于保存数据。

在此行Input.TestName = TestData.TestName;上出现public class TestData { [Key] public int TestID { get; set; } public string TestName { get; set; } } 错误

    private readonly Test.Models.TestContext _context;
    public EditModel(Test.Models.TestContext context)
    {
        _context = context;
    }
    [BindProperty]
    public TestData TestData { get; set; }

    [BindProperty]
    public InputModel Input { get; set; }

    public class InputModel
    {
        [Required, MaxLength(50), MinLength(3)]
        public string TestName { get; set; }
    }

    public async Task<IActionResult> OnGetAsync(int? id)
    {
        TestData = await _context.TestData.FirstOrDefaultAsync(m => m.TestID == id);
        Input.TestName = TestData.TestName; //Error Occurs here. TestData.TestName has value while debug.
        return Page();
    }

    public async Task<IActionResult> OnPostAsync()
    {
        TestData.TestName = Input.TestName;
        _context.Attach(TestData).State = EntityState.Modified;
        await _context.SaveChangesAsync();
        return RedirectToPage("./Index");
    }

页面模型

TestName

我在InputModel class之外尝试了class,但效果很好,但是我有很多类似的属性可以使用。所以我想将它们放在一个import React, { PropTypes } from 'react'; import { Link, browserHistory } from 'react-router'; import * as DataConnectionAction from '../../actions/dataconnectionAction.jsx'; import DataConnectionStore from '../../store/dataconnectionstore.jsx'; class DataSource extends React.Component { constructor(props) { super(props); this.state = { datasourcelist: [], }; this._dataconnectionStoreChange = this._dataconnectionStoreChange.bind(this); } componentWillMount() { DataConnectionStore.on('change', this._dataconnectionStoreChange); } componentWillUnmount() { DataConnectionStore.removeListener('change', this._dataconnectionStoreChange); } componentDidMount() { DataConnectionAction._getDataSourcesList(); } _dataconnectionStoreChange(type) { if (type == 'DataSourcesList') { let datasourcelist = DataConnectionStore._getDataSourceList() || {}; this.setState({ datasourcelist: datasourcelist.dataconnections }); } } DataSourceView(el) { let data = { id: el.dataConnectionName } } _handleSearchChange(e) { let value = e.target.value; let lowercasedValue = value.toLowerCase(); let datasourcedata = this.state.datasourcelist; let datasourcelist = datasourcedata && datasourcedata.filter(el => el.dataConnectionName.toLowerCase().includes(lowercasedValue)); this.setState({ datasourcelist }); } DataSourcesCardUI() { let datasourcedata = this.state.datasourcelist; return ( datasourcedata && datasourcedata.map((el) => <div key={el.key}> <div className="col-md-3 topadjust"> <div className="panel panel-default datasource_panel "> <div className="panel-heading"> <h5 className="panel_title"><i className="fa fa-database"></i> &nbsp; {el.dataConnectionName}</h5> </div> <Link className="panel-body" onClick={this.DataSourceView.bind(this, el)}> <div className="datasource_txt text-center"> <h6>{el.databaseHost}</h6> <h6>{el.dataConnectionType} </h6> <p>{el.createdDate}</p> </div> </Link> </div> </div> </div> ) ); } render() { return ( <div> <section className="content_block"> <div className="container-fluid"> <div className="row dashboard_list"> {this.DataSourcesCardUI()} </div> </div> </section> </div> ); } } export default DataSource;

请在这里建议我所缺少的内容。

1 个答案:

答案 0 :(得分:2)

在问题中已确认TestData.TestName在调试器中具有值时,应将注意力转移到Input.TestName上。更具体地说,这很可能意味着Input属性本身就是null,这将导致您的NullReferenceException

这也是有道理的。调用OnPostAsync时,ASP.NET Core尝试使用请求中的数据绑定到您的Input属性,这将导致它为您创建InputModel的实例。可以通过使用[BindProperty]属性本身上的Input属性来启用此功能。

但是,当调用OnGetAsync时,不会发生相同的过程。默认情况下,[BindProperty]仅触发非GET请求来执行此绑定,这意味着Input调用中的OnGetAsync将是null(这是默认值,仅供参考)类型的属性)。

要解决此问题,请在尝试设置其OnGetAsync值之前,先更新您的Input实现以创建自己的TestName实例。这是实现该目标的一种方法:

public async Task<IActionResult> OnGetAsync(int? id)
{
    TestData = await _context.TestData.FirstOrDefaultAsync(m => m.TestID == id);
    Input = new InputModel { TestName = TestData.TestName };
    return Page();
}

还值得记住的是,如果ID不匹配,则您对FirstOrDefaultAsync的呼叫会将TestData设置为null,这将为您提供不同的NullReferenceException