2

一般来说,我对 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();

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

任何帮助或帮助链接表示赞赏!提前致谢!

4

1 回答 1

3

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

这很可能是因为您使用的是旧版本的 EF。4.1 EF 之前使用的ObjectContext是没有Entry方法的。EF 4.1+ 使用具有该Entry方法的 DbContext。另外,您有一个名为的参数mod,并且正在保存一个名为 的变量model,这是拼写错误吗?这里有一个很棒的关于 EF 和 MVC 的教程

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

它被称为模型绑定,在这里有很大的解释

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

是的

如果不是,会发生什么?

只要正确命名 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();
}
于 2013-04-17T01:33:16.493 回答