How to get rid of the foriegn key exception in mvc - c#

I have a module in my project where in a functionality I have a textbox where I am entering a missing note and saving it with button, but the table where I am saving the data is having a foreign key and I am getting the following exception
My code is as follows
public ActionResult SetBreakageNote(int id, string MissNote, int charge)
{
var Rdetail = new ReservationDetail();
if (ModelState.IsValid)
{
Rdetail.ReservationID = id;
Rdetail.Description = MissNote;
Rdetail.ChargeType = charge;
db.Insert(Rdetail);
}
return RedirectToAction("Index");
}
My View
#model IEnumerable<RoomTypeView>
<div class="row">
#foreach (var item in Model)
{
<div class="col-3">
<div class="row">
<div class="col-8">
<div class="inventory my-1">
<textarea class="form-control breakage" placeholder="Enter Breakage Note" rows="1"></textarea>
</div>
</div>
<div class="col-4">
<button type="button" class="btn btn-default breakage" data-brid="#item.ReservationID"><i class="fa fa-file-invoice" style="color:red;"></i></button>
</div>
</div>
</div>
}
</div>
$('.breakage').click(function () {
$.post("#Url.Action("SetBreakageNote", "HouseKeeping")", { id: $(this).data('brid'), MissNote: $('.breakage').val(), charge: #((int)ChargeTypeEnum.Breakage) });
});
Here is the exception I am getting
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_ReservationDetails_Reservation". The conflict occurred in database "CavalaV3DB", table "dbo.Reservation", column 'ReservationID
ReservationID is a foreign key for Reservation table.
Please help me with this

You are trying to insert some value into your Rdetail in ReservationID column. But that value is not there in Reservation table.
This is violating Foreign key constraint created in the Rdetail table.
You can avoid this by checking this before inserting data into the table
if (ModelState.IsValid)
{
if(db.Reservation.where(a=>a.ReservationId==id).Amy()) //Condition to check if data is there or not
{
Rdetail.ReservationID = id;
Rdetail.Description = MissNote;
Rdetail.ChargeType = charge;
db.Insert(Rdetail);
}
}

Before data can be inserted, the value in the foreign key field must exist in the other table first.You must build the table containing the Primary Key first after that you can populate them in a drop down from where you need to select first to save data.
the best way to deal with foreign key in other table's View Bind them in a Drop Down List and set attribute required

Related

Blazor Server - Insert CustomerID when inserting a Project to another table

My project has a few tiers here. Customer -> Project
The Project Table has a value for the CustomerID.
I'm getting a list of CustomerNames using my CustomersModel.
Simple example of what I'm trying to do here. Choose a customer from a list and then type in a new Project Name and submit that to a table. Binding the CustomerID causes the "Chose a Customer" option to not show up in the select drop down. If I put CustomerName is the bound value it will show as the placeholder for the drop down.
But I need to pass the CustomerID to the Projects Table with the new Project Name.
I'm not sure what I'm missing here.
--
Component Code
<EditForm Model="#newProject" OnValidSubmit="#InsertLocation">
<DataAnnotationsValidator />
<div class="form-group">
<div class="row">
<div class="col-md-5">
<label class="form-label">Customer Name</label>
<InputSelect class="form-control" id="CustomerName" #bind-Value="newProject.CustomerID">
#if (customer is null)
{
}
else
{
<option selected disabled value="-1"> Choose a Customer</option>
#foreach (var customer in customers)
{
<option>#customer.CustomerName</option>
}
}
</InputSelect>
#*<ValidationMessage For="(() => newProject.CustomerID)" />*#
</div>
<div class="col-md-5">
<label class="form-label">Location Name</label>
<InputText class="form-control" id="ProjectName" #bind-Value="newProject.ProjectName" placeholder="Location Name" />
<ValidationMessage For="(() => newProject.ProjectName)" />
</div>
</div>
#code from the component
private ProjectsViewModel newProject = new ProjectsViewModel();
private async Task InsertLocation()
{
//assign the new project data to the project model in the back end
ProjectsModel project = new ProjectsModel
{
//TODO: make these match what is in the model and update insert query
ProjectName = newProject.ProjectName,
CustomerID = newProject.CustomerID
};
await projectsData.InsertLocation(project); //send data to db
newProject = new ProjectsViewModel();
projects = await projectsData.ReadProjects();
OpenAddLocationModal = false;
}
And finally sending to the stored procedure from the projectData file.
public async Task InsertLocation(IProjectsModel project)
{
var p = new
{
project.CustomerID,
project.ProjectName
};
await _db.SaveData("dbo.spProject_Create", p, "DefaultConnection");
}
SQL Procedure
#ProjectName nvarchar(255),
#CustomerID int
as
begin
insert into dbo.Projects(CustomerID, ProjectName)
values (#CustomerID, #ProjectName);
end
Thanks for any help.

ASP.NET MVC Repository and Controller Error

I am getting this error message whenever I try to go to my OrderHistory page.
The parameters dictionary contains a null entry for parameter 'Id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult History(Int32)' in 'Mis324Assignments.Controllers.MusicController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
This is my controller:
public ActionResult History(int Id)
{
return View(mor.GetHistory(Id));
}
This is my Repository:
public List<MusicHistoryModel> GetHistory(int custID)
{
using (IDbConnection db = new SqlConnection(connectString))
{
string sql = #"SELECT OI.OrderId, OI.ASIN, OI.Qty, OI.Title, OI.Artist, OI.Price, O.OrderDate
FROM tblOrders as O join tblOrderItems as OI on O.OrderId = OI.OrderId
Where O.CustId = #custID";
List<MusicHistoryModel> history = db.Query<MusicHistoryModel>(sql,new { custID }).ToList();
return history;
}
}
This is my View:
#model IEnumerable<Mis324Assignments.Models.MusicHistoryModel>
#{
ViewBag.Title = "History";
Layout = "~/Views/Music/_3ColLayout.cshtml";
}
<h2>Order History</h2>
#foreach (var item in Model)
{
<div class="row" style="padding:4px;">
<div class="col-md-2">
<img src="http://images.amazon.com/images//P#(item.ASIN).01._SCTHUMBZZZ_V1115763748_.jpg"
class='productImage' style="margin:0 0 5px 10px;" />
</div>
#item.OrderID
#item.OrderDate
#item.title
#item.artist
#item.price
#item.qty
</div>
}
This is my ActionLink that redirects to the History View:
<form action="~/Music/History" method="post" class="enhancement">
<input type="submit" value="Order History*" /><br />
</form>
I am passing in an int id in my controller and it is using that int id as the custID to get information from my repository. I dont know why the error message is saying I am not passing anything into the int id parameter
When looking at your view implementation, it seems that you are not passing id in the History action which is needed by your History Action.
You can pass id as your parameter in following way :
#using(Html.BeginForm("History", "Music",
new { Id= your_id_should_be_here }, FormMethod.Post, new{ #class="enhancement"})
{
<input type="submit" value="Order History*" /><br />
}
Answer submitted already put it as comment not as answer.
I figured it out!!! ON my Action link I did not pass in the CustID parameter. That is why it did not get any id parameters!

Passing selected button value from view to controller

I would like to pass the selected button value to the controller. See my code below.
In my controller I am passing through the ProductId which I will then use to set up my product value inside my controller.
Controller:
public ActionResult PlaceOrder(int ProductId, string OrderType)
{
// Do something
}
Inside my view I have a foreach loop which will create radio like buttons and I have also got a hiddenfor(SelectedProductId)
View:
<div class="panel panel-primary">
<div class="panel-heading">Panel Name</div>
<div class="panel-body">
<div class="row">
<div class="form-group">
#Html.HiddenFor(m => m.SelectedProductId)
#if (Model.Products != null && Model.Products.Count > 0)
{
<div class="btn-group" data-toggle="buttons">
#foreach (var product in Model.Products)
{
<label class="btn btn-default productButton">
<div class="labelProduct">#Product.Name</div>
<input type="radio" name="ProductGMX" id="#("product" + #product.Id)" autocomplete="off" checked data-id="#product.Id">
</label>
}
</div>
I will want to pass the Product Id in the ActionLink which will then pass it to the controller but I am not sure how this can be achieved
Button Click:
#Html.ActionLink("Order with standard delivery", "PlaceOrder", "Standard", new { ProductId = ?, OrderType = "Standard delivery" }, new { area = "Standard" })
#Html.ActionLink("Order with Next day Delivery", "PlaceOrder", "Elevated", new { ProductId = ?, OrderType = "NextDay" }, new { area = "Elevated", })
You either need to use JavaScript to update the ActionLink's url whenever the product changes, using the data-id from the radio button.
Or
Use submit buttons instead of ActionLinks, and set the value on the radio button to the product id. You'll need to put some logic in your controller to handle the two different buttons.
Those aren't buttons. They're links, which don't participate in the form submission.
Use real buttons, i.e. <button></button> and give them a name. Then you can see which was clicked by inspecting the Request object:
<button name="_StandardDelivery">Order with standard delivery</button>
Then in your action:
if (Request["_StandardDelivery"] != null) {
// user chose standard delivery
}

I want to show error message when textbox is null in mvc3

I have a control input type is text that will accept id which will enter by user. When user doesn't enter any id and when he will click on button for getting details I have to show message that "please enter id in textbox". All these things has beeen design in mvc3. Now please help to us that how we will do it ? I am new on mvc3.
Update
This is my HTML Code:
<div class="centerize">
<input type="text" name="entryid" value="" placeholder="Enter valid id" style="height:30px; text-align: center"/>
</div>
<div class="centerize" style="height:20px"></div>
<div class="centerize">
<input type="submit" value="Submit" style="height: 30px; width: 100px"/>
</div>
<div class="centerize">
#Html.ValidationSummary()
</div>
if you do want to use Javascript validation:
#Html.TextBoxFor(m=>m.userid,new {id="userid"})
JS:
$(#submit).click(function()
{
var data=$("#userid").val();
if(data.length==0)
{
alert("Please enter user id");
return false;
}
});
If you want to use data annotations for your model for validation just use [Required] attribute for your
field userid
If you wanna do it on server side, add a Required data Annotation to the field:
[Required]
public string UserId{get;set;}
And, if you wanna do it on client-side, use this script;
<script>
$('input:submit').click(function()
{
var $entryId=$('input[name="entryid"]').val();
if($entryId.trim()=="")
{
alert("Entry Id is required!");
return false;
}
});
</script>

Form Collection issue

I have an html begin form in mvc
#using (Html.BeginForm("Search", "Reports",FormMethod.Post, new { enctype = "multipart/form-data", #class = "form-inline" }))
{
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="Value" name="SearchValue">
<input type="text" class="form-control input-sm second-value" placeholder="Value" style="display:none;" name="SearchValue1">
<button type="button" class="btn btn-default btn-Add">+</button>
</div>
<div id="othersearch"></div>
<input type="submit" value="Search" class="btn btn-primary" />
}
I want to post this form item in one controller
public ActionResult Search(FormCollection collection)
{
string searchvalue = collection.Get("SearchValue");
return View();
}
my problem is that some times second text box is not visible.. that time i dont want to collect the values.And when i press button add generate the same type of input field in the form with same name (i can add many input box). Then how can i collect all these in my controller . please help me..
You can have all the text boxes with same name "SeachValue" in your case.
string searchvalue = collection.Get("SearchValue");
This will return all text box values as comma saperated string which you can split and use further.
Check out the screen shot
the html
and the results
You can get value of all textboxes having same name using following code:
var results = ((String[])formcollection.GetValue("mytxt").RawValue).ToList();
foreach (var item in results)
{
//string name = item;
}
When ever you add a element dynamically make sure you also set it a name. so when you add a new input element it must be
<input type="text" name="NewTextBox" class="form-control input-sm" placeholder="Value" name="searchvalue">
So like this no matter how many text boxes you add, All will have same name. Once you post the form. In your controller do this.
[HTTPPOST]
public ActionResult Search(MyModel newModel,string[] NewTextBox)
{
// here as you had dynamic textbox with name = NewTextBox you
//will get all its value binded to the above string[]
}
OR
You can retrive them using Request.form["NewTextBox"] as
[HTTPPOST]
public ActionResult Search(MyModel newModel)
{
var values = Request.Form[NewTextBox];
}
But I would recommend you the first approach where you use the MVC Model Binder to take care of all the things. You will just have array of values to play with.
NOTE: Always make sure you get the names right, and use the name right while playing with MVC. As all the binding depends on the naming itself.

Categories

Resources