在POST编辑中保存表单的正确方法?

时间:2013-04-17 01:08:31

标签: asp.net-mvc asp.net-mvc-4 entity-framework-4

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

    [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 ...行上遇到InvalidOperationException。我看到可能是因为我没有分配主键并注意到我的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;
}

我不知道如何保存通过的模型。我看过的所有教程都有非常简单的模型,保存是通过类似的,

完成的
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();

当我把它放在我的代码中时,第一行甚至都没有编译;它说没有方法入口。模型如何从表单字段中获取新值?视图如何知道将该模型作为参数传递?是因为视图是强类型的吗?如果不是,会发生什么?视图是否汇总了所有输入并选择表单元素中的内容并将它们放入模型中?我只是对它的运作方式感到困惑。最重要的是,如何保存模型?

感谢任何帮助或帮助链接!提前谢谢!

1 个答案:

答案 0 :(得分:3)

  

当我把它放在我的代码中时,第一行甚至都没有编译;它说   没有方法输入。

这很可能是因为您使用的是旧版EF。在4.1之前,EF使用没有ObjectContext方法的Entry。 EF 4.1+使用具有Entry方法的DbContext。此外,您有一个名为mod的参数,并且您正在保存名为model的变量,这是一个拼写错误?有a great tutorial on EF and MVC here

  

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

它被称为model binding that is greatly explains here

  

是因为视图是强类型的吗?

  

如果不是,会发生什么?

只要正确命名HTML元素,您仍然可以利用模型绑定。例如,您有一个声明为:

的控制器方法
[HttpPost]
ActionResult Product(int id, string name) {
}

如果命名与参数名称匹配的元素,模型绑定器可以完成它的工作:

<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();
}