得到错误的POST实体框架 - 值不能为空。参数名:源 [英] Getting error on POST with Entity Framework - Value cannot be null. Parameter name: source

查看:323
本文介绍了得到错误的POST实体框架 - 值不能为空。参数名:源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑 - 的要求,这是观点...

- 启动修改

  @model salesWebTest.viewModel.vwbooking@using(Html.BeginForm()){
@ Html.AntiForgeryToken()
@ Html.ValidationSummary(真)@ Html.HiddenFor(型号=> model.bookings.bookingid)
@ Html.EditorFor(型号=> model.bookings.name)@foreach(在Model.traces VAR项)
{
    @ Html.EditorFor(M = GT; item.contact_Name)
}
}

- 最终修改

- 启动原题
我有一个包含两个班一个ViewModel ...

 公共类vwbooking
{
    公众预订预订{搞定;组; }
    公共IEnumerable的<跟踪和GT; {痕迹得到;组; }
}

预订和跟踪是实体的EDMX。

我想通过一个调用来更新这两个类中的数据进行保存。

这是我已经试过...

 公众的ActionResult编辑(vwbooking vwbooking)
{
    如果(ModelState.IsValid)
    {
        db.bookings.Attach(vwbooking.bookings);
        db.Entry(vwbooking.bookings).STATE = EntityState.Modified;
        vwbooking.traces.ToList()的ForEach(//错误发生时HERE
                  T =>
                  {
                      db.traces.Attach(T);
                      db.Entry(T)= .STATE EntityState.Modified;
                  });
        db.SaveChanges();
    }
}

如果我删除的痕迹部分,预约的部分将正确更新。

这是GET方法...

 公众的ActionResult编辑(INT ID = 0)
{
    预订预订= db.bookings.Find(ID);
    VAR视图模型=新vwbooking();
    viewModel.bookings =预订;
    viewModel.traces =(从升的db.traces那里l.bookingid == booking.bookingid选择L);
    返回视图(视图模型);
}

这是我的数据库上下文类

 公共类salesContext:的DbContext
{
    公共salesContext():基地()
    {
        Configuration.LazyLoadingEnabled = TRUE;
    }    公共salesContext(字符串连接):基地(连接)
    {
        Configuration.LazyLoadingEnabled = TRUE;
    }    公共DbSet<预订>预订{搞定;组; }
    公共DbSet<跟踪和GT; {痕迹得到;组; }    保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
    {
        base.OnModelCreating(模型构建器);
        modelBuilder.Entity<预订>()HasKey。(E => e.bookingid);
        modelBuilder.Entity<跟踪和GT;()HasKey。(E => e.traceid);
    }
}


解决方案

这个问题似乎是编辑器的安装方式。我认为,这是导致该模型没有正确地绑定在提交

  @ Html.EditorFor(M = GT; item.contact_Name)

如果您要检查名称的属性<输入> 通过这个辅助生成的元素,将很可能看到它显示

 <输入名称=item.contact_Name/>

对于每一个这些。它甚至可能只是说 NAME =CONTACT_NAME

这是框架的一个严重的缺陷和解决办法为它通常是做一个整体的自定义助手或者使用前端解决方案来解决这个名字。

该名称必须匹配的究竟的到模型。它应该是你的价值观是

 <输入名称=痕迹[0] .contact_Name/>
<输入名称=痕迹[1] .contact_Name/>
等等..

和所以我建议搞清楚了与当前项目工程,以确保这些名字得到正确设置的一种方式。

EDIT - as requested, this is the view...

--start edit

@model salesWebTest.viewModel.vwbooking

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

@Html.HiddenFor(model => model.bookings.bookingid)
@Html.EditorFor(model => model.bookings.name)

@foreach (var item in Model.traces)
{
    @Html.EditorFor(m => item.contact_Name)
}
}

--end edit

--start original question I have a viewModel that contains two classes...

public class vwbooking
{
    public booking bookings { get; set; }
    public IEnumerable<trace> traces { get; set; }
}

Booking and trace are entities in an edmx.

I want to update the data in these two class with one call to save.

This is what I've tried...

public ActionResult Edit(vwbooking vwbooking)
{
    if (ModelState.IsValid)
    {
        db.bookings.Attach(vwbooking.bookings);
        db.Entry(vwbooking.bookings).State = EntityState.Modified;
        vwbooking.traces.ToList().ForEach( //THE ERROR OCCURS HERE
                  t =>
                  {
                      db.traces.Attach(t);
                      db.Entry(t).State = EntityState.Modified;
                  });
        db.SaveChanges();
    }
}

If I remove the traces portion, the booking portion will update correctly.

This is the GET method...

public ActionResult Edit(int id = 0)
{
    booking booking = db.bookings.Find(id);
    var viewModel = new vwbooking();
    viewModel.bookings = booking;
    viewModel.traces = (from l in db.traces where l.bookingid == booking.bookingid select l);
    return View(viewModel);
}

This is my db context class

public class salesContext : DbContext
{
    public salesContext() : base()
    {
        Configuration.LazyLoadingEnabled = true;
    }

    public salesContext(string Connection) : base(Connection)
    {
        Configuration.LazyLoadingEnabled = true;
    }

    public DbSet<booking> bookings { get; set; }
    public DbSet<trace> traces { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<booking>().HasKey(e => e.bookingid);
        modelBuilder.Entity<trace>().HasKey(e => e.traceid);
    }
}

解决方案

The issue appears to be the way the editor is setup. I believe that this is causing the model to not properly bind on submit

@Html.EditorFor(m => item.contact_Name)

If you were to inspect the name attribute of the <input> element generated by this helper, you will more than likely see that it reads

<input name="item.contact_Name" />

for every one of these. It may even just say name="contact_Name".

This is a severe drawback of the framework and the workarounds for it are usually to make a whole custom helper or to use a front end solution to fix the names.

The name must match exactly to the model. What it should be for your values is

<input name="traces[0].contact_Name" />
<input name="traces[1].contact_Name" />
etc..

and so I would suggest figuring out a way that works with your current project to make sure that those names get properly set.

这篇关于得到错误的POST实体框架 - 值不能为空。参数名:源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆