C# MVC Query with WHERE clause and 2 params from the View - c#

I need to query my database with a WHERE clause and pass to parameters from my view to the controller. I am at a total loss as I am a JavaScript and PHP developer and am currently learning dotnet MVC (I am using vs10 framework4).
I need to in essence make this query:
select * from myTable where column1=16 and column2=24
The values of column1 and column2 are in my View. I have found a million examples on how to pull either a whole table, or a result based upon one parameter, I cannot figure out how to do that simple query.
This seems like a simple task and I would appreciate any help as I have spent 5 hours trying to figure this out.
Here are some key components of my code that will hopefully help someone help me. I sincerely appreciate any help.
Controller:
public class SignBuilderController : Controller
{
SignBuilderModel signBuilderModel = new SignBuilderModel();
//
// Initialize database entities
SignBuilderEntities _db;
public SignBuilderController()
{
_db = new SignBuilderEntities();
}
//
// Get /SignBuilder/PrintSetup
[Authorize]
public ActionResult PrintSetup()
{
var pricesList = signBuilderModel.GetPricingList().ToList();
return View("PrintSetup", pricesList);
}
// get Column1 and column 2 query
public ActionResult TestPage(int column1, int column1)
{
//do something here
return View();
}
And in my View I would retrieve the values for my where clause from input fields.
Example:
<input type="text" name="column1value" id="column1value" />
<input type="text" name="column2value" id="column2value" />
Obviously I am using a Model as well, so if that is needed to make this work no problem. I am really looking for sample code I can use as an example to learn from. I really appreciate any help, and am about to pull out my hair.

Try this(I assume your view is strongly typed):
public ActionResult(int column1, int column2)
{
//do something here.
var model =
(
from p in this.GetPricingList()
where (p.column1 == column1) && (p.column2 == column2)
select p
).FirstOrDefault();
return View(model);
}
and in the View:
<input type="text" name="column1" id="column1value" value="<%=Model.column1%>"/>
<input type="text" name="column2" id="column2value" value="<%=Model.column2%>"/>

You need to post the values to the Action method on your controller
Using something like this in your view:
<% using (Html.BeginForm("RunQuery", "ControllerName")) { %>
<input type="text" name="column1" id="column1value" />
<input type="text" name="column2" id="column2value" />
<input type="submit" value="Run Query" />
<% } %>
and then the accompanying action method
[HttpPost]
public ActionResult RunQuery(string column1, string column2)
{
var results = GetDataFromDatabase(column1, column2);
return View(results );
}

I'm afraid your code would not compile. What you annotated as your controller does not inherit from controller class at all and your actionresult method has no name. I wonder how could you visit your page in the browser. The code should be like
public class MyApplicationModel:Controller
{
//use entity framework
private MyApplicationEntities entities = new MyApplicationEntities();
//
// Method to query database for price lists table
public IQueryable<pricingUploaded> GetPricingList()
{
return entities.pricingUploadeds;
}
//
// Method to query Column1 and Column2 in table pricingUploaded
[HttpGet]
public ActionResult Query()
{
//this action will render the page the first time
return View();
}
[HttpPost]//this method will only accept posted requests
public ActionResult Query(int column1, int column2)
{
//do something here.
var _result = entities.Where(x=>x.column1 == column1 && x.column2 == column2);
return View(_result);//pass result to strongly typed view
}
In your view you have to create a form, that when submitted can post values to HttpPost overload of Query method
<%:Html.BeginForm();%>
<input type="text" name="column1">
<input type="text" name="column2">
<input type="submit" id="save" value="query">
<%:Html.EndForm();%>
Now you enter values in your form and click query button, you will have column1 and column2 values in you Query Actionresult accepting posted request. You better put a break point there and inspect how things are really working and figure out how to do what you need to do.
Edit: based on your comment that you want to pass values ajaxically you can do little bit of jQuery:
<script type="text/javascript">
$(function(){
$("form").submit(function(){
$.ajax({
type:"post",
url:"myapplicationmodel/query",
success:function(data)
{
//do something with returned data
}
});
return false;// to prevent normal form post
});
});
</script>

What about this:
public ActionResult(int column1, int column2)
{
var query = from m in _db.MyTable
where m.Column1 == column1
where m.Column2 == column2
select m;
// Or this for typed model
// select new MyModel { Column1 = m.Column1, etc }
var model = query.First();
return View(model);
}

I'm assuming that the entities is a Linq to Entity right? if that is the case, couldn't you use:
var model = from e in entities
where column1=16 and column2=24
select e;
and then pass that model into the vew.
Basically, if entities is of the type IQueryable or IEnumerable or any of the other linq-able interfaces, you can perform that type of query. Make sure that you are using System.Linq; in the top of your code file.
Hope that helps!

Related

Form not returning value to controller action due to ID conflict

I have a form with a DropDownListFor. When I select the ID from my drop down list, select a date and click submit, I get error:
The parameters dictionary contains a null entry for parameter 'CasinoID' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32, System.DateTime, NameSpace.ViewModels.TerminalReceiptPostData)' in 'Namesppace.Controllers.TerminalReceiptsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
It worked fine with just a regular Input tag and typing it in manually... however when I added a DropDownListFor this issue arises. Am I setting up the DDL wrong? Any other issues as to why this would happen? Below is some code.
Controller Action:
[HttpPost]
public ActionResult Index(int CasinoID, DateTime Date)
{
var model = TRBL.GetTransactionTestsData(CasinoID, Date);
return View(model);
}
View:
#using (Html.BeginForm("Index", "TerminalReceipts", new { id = "submitForm" }))
{
<div>
#*<input type="text" name="CasinoID" placeholder="Enter Casino ID" id="cIdSearch" />*#
#Html.DropDownListFor(o => o.TerminalReceiptPostData.CasinoIdDDL, Model.TerminalReceiptPostData.CasinoIdDDL, new { id = "CasinoID"})
<input id="datepicker" class="datepicker-base" name="Date" placeholder="MM/DD/YYY" type="text" />
<button type="submit" class="btn btn-sm btn-primary" id="search" onclick="checkField()"> Search Transactions</button>
</div>
}
Edit update
So I was able to change how the structure a bit to now be able to get the CasinoID to be passed properly to the controller action. Below are the changes... however after the action goes to return the model, I get an obj reference not set to instance of the obj err.
Action:
[HttpPost]
public ActionResult Index(int CasinoID, DateTime Date)
{
var id = Int32.Parse(Request.Form["CasinoID"].ToString());
var model = TRBL.GetTransactionTestsData(id, Date);
return View(model);
}
Change to DDL:
#Html.DropDownList("CasinoID", Model.TerminalReceiptPostData.CasinoIdDDL, "Select Casino")
The int CasinoID will be bound by a form field with the name CasinoID. I think the #Html.DropDownListFor is not generating the 'name' you want.
You can add name explicitly like
#Html.DropDownListFor(o => o.TerminalReceiptPostData.CasinoIdDDL, Model.TerminalReceiptPostData.CasinoIdDDL, new { id = "CasinoID", name="CasinoID"})
Or better to create a ViewModel with the fields CasinoID, Date & CId and use BindProperty on that ViewModel instance
Okay so I figured out what was going on..
I actually have two seperate controller actions named Index. One for post and one for get. Since I am now sending back a model on the POST one, the drop down list was not getting "re-filled" with the drop downs... So i simply took a call from my GET action and added it to the post..
[HttpPost]
public ActionResult Index(int CasinoID, DateTime Date)
{
var id = Int32.Parse(Request.Form["CasinoID"].ToString());
var model = TRBL.GetTransactionTestsData(id, Date);
model.TerminalReceiptPostData = TRBL.GetCasinosDDL();
return View(model);
}
Probably not the best way to do it, but works fine.

asp net. How to remove data from a database

First I want to say I'm just starting to learn and I'm french, so please be very simple in your explanation. Just imagine you're talking to a 3 years old and I should be ok. Please don't overload me with dozens of lines of code without any explanation.
OK here's what I want to do: I have a very simple database table of article author. The table has 5 columns:
First Name, Second name, Dob, Phone Nb, Place of Birth, UserId
The userId is automatically created. I have created a form where a user would write the first name and second name (in 2 separated textboxes and I want to use that to fetch the userId in the table and use it to delete the entire line)
Here's the code for my form
model projet_clement.Models.HomeModel
<form method="post" action="~/home/SupressionAuteur">
<h3>deleting author page</h3>
<p>first name of the author to delete</p>
<input type="text" name="Nom" />
<p>second name of the author to delete</p>
<input type="text" name="Prenom" /><br />
<br />
<input type="submit" value="Delete" />
</form>
<h3>For reminder, here's a table of the author already created</h3>
<table>
<tr>
<td>Nom</td>
<td>Prenom</td>
<td>Date de naissance</td>
<td>N° de téléphone</td>
<td>Département de naissance</td>
<td>UserId</td>
</tr>
#foreach (var i in Model.UserList)
{
<tr>
<td>#i.Nom</td>
<td>#i.Prenom</td>
<td>#i.Naissance</td>
<td>#i.Numero</td>
<td>#i.Departement</td>
<td>#i.userId</td>
</tr>
}
</table>
OK now what I would like to know is how can I get the userId thanks to the first name and second name, and how can I delete a whole row just using this id.
Here's my c# code
[HttpGet]
public ActionResult SupressionAuteur()
{
var allUsers = db.Users.Where(x => x.Nom != null);
var model = new HomeModel(allUsers);
return View(model);
}
[HttpPost]
public ActionResult SupressionAuteur(Users formUser)
{
//for those who skipped french class, nom = first name and prenom = second name;)
var userId = db.Users.Where(x => x.Nom == formUser.Nom && x.prenom == formuser.prenom);
db.Users.Remove([What should i write here?]);
return RedirectToAction("SupressionAuteur", "Home");
}
Of course it doesn't work!
When I run my code the userId var never get the good value. So I guess the way I try to get it is wrong
And how am I supposed to use the db.users.remove() method? Is it the one I should use by the way? I was told so.
Thanks in advance, I'm really stuck :)
Steps
Get the user - ideally you want to use the userid (or primary key) to retrieve the user
Remove the user from the db
Save the changes in the context
Code:
var user = db.Users.Single(x => x.Nom == formUser.Nom && x.prenom == formuser.prenom);
db.Users.Remove(user);
db.SaveChanges();

What does values["PromoCode"] reference?

I am going through this tutorial and am confused as to what he is refrencing with the first part of this statement, at first i thought it was the values in the promo code table but there is no model to build that table from. The tutorial link is as follows:http://www.asp.net/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-9
string.Equals(values["PromoCode"], PromoCode,
StringComparison.OrdinalIgnoreCase) == false
PromoCode is a constant
values["PromoCode"] is one of the posted values from the form : see in the view
You can access the FormCollection (values is a FormCollection, which stores all inputs from the form, and inherits from NameValueCollection) by its keys : the keys are the names of the inputs.
<div class="editor-field">
#Html.TextBox("PromoCode") // it's not a TextBoxFor
</div>
this will generate something like
<input type="text" name="PromoCode" id="PromoCode" />
It's not linked to anything in the model, indeed.
See the method signature:
public ActionResult AddressAndPayment(FormCollection values)
So it is a collection of all posted values.
See the signature of the method:
public ActionResult AddressAndPayment(FormCollection values) // <-- here
{
// ...
if (string.Equals(values["PromoCode"], PromoCode,
StringComparison.OrdinalIgnoreCase) == false)
{
// ...
}
// ...
}
the values is of type FormCollection, which means the data collection in the HTML <form> posted from browser, the MVC model-binding will gather form data into FormCollection instance (the values here), so you may get form data by code like values["PromoCode"], which is the same as Request.Form["PromoCode"] in classic asp/asp.net.

Getting value from jquery datetimepicker in MVC

Im playing around with a booking-system in MVC.
I have a view where you select 3 diffrent values (treatment, hairdresser and date).
#using (Html.BeginForm("testing", "Home", FormMethod.Post)) {
<p id="frisor"> Frisör: #Html.DropDownList("Fris", "All")<a class="butt" onclick="showdiv()">Nästa steg</a></p>
<p id="behandling">Behandling: #Html.DropDownList("Cat", "All")<a class="butt" onclick="showdiv2()">Nästa steg</a></p>
<p>
Datum:
<input type="text" id="MyDate" /> <-------This is a jquery datetimepicker
</p
I would like to save the customers three choices in three properties i have created.
My post method looks like this:
[HttpPost]
public ActionResult Testing(string Fris, string Cat, DateTime MyDate)
{
kv.treatment = Cat
kv.Hairdresser = Fris;
kv.Datum = MyDate;
return View();
}
I get the two first (hairdresser,treatment) fine,
the problem is that i dont know how to get the value from the jquery datetimpicker.
Any help appreciated!
The input needs a name in order to be included in the form post:
<input type="text" id="MyDate" name="MyDate" />
Otherwise the browser won't include it in the posted data, so it will never reach the server for model binding. (And, of course, the name has to match the method argument name for the model binder to match them.)

dropdown in mvc3 edit form

This maybe very simple but I cant seem to sort it out on my own.
I have created a simple db and entity modal that looks like this
I am trying to create an Create form that allows me to add a new Order. I have a total of 3 tables so what I am trying to do is have the form allowing the person to enter Order date and also has a dropdown list that allows me to select a product from the product table
I want to be able to create a Add or Edit view that allow me to insert the OrderDate into the OrderTable and also insert the OrderID and selected ProductID into OrderProduct.
What steps do I need to do here.
I have created an OrderController and ticked the "Add Actions" and than added a Create View which looks like this
#model Test.OrderProduct
#{
ViewBag.Title = "Create2";
}
<h2>Create2</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>OrderProduct</legend>
<div class="editor-label">
#Html.LabelFor(model => model.OrderID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OrderID)
#Html.ValidationMessageFor(model => model.OrderID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductID)
#Html.ValidationMessageFor(model => model.ProductID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
This creates the view that contains a textbox for both OrderID and ProductID however no date.
My controller CreatePost hasnt been changed
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
var data = collection;
// TODO: Add insert logic here
// db.Orders.AddObject(collection);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
My questions are,
1.How do I swap out ProductID textbox to be a dropdown which is populated from Product
2.How do I get the data from FormCollection collection? I thought of just a foreach however I dont know how to get the strongly typed name
Any help for a newbie would be very helpful.
Thank you!
First thing's first, don't bind to the Order entity. Never bind to an EF object, always try and use a ViewModel. Makes life simpler for the View, and that is the goal here.
So, have a ViewModel like this:
public class CreateOrderViewModel
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int SelectedProductId { get; set; }
public IEnumerable<SelectListItem> Products { get; set; }
}
That's it right now.
Return that to your View in your [HttpGet] controller action:
[HttpGet]
public ActionResult Create()
{
var model = new CreateOrderViewModel
{
Products = db.Products
.ToList() // this will fire a query, basically SELECT * FROM Products
.Select(x => new SelectListItem
{
Text = x.ProductName,
Value = x.ProductId
});
};
return View(model);
}
Then to render out the list of Products: (basic HTML excluded)
#model WebApplication.Models.CreateOrderViewModel
#Html.DropDownListFor(model => model.SelectedProductId, Model.Products)
The only thing i don't know how to do is bind to the DateTime field. I'm guessing you would need an extension method (HTML Helper) which renders out a Date Picker or something. For this View (creating a new order), just default to DateTime.Now.
Now, onto the [HttpPost] controller action:
[HttpPost]
public ActionResult Create(CreateOrderViewModel model)
{
try
{
// TODO: this manual stitching should be replaced with AutoMapper
var newOrder = new Order
{
OrderDate = DateTime.Now,
OrderProduct = new OrderProduct
{
ProductId = SelectedProductId
}
};
db.Orders.AddObject(newOrder);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Now, i also think your EF model needs work.
To me (in English terms), a Product can have many orders, and an Order can have many Products.
So, it should be a many-to-many. Currently it's a 1-1 with a redundant join table. Did you generate that from a DB? If so, your DB possibly needs work.
You should have a navigational property called Products on the Order entity, which references a collection of Product, made possible by a silent join to the join table in the many-to-many.
This also means you no longer have a DropDownList, but a MultiSelectDropDownList.
Thanks Craig. Your few days (as at time of posting) of MVC have solved my few days of trying to get the selected value back from DropDownListFor.
I had no problem in the Create view in getting the selected value of the DDLF, but the Edit view was a completely different matter - nothing I tried would get the selected value back in the Post. I noticed the selected value was lurking in the AttemptedValue of the ModelState, and so Dr.Google referred me here.
I had this in my view
#Html.DropDownList(model => model.ContentKeyID, Model.ContentKeys, Model.ContentKeyName)
where ContentKeys is a SelectList populated from the DB via a ViewModel, and ContentKeyName is the curently selected name.
The wierd thing is, I have another DDL on the view populated in an identical manner. This one works. Why, I don't know. It is the second DDL on the form, but I can't see that making a difference.
I read somewhere else it might have been that I was using Guids as the Id, but that didn't seem to make a difference - I changed to Int32, but don't think I had to - I think it's enums that disagree with DDLF. Nullables seemd to make no difference either.
Now that I've added the form collection to my Post ActionResult, and get the selected value using
-view
#Html.DropDownList("ContentKey", Model.ContentKeys)
-in controller (Post)
contentKeyId = int.Parse(form.GetValue("ContentKey").AttemptedValue);
all is good, and I can get on with more exciting things. Why is that the simplest things can hold you up for so long?
I have been struggling with this over the last day or so too. I'll share my limited knowledge in the hope that it will help someone else.
Note that I use a singleton with a pre-populated list to keep my example application small (i.e. no EF or DB interaction).
To show the ProductList you will need to have a ViewBag or ViewData item which contains the ProductList.
You can set this up in the Controller with something like
ViewData["ProductList"] = new SelectList(Models.MVCProduct.Instance.ProductList, "Id", "Name", 1);
Then update your View to something like:
<div class="editor-field">#Html.DropDownList("ProductList")</div>
For the Post/Create/Update step you need to look into the FormCollection to get your results. Reading other posts it sounds like there used to be a bug in here, but it's fixed now so ensure you have the latest. For my example I have a DropDownList for Product so I just get the selected Id and then go searching for that Product in my list.
[HttpPost]
public ActionResult Create(FormCollection form )//Models.MVCOrder newOrder)
{
MVC.Models.MVCOrder ord = Models.MVCOrder.Instance.CreateBlankOrder();
//Update order with simple types (e.g. Quantity)
if (TryUpdateModel<MVC.Models.MVCOrder>(ord, form.ToValueProvider()))
{
ord.Product = Models.MVCProduct.Instance.ProductList.Find(p => p.Id == int.Parse(form.GetValue("ProductList").AttemptedValue));
ord.Attribute = Models.MVCAttribute.Instance.AttributeList.Find(a => a.Id == int.Parse(form.GetValue("attributeId").AttemptedValue));
UpdateModel(ord);
return RedirectToAction("Index");
}
else
{
return View(ord);
}
}
I've only been working on MVC3 for the last few days, so any advice on improving the above would be appreciated.

Categories

Resources