ado.net mvc3元组在模型和单个视图中使用

时间:2011-11-14 07:04:32

标签: asp.net-mvc-3 tuples

我有以下ADO模型

学生 ID,名称 和 的 ID,名称,student_id数据

我为它做了以下观点

@model Tuple<MvcApplication4.Models.Course, MvcApplication4.Models.Student >
@{
    ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Course</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Item1.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Item1.Name)
            @Html.ValidationMessageFor(model => model.Item1.Name)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Item1.S_ID, "Student")
        </div>
            <fieldset>
        <legend>Student</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Item2.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Item2.Name)
            @Html.ValidationMessageFor(model => model.Item2.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Item2.Class)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Item2.Class)
            @Html.ValidationMessageFor(model => model.Item2.Class)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

    </fieldset>
}

它的控制器为

public ActionResult Create()
{
      return View();
} 

//
// POST: /Default3/Create

[HttpPost]
public ActionResult Create(Tuple<Student ,Course > t)
{

    try
    {
        // TODO: Add insert logic here

        db.Students.AddObject(t.Item1);
        db.SaveChanges();

        t.Item2.S_ID = t.Item1.Id;
        db.Courses.AddObject(t.Item2);
        db.SaveChanges();

        return RedirectToAction("Copy");
    }
    catch
    {
        return View();
    }
}

但是当我点击“创建”按钮时,它会出现以下错误

  
    应用程序中的服务器错误。

  
     

没有为此对象定义无参数构造函数。

7 个答案:

答案 0 :(得分:11)

Tuple<X, Y>类没有默认构造函数,因此如果您希望这样做,则需要编写自定义模型绑定程序。另一种可能性是使用我建议你的自定义视图模型:

public class MyViewModel
{
    public Course Course { get; set; }
    public Student Student { get; set; }
}

然后:

public ActionResult Create()
{
    return View(new MyViewModel());
} 

//
// POST: /Default3/Create

[HttpPost]
public ActionResult Create(MyViewModel model)
{
    try
    {
        // TODO: Add insert logic here
        db.Students.AddObject(t.Student);
        db.SaveChanges();

        t.Course.S_ID = t.Student.Id;
        db.Courses.AddObject(t.Course);
        db.SaveChanges();

        return RedirectToAction("Copy");
    }
    catch
    {
        return View(model);
    }
}

最后:

@model MvcApplication4.Models.MyViewModel
@{
    ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Course</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Student.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Student.Name)
            @Html.ValidationMessageFor(model => model.Student.Name)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Student.S_ID, "Student")
        </div>
            <fieldset>
        <legend>Student</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Course.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Course.Name)
            @Html.ValidationMessageFor(model => model.Course.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Course.Class)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Course.Class)
            @Html.ValidationMessageFor(model => model.Course.Class)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

答案 1 :(得分:2)

MVC非常聪明,但它无法真正弄清楚如何创建Tuple的新实例并创建项目的新实例,然后为其分配适当的项目。这太复杂了。

您得到的错误是因为Tuple没有默认的无参数构造函数,并且需要在构造函数中将新项传递给它,这是MVC无法做到的。

您必须将其分解,并在包含项目成员的视图模型中在控制器操作中创建元组。

答案 2 :(得分:2)

您需要将模型传递给您的视图。 例如:

return View(model);

答案 3 :(得分:1)

这似乎已经解决了我作为替代方案的问题,它现在正在运作:

[HttpGet]
public ActionResult Create()
{  
    Course course = new Course();
    Student student = new Student();
    var tuple = new Tuple<Course,Student>(course,student);
    return View(tuple);
}

[HttpPost]
public ActionResult Create(Tuple<Course,Student> tuple){ do something ...}

我尝试了其他一些方法,包括一些已经在这里建议但是没有解决问题的方法。我刚发布这个帖子是为了帮助那些可能想要使用Tuple的人,只有在你没有其他选择时才使用它。

答案 4 :(得分:0)

经过几分钟的挖掘和思考后,我开始工作了。以下是我所做的一个简单示例:

GET行动:

[HttpGet]        
public ActionResult Update(int id = 0) 
{
    ProductDto product = _productService.FindByID(id);
    SupplierDto supplier = _supplierService.FindByProductID(productId: product.ProductID);        

    return View(model: new Tuple<ProductDto, SupplierDto>(product, supplier));
}

发布操作:

[HttpPost]
public JsonResult Update(int id = 0, ProductDto Item1, SupplierDto Item2) 
{
    // Get the product name
    string productName = Item1.ProductName;

    // Get the supplier name
    string supplierName = Item2.SupplierName;

    ...

    return Json(new { success = true });
}

查看:

@model Tuple<ProductDto, SupplierDto>
@{
    ViewBag.Title = "add title later ... ";
    AjaxOptions options = new AjaxOptions { ... };
}

@using (Ajax.BeginForm("Update", "Product", options, htmlAttributes: new { @id = "update-form" })) 
{
    <fieldset>
        <legend>Update Product</legend>
        <div class="display-label">
            @Html.LabelFor(model => model.Item1.ProductName)         
        </div>
        <div class="display-field">
            @Html.EditorFor(model => model.Item1.ProductName)            
        </div>

        ...

         <div class="display-label">
            @Html.LabelFor(model => model.Item2.SupplierName)
        </div>
        <div class="display-field">
            @Html.EditorFor(model => model.Item2.SupplierName)            
        </div>
    </fieldset>
    <div class="submit-button">
        <button type="submit" class="button">Update details</button>
    <div>
}

答案 5 :(得分:0)

您应该在参数中绑定前缀 控制器:

public ActionResult ThisMethod([Bind(Prefix = "Item1")] AccountViewModel model)
{
            // toDo
}

查看:

@model Tuple<AccountViewModel>

@Html.EditorFor(model => model.Item1.Firstname)  

答案 6 :(得分:0)

@DarinDimitri的解决方案是正确的,但是Tuple也有办法。如果仅在下面更改这些代码,则将获得元组模型。

[HttpPost]
public ActionResult Create(Course Item1, Student Item2)
{
    try
    {
        // TODO: Add insert logic here

        db.Students.AddObject(Item2);
        db.SaveChanges();

        Item1.S_ID = Item2.Id;
        db.Courses.AddObject(Item1);
        db.SaveChanges();

        return RedirectToAction("Copy");
    }
    catch
    {
        return View();
    }