asp.net MVC 4 how to add data into table query - asp.net

So basically i have made table query "ProductTable" in my data connections
the query contains 4 rows ID,Name,Quantity and Price
all i want is to fill this table with data
in Table.aspx i have this :
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Father.Models.ProductTable>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Table
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h1>Table</h1>
<% using (Html.BeginForm()) { %>
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary() %>
<fieldset>
<ol>
<li>
<%: Html.LabelFor(z => z.ID) %>
<%: Html.TextBoxFor(z => z.ID) %>
</li>
<li>
<%: Html.LabelFor(z => z.Name) %>
<%: Html.TextBoxFor(z => z.Name) %>
</li>
<li>
<%: Html.LabelFor(z => z.Quantity) %>
<%: Html.TextBoxFor(z => z.Quantity) %>
</li>
<li>
<%: Html.LabelFor(z => z.Price) %>
<%: Html.TextBoxFor(z => z.Price) %>
</li>
</ol>
<input type="submit" value="Enter" />
</fieldset>
<% } %>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="FeaturedContent" runat="server">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="ScriptsSection" runat="server">
</asp:Content>
In my Tablemodel :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Globalization;
using System.Web.Security;
namespace Father.Models
{
public class ProductTable
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
public int Price { get; set; }
}
}
in my TableController :
public class TableController : Controller
{
public ActionResult Table()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Table(ProductTable zxc)
{
if (ModelState.IsValid)
{
try
{
}
catch
{
}
}
return View(zxc);
}
}
What to write inside the controller so i can finally put my data into the table

I think you need to spend some more time reading about the MVC paradigm vs. Web Forms. Take a look at Razor as well. You appear to be mixed up as to how everything is supposed to be happening.
You don't need the two methods in your controller.
public ActionResult Table() {
var zxc = new ProductTable();
// Load the data into the object.
return View(zxc);
}
That method in your controller above will pass the ProductTable into the View you have at the top of the question as a Model which will then allow you to populate the data into the Labels and Textboxes that you have set up.
Your HttpPost method that you have there is for saving the data that is changed from the form. You will then validate that everything gets updated properly, and either send them back to another form (if the save was successful), or back to the Table view you have with the model back inside that includes any validation errors or other tips to the user.

Related

MVC 2 model with IList<T> properties binding question

I'm working on an MVC 2 project and I have a model that looks like this:
public string AccountNumber { get; set; }
public IList<Equipment> ShippedEquipmentList { get; set; }
and a view that has a button for adding a new piece of equipment. Clicking the button dynamically adds new textboxes to the view for specifying another piece of equipment. The partial view it renders looks like this:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RmaMVC.Models.Entities.Equipment>" %>
<div class="editorRow">
Item: <%: Html.TextBoxFor(x => x.ItemID); %>
Value: <% Html.TextBoxFor(x => x.Description); %>
</div>
My question is: how do I bind this data to the model? When the controller gets called the ShippedEquipmentList comes back as null.
Edit: here is what I have so far. My model looks like this:
public string AccountNumber { get; set; }
public IList<Equipment> ShippedEquipmentList { get; set; }
FormInputs()
{
ShippedEquipmentList = new List<Equipment>();
// adding a single blank piece of equipment so that the length isn't 0
Equipment blank = new Equipment();
ShippedEquipmentList.Add(blank);
}
my main view is this:
<% Html.BeginForm(); %>
<div id="items">
</div>
<%: Ajax.ActionLink("add new", "AddNewEquipment", new AjaxOptions {
UpdateTargetId = "items", InsertionMode = InsertionMode.InsertAfter }) %>
<input type="submit" value="submit" />
<% Html.EndForm(); %>
my controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormInputs input)
{
return View(input);
}
public ActionResult AddNewEquipment()
{
return PartialView("~/Views/RMA/EditorTemplates/Equipment.ascx");
}
the partial view that generates the text boxes for the equipment:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RmaMVC.Models.Entities.Equipment>" %>
<p>
<%: Html.TextBoxFor(x => x.ItemID) %>
<%: Html.TextBoxFor(x => x.Description) %>
<%: Html.TextBoxFor(x => x.Quantity) %>
<%: Html.TextBoxFor(x => x.SerialNumber) %>
</p>
Check this: Model Binding To A List

MVC2: How submit data from Partial view to his controller?

I have this model:
public class Package
{
public string CustomerName { get; set; }
public List<Product> Products { get; set; }
public int Id { get; set; }
}
public class Product
{
public int Quantity { get; set; }
public string Name { get; set; }
public int Id { get; set; }
}
I have a Create's view for creating a new Package and one or many Create product's PartialView.
How I can submit the Product informations to the Product's controller without leave the View?
Here is my Product's Partialview code:
<% using (Ajax.BeginForm("Create", "Product", new AjaxOptions())) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Name) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Name) %>
<%: Html.ValidationMessageFor(model => model.Name) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Quantity) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Quantity) %>
<%: Html.ValidationMessageFor(model => model.Quantity) %>
</div>
<%-- <p>
<input type="submit" value="Create" />
</p>--%>
</fieldset>
<% } %>
Thank you
You can use AJAX to solve your problem. The code pode below post 3 values to YourController in YourAction.
jQuery('#YourButton').click(function (event) {
var jqxhr = $.post("YourController/YourAction", {
lastName: $("#tbLastName").val(),
firstName: $("#tbFirstName").val(),
id: $("#id").val()
},
function (data) {
$('#WhereResultAppear').html(data); //can be deleted
})
.success(function () {
$('#InCaseOfSuccess').html(data); //can be deleted
})
.error(function (jqXHR, status, error) {
$('#InCaseOfError').html(data); //can be deleted
})
.complete(function () {
$('#WhenActionIsComplete').html(data); //can be deleted
});
});
Give an id to your form in the partial view. and then use JQuery to send data by serializing the form.
$.post("controller/action", $("#formId").serialize(),
function(data) {
alert("Data Loaded: " + data);
});
And in the controller
Package pakage = new Package();
UpdateModel(pakage );
Although you can write code to serialize the data as the other answers mention, I would consider surrounding the fields in an
#using (Ajax.BeginForm("ActionOnController", new AjaxOptions{}))
{
}
This will do it all for you (as long as you include the necessary javascript e.g. jquery.unobtrusive-ajax.min.js)
Take a look at the AjaxOptions documentation. This allows you to (amongst other things) update another section after posting the values back. You can use this to indicate success
Martin

ASP MVC2 Retrieving complex nested object from the form

I'm quite new to ASP MVC so maybe this is simple but I'm really stuck cause I've searched the forums with no luck ;)
I've prepared a simple example of my problem. Here's what I'm trying to do. I have the following model that I'm passing to the view:
public class SearchModel
{
public int ItemsFound { get; set; }
public int TotalItems { get; set; }
public SearchFacetModel SearchFacet { get; set; }
}
and the nested class is
public class SearchFacetModel
{
public string SearchText { get; set; }
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
}
The controller looks like this
[HttpGet]
public ActionResult Index()
{
SearchModel model = new SearchModel { SearchFacet = new SearchFacetModel() { SearchText = "test", DateFrom = DateTime.Now }, ItemsFound=1, TotalItems=10 };
return View(model);
}
[HttpPost]
public ActionResult Index(SearchModel model) // Where is model.SearchFacet? Why null?
{
return View(model);
}
The view:
<% using(Html.BeginForm()) { %>
Search<br />
<%=Html.TextBoxFor(m=>m.ItemsFound) %><br />
<%=Html.TextBoxFor(m=>m.TotalItems) %><br />
Search Facet<br />
<% Html.RenderPartial("SearchFacet", Model.SearchFacet); %>
<button type=submit>Submit</button>
<%} %>
The SearchFacet control:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication3.Models.SearchFacetModel>" %>
<%=Html.TextBoxFor(m=>m.DateFrom) %>
<%=Html.TextBoxFor(m=>m.DateTo) %>
<%=Html.TextBoxFor(m=>m.SearchText) %>
Now, I've already put comment near the Index method with HttpPost. I'm getting the SearchModel object but it doesn't have its SearchFacet child object. The child is null.
When I'm changing SearchFacet.ascx to accept whole SearchModel and pass it from main view then it works. But I don't want to pass whole stuff always and everywhere.
I'm surely missing something related to Model Binder but what and how to make it work my way? :)
Any help will be appreciated.
Gacu
The reason it doesn't work is because HTML helpers inside the partial doesn't generate proper names for the input tags. If you look at the generated source code you will see:
<input type="text" name="SearchText" id="SearchText" value="test" />
whereas it should be:
<input type="text" name="SearchFacet.SearchText" id="SearchFacet_SearchText" value="test" />
in order for the default model binder to properly map the objects in the POST action. One way to solve this is to use editor templates:
<% using(Html.BeginForm()) { %>
Search<br />
<%=Html.TextBoxFor(m=>m.ItemsFound) %><br />
<%=Html.TextBoxFor(m=>m.TotalItems) %><br />
Search Facet<br />
<%= Html.EditorFor(x => x.SearchFacet) %>
<button type=submit>Submit</button>
<%} %>
and then inside (~/Views/Home/EditorTemplates/SearchFacetModel.ascx):
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MvcApplication3.Models.SearchFacetModel>" %>
<%=Html.TextBoxFor(m=>m.DateFrom) %>
<%=Html.TextBoxFor(m=>m.DateTo) %>
<%=Html.TextBoxFor(m=>m.SearchText) %>
Note that the name of the partial should be the same as the type of the property: SearchFacetModel.ascx and located inside the EditorTemplates folder.

ASP.NET MVC2 model binding problem

Why is my controller receiving an empty model in this case?
Using
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<X.Models.ProductModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h2>Product</h2>
<% using (Html.BeginForm() {%>
<%: Html.ValidationSummary(true) %>
<div class="editor-label">
Product Name
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Name) %>
<%: Html.ValidationMessageFor(model => model.Name) %>
</div>
<br />
<div class="editor-label">
Short Description
</div>
<div class="editor-field">
<%: Html.TextAreaFor(model => model.ShortDesc) %>
<%: Html.ValidationMessageFor(model => model.ShortDesc) %>
</div>
<br />
<div class="editor-label">
Long Description
</div>
<div class="editor-field">
<%: Html.TextAreaFor(model => model.LongDesc) %>
<%: Html.ValidationMessageFor(model => model.LongDesc) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
<% } %>
</asp:Content>
and the following controller.
using System.Web.Mvc;
using X.Lib.Services;
using X.Models;
namespace X.Admin.Controllers
{
public class ProductController : Controller
{
[HttpGet]
public ActionResult ProductData()
{
return View();
}
[HttpPost]
public ActionResult ProductData(ProductModel NewProduct)
{
//Validate and save
if(ModelState.IsValid)
{
//Save And do stuff.
var ProductServ = new ProductService();
ProductServ.AddProduct(NewProduct);
}
return View();
}
}
}
Model:
public class ProductModel
{
public int ID;
[Required(ErrorMessage = "Name is required")]
public string Name;
public string LongDesc;
public string ShortDesc;
}
EDIT: you need to use properties not variables
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
public string LongDesc { get; set; }
public string ShortDesc { get; set; }
Also...
You are not passing the model back to the view.
return View(NewProduct);
I normally pass a blank model in to the GET action too
ProductModel NewProduct = new ProductModel();
return View(NewProduct);
This way if you wish to set any default values you can do so easily.
Code example in full I've also added try and catch blocks around the adding of the product and given example views you could be returning on success or fail:
[HttpGet]
public ActionResult ProductData()
{
ProductModel NewProduct = new ProductModel();
return View(NewProduct);
}
[HttpPost]
public ActionResult ProductData(ProductModel NewProduct)
{
//Validate and save
if(!ModelState.IsValid)
{
// Return the model back to view
return View(NewProduct);
}
try{
//Save And do stuff.
var ProductServ = new ProductService();
ProductServ.AddProduct(NewProduct);
}
catch(Exception){
return View("Fail");
}
return View("Success");
}

ModelState always valid

I've got something seemingly very simple not working.
I have got a model
public class Name: Entity
{
[StringLength(10), Required]
public virtual string Title { get; set; }
}
public class Customer: Entity
{
public virtual Name Name { get; set; }
}
a view model
public class CustomerViweModel
{
public Customer Customer { get; set; }
}
a view
<% using(Html.BeginForm()) { %>
<%= Html.LabelFor(m => m.Customer.Name.Title)%>
<%= Html.TextBoxFor(m => m.Customer.Name.Title)%>
<button type="submit">Submit</button>
<% } %>
and a controller
[HttpPost]
public ActionResult Index([Bind(Prefix = "Customer")] Customer customer)
{
if(ModelState.IsValid)
Save
else
return View();
}
No matter what I enter as the title (null, or a string > 10 chars), ModelState.IsValid is always true. The Title field in the Customer object has a value, so the data is being passed around, but not being validated?
Any clues?
In your View I don't see any text box or a field allowing to send data to the controller, only a label. Properties will not be validated if they are not posted. Add a textbox, leave it blank and your model won't be valid any more:
<%= Html.TextBoxFor(m => m.Customer.Name.Title)%>
UPDATE:
Here's the code I've used:
Model:
public class Name
{
[StringLength(10), Required]
public virtual string Title { get; set; }
}
public class Customer
{
public virtual Name Name { get; set; }
}
public class CustomerViewModel
{
public Customer Customer { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index([Bind(Prefix = "Customer")]Customer cs)
{
return View(new CustomerViewModel
{
Customer = cs
});
}
}
View:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyApp.Models.CustomerViewModel>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using(Html.BeginForm()) { %>
<%= Html.LabelFor(m => m.Customer.Name.Title)%>
<%= Html.TextBoxFor(m => m.Customer.Name.Title)%>
<button type="submit">Submit</button>
<% } %>
</asp:Content>
When you submit this form a validation error is shown.
Remark1: I've omitted the Entity base class in the models as I don't how does it look.
Remark2: I've renamed the variable in the Index action to cs. I remember that there was some problems with this in ASP.NET MVC 1.0 when you had the prefix and the variable named the same but I am not sure whether this applies here and I think it was fixed.
Figured it out, it was becuase I'm referencing System.ComponentModel.DataAnnotations 3.6 instead of 3.5. From what I gather, 3.6 is for WCF RIA services only.

Resources