开发者

Asp.Net Mvc - RenderAction - Create in a list view

EDIT

I put my solution on a share site. Like that you'll be able to see what I'm talking about. You can download it here : http://www.easy-share.com/1909069597/TestRenderAction.zip

To test it, start the project (let the create form empty) and click the Create button. You'll see what happen.

It's only a example project. I don't care to persist my object to the database for now. I care to make my example work.

I got the following controller :

public class ProductController : Controller
{
    public ActionResult List()
    {
        IList<Product> products = new List<Product>();

        products.Add(new Product() { Id = 1, Name = "A", Price = 22.3 });
        products.Add(new Product() { Id = 2, Name = "B", Price = 11.4 });
        products.Add(new Product() { Id = 3, Name = "C", Price = 26.5 });
        products.Add(new Product() { Id = 4, Name = "D", Price = 45.0 });
        products.Add(new Product() { Id = 5, Name = "E", Price = 87.79 });

        return View(products);
    }

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

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(Product product)
    {
        return View(product);
    }
}

The following model :

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
}

My Product/List.aspx :

<h2>List</h2>

<table>
    <tr>
        <th></th>
        <th>
            Id
        </th>
        <th>
            Name
        </th>
        <th>
            Price
        </th>
    </tr>

<% foreach (var item in Model) { %>

    <tr>
        <td>
            <%= Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) %> |
            <%= Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ })%>
        </td>
        <td>
            <%= Html.Encode(item.Id) %>
        </td>
        <td>
            <%= Html.Encode(item.Name) %>
        </td>
        <td>
            <%= Html.Encode(String.Format("{0:F}", item.Price)) %>
        </td>
    </tr>

<% } %>

</table>

<p>
   <% Html.RenderAction("Create"); %>
</p>

My Product/Create.ascx :

<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

<% using (Htm开发者_如何学Gol.BeginForm("Create", "Product", FormMethod.Post)) {%>

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Id">Id:</label>
            <%= Html.TextBox("Id") %>
            <%= Html.ValidationMessage("Id", "*") %>
        </p>
        <p>
            <label for="Name">Name:</label>
            <%= Html.TextBox("Name") %>
            <%= Html.ValidationMessage("Name", "*") %>
        </p>
        <p>
            <label for="Price">Price:</label>
            <%= Html.TextBox("Price") %>
            <%= Html.ValidationMessage("Price", "*") %>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<% } %>

<div>
    <%=Html.ActionLink("Back to List", "Index") %>
</div>

The problem is that when I hit the create button and I got an error (like empty field), the return view only return my Create.ascx control. It's doesn't return the Product/List.asxp page with in my Create.ascx control with the errors. That's what I would like it's does.

Any idea how I can solve that problem ?

I use Asp.Net Mvc 1 with Asp.Net Futures (which have the Html.RenderAction).


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Product product)
{
  ...
  return View("List");
}

or

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Product product)
{
  ...
   return RedirectToAction("List", "Product");
}


your controller should work like this:

public class ProductController : Controller
{
  IList<Product> products;

  public ProductController( )
  {
    products = new List<Product>();
    products.Add(new Product() { Id = 1, Name = "A", Price = 22.3 });
    products.Add(new Product() { Id = 2, Name = "B", Price = 11.4 });
    products.Add(new Product() { Id = 3, Name = "C", Price = 26.5 });
    products.Add(new Product() { Id = 4, Name = "D", Price = 45.0 });
    products.Add(new Product() { Id = 5, Name = "E", Price = 87.79 });
  }

  public ActionResult List( )
  { 
    return View(products);
  }

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

  [AcceptVerbs(HttpVerbs.Post)]
  public ActionResult Create(Product product)
  {
    products.Add(product);
    return View("List", products);      
  }
} 

Additionally, you need to call RenderPartial instead of RenderAction, because otherwise your POST method will be invoked (due to you did a post-command by submitting the form):

<p> 
   <% Html.RenderPartial("Create"); %> 
</p> 

This should work, you only need to persist your products list, as it will reset with every postback.

I hope this helped you :)


Are the names of your text fields the same as the properties in your Product object?

Does your product object declare it's properties like this;

public string Name {get;set;}

You must have getters and setters on your objects.

EDIT

Wait, are you wanting fields from your list View to be available in the post to your create action? If yes then you need to place the BeginForm at the View level and not the PartialView level.

Only fields contained within the begin form will be posted to your controller.

EDIT 2

Ah, I think I see it now.

In your controller I think you should do a product.IsValid to check first.

But in your html you should also do this;

<%= Html.TextBox("Id", Model.Id) %>

You need to fill in the value for the text box.

Hope this is what you were after.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜