Asp.net mvc 在后期编辑中保存表单的正确方法?

Asp.net mvc 在后期编辑中保存表单的正确方法?,asp.net-mvc,asp.net-mvc-4,entity-framework-4,Asp.net Mvc,Asp.net Mvc 4,Entity Framework 4,一般来说,我对asp.net和mvc有些陌生。我正在实现控制器的GET-edit和POST-edit方法。我正在使用强类型视图编辑表单。我正在将模型传递回POST-edit方法,但我不知道如何保存它。这是我到目前为止所拥有的。。。我知道的不多 [HttpPost] public ActionResult ModifyContract(ModContract mod) { // submit modified contract if (Mod

一般来说,我对asp.net和mvc有些陌生。我正在实现控制器的GET-edit和POST-edit方法。我正在使用强类型视图编辑表单。我正在将模型传递回POST-edit方法,但我不知道如何保存它。这是我到目前为止所拥有的。。。我知道的不多

    [HttpPost]
    public ActionResult ModifyContract(ModContract mod)
    {
        // submit modified contract
        if (ModelState.IsValid)
        {
            OutlookMediaEntities1 db = new OutlookMediaEntities1();
            db.ObjectStateManager.ChangeObjectState(mod, EntityState.Modified);

            // save changes
            db.SaveChanges();

            return RedirectToAction("ContractDetails", "Contract", new { id = (int) ViewData["contractid"] });
        }
        else
        {
            ModelState.AddModelError("", "Missing necessary information");
            return View();
        }
    }
我在db.ObjectStateManager上收到一个InvalidOperation异常。。。线路。我看到一些东西说这可能是因为我没有分配主键,并且注意到我的ModAds类(下面)没有包含主键。添加了它,但我得到了相同的错误。以下是堆栈跟踪:


[InvalidOperationException: The ObjectStateManager does not contain an ObjectStateEntry with a reference to an object of type 'oulookmediaweb.Models.ModContract'.]
   System.Data.Objects.ObjectStateManager.ChangeObjectState(Object entity, EntityState entityState) +278
   oulookmediaweb.Controllers.ContractController.ModifyContract(ModContract mod) in C:\Users\georgiev.1\Outlook4\oulookmediaweb\Controllers\ContractController.cs:1113
   lambda_method(Closure , ControllerBase , Object[] ) +163
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +205
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.c__DisplayClass42.b__41() +28
   System.Web.Mvc.Async.c__DisplayClass8`1.b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +50
   System.Web.Mvc.Async.c__DisplayClass39.b__33() +58
   System.Web.Mvc.Async.c__DisplayClass4f.b__49() +237
   System.Web.Mvc.Async.c__DisplayClass37.b__36(IAsyncResult asyncResult) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50
   System.Web.Mvc.Async.c__DisplayClass2a.b__20() +24
   System.Web.Mvc.Async.c__DisplayClass25.b__22(IAsyncResult asyncResult) +126
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +45
   System.Web.Mvc.c__DisplayClass1d.b__18(IAsyncResult asyncResult) +14
   System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +25
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +61
   System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +25
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +49
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.c__DisplayClass8.b__3(IAsyncResult asyncResult) +28
   System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +25
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +49
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8970141
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
以下是模型:

public class ModContract
{
    public int contract_id;
    public string contract_name { get; set; }
    public List<ModAds> ads;

    public string print_product_id { get; set; }
    public string print_ad_option_id { get; set; }
}

public class ModAds
{
    public int contr_ad_id;
    public string name;
    public string product_name;
    public string adv_product;
    public List<string> editions;
    public double freq_disc;
    public double other_dis_dol;
    public double? other_dis_per;
    public string non_cash_note;
    public double non_cash_cons;
}
当我将第一行放入代码中时,它甚至没有编译;上面说没有方法条目。模型如何从表单字段中获取新值?视图如何知道将该模型作为参数传递?是因为视图是强类型的吗?如果不是呢?视图是否汇总了所有输入并选择表单元素中的内容并将其放入模型中?我只是对这一切是如何运作的感到困惑。最重要的是,如何保存模型

感谢您的帮助或帮助链接!提前谢谢

当我将第一行放入代码中时,它甚至没有编译;上面说 没有方法条目

这很可能是因为您使用的是旧版本的EF。在4.1版之前,EF使用的
ObjectContext
没有
条目
方法。EF 4.1+使用具有
Entry
方法的DbContext。另外,您有一个名为
mod
的参数,并且您正在保存一个名为
model
的变量,这是打字错误吗?有

模型如何从表单字段中获取新值?视图如何知道将该模型作为参数传递

它叫

是因为视图是强类型的吗

如果不是呢

只要正确命名HTML元素,您仍然可以利用模型绑定。例如,您将控制器方法声明为:

[HttpPost]
ActionResult Product(int id, string name) {
}
如果命名与参数名称匹配的元素,则模型绑定器可以完成其工作:

<input type="hidden" name="id"/>
<input type="text" name="name" id="name"/>

当您说“model”时,我假设这些是您从数据库查询并传递到视图的实体?是的,我在GET edit中查询数据库,并将查询的内容放入模型并返回视图(model)。您是否使用EF 4.1及以上版本?不,我相信是4.0。您确定“EF 4.1+使用DbContext”吗?我认为代码首先使用DbContext,模型首先使用ObjectContext,而不管EF版本如何。不过我可能错了。尽管您可以先使用DbContext生成器模板从模型生成DbContext。我猜提问者是首先使用模型的,但是有一些来自MVC示例的代码首先使用了代码。这很有意义,谢谢!不过我使用的是EF4.0,所以db.Entry这个东西不起作用。db.Entry行不是我代码的一部分(我删除了它,因为它不起作用),我只是想说明我在教程中看到了什么,比如你链接到lol的那一行。有没有EF 4.0教程的链接?有一段时间我不确定,因此,我使用EF挖掘一些旧项目,并仔细检查它是否引用了版本
4.1.10715.0
,以确保不会误导任何人。因此,DbContext在该版本中可用。谢谢你的评论@AaronLS:)不客气@maus。如果你还在开始你的项目,我建议你使用最新的版本,我想是第5版。它可能有一些问题,但它带来的好处加上以前版本解决的问题将超过它。这是一个小组项目,已经做了一段时间了。我宁愿现在不更新任何东西。
<input type="hidden" name="id"/>
<input type="text" name="name" id="name"/>
[HttpPost]
public ActionResult ModifyContract(ModContract mod)
{
    // do some validation or anything else you need to do here
    // then save your entity
    db.Entry(mod).State = EntityState.Modified;
    db.SaveChanges();
}