asp-action renders action="" instead of the correct URL - c#

I have a method in my controller called "NewJobApp" that works fine and returns the view with "NewJobApp" model.
[AllowAnonymous]
[HttpGet("Consultant/NewJobApp/{agencyID:int}/{userID:int}/{companyID:int}/{jobID:int}")]
public async Task<ViewResult> NewJobApp(int agencyID, int userID, int companyID, int jobID)
{
NewJobApp nja = await Repository.GetNewJobApp(agencyID, userID, companyID, jobID);
return View(nja);
}
In the view I have a form that should call "SubmitNewJobApp", but when I view the page source, it shows action=""
<form id="JobAppForm" class="form-group" asp-controller="Consultant" asp-action="SubmitNewJobApp" method="post" style="text-align: left">
#Html.AntiForgeryToken()
<input id="AgencyID" asp-for="#Model.AgencyID" value="#Model.AgencyID" type="hidden" />
<input asp-for="#Model.AgencyName" value="#Model.AgencyName" type="hidden" />
<input asp-for="#Model.UserID" value="#Model.UserID" type="hidden" />
<input asp-for="#Model.CompanyID" value="#Model.CompanyID" type="hidden" />
<input asp-for="#Model.JobID" value="#Model.JobID" type="hidden" />
#if (!String.IsNullOrEmpty(Model.Errs))
{
#Html.Raw(Model.Errs);
}
<p style="margin: 0px; font-size: 8px"> </p>
<div class="form-group">
<label style="width: 120px; text-align: left; display: inline-block;" asp-for="#Model.JobTitle">Job:</label>
<input type="text" asp-for="#Model.JobTitle" value="#Model.JobTitle" readonly />
</div>
<div class="form-group">
<label style="width: 120px; text-align: left; display: inline-block;" asp-for="#Model.CompanyName">Company:</label>
<input type="text" asp-for="#Model.CompanyName" value="#Model.CompanyName" readonly />
</div>
<p style="margin-bottom: 4px;">Enter person search expression:</p>
<input asp-for="#Model.SearchExpression" value="#Model.SearchExpression" style="width: 132px; margin-bottom: 8px;" />
<button id="myButton" class="btn btn-primary" type="submit">Get Candidates</button>
<p style="margin: 0px; font-size: 8px"> </p>
<div class="form-group">
<label style="width: 120px; display: inline-block;" asp-for="ContactID">Contact:</label>
#Html.DropDownListFor(m => m.ContactID, Model.Contacts, "Choose a Contact", new { #class = "myDDL", #id = "contactsDDL" })
</div>
<div class="text-center" style="text-align: right">
<button id="btnSave" class="btn btn-primary" type="submit">Save</button>
</div>
</form>
This is the "SubmitNewJobApp" method in the controller, but it never gets called.
[HttpPost()]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SubmitNewJobApp(NewJobApp nj)
{
int id = 0;
bool is_err = false;
string err = string.Empty;
// check data
if (nj.ContactID == 0)
{
is_err = true;
}
// check model state
if (!ModelState.IsValid || is_err)
{
nj = await Repository.GetNewJobApp(nj);
return View("NewJobApp", nj);
}
nj.NewRecordID = id;
return View("NewJobApp", nj);
}

I still don't understand why this doesn't work, but I have a temporary solution.
If I remove the HttpGet template on the method that returns the "NewJobApp" view, the form action now contains a value, and works!
Previous method:
[AllowAnonymous]
[HttpGet("Consultant/NewJobApp/{agencyID:int}/{userID:int}/{companyID:int}/{jobID:int}")]
public async Task<ViewResult> NewJobApp(int agencyID, int userID, int companyID, int jobID)
{
NewJobApp nja = await Repository.GetNewJobApp(agencyID, userID, companyID, jobID);
return View(nja);
}
Now changed to:
[HttpGet()]
[AllowAnonymous]
public async Task<ViewResult> NewJobApp(int agencyID, int userID, int companyID, int jobID)
{
NewJobApp nja = await Repository.GetNewJobApp(agencyID, userID, companyID, jobID);
return View(nja);
}
This is the changed code that calls the "NewJobApp" controller method:
function startNewApplicant() {
var para1 = #ViewBag.AgencyID;
var para2 = #Model.Job.UserID;
var para3 = #Model.Job.CompanyID;
var para4 = #Model.Job.JobID;
// var url = "NewJobApp/" + para1 + "/" + para2 + "/" + para3 + "/" + para4; (previous)
var url = "NewJobApp?agencyID=" + para1 + "&userID=" + para2 + "&companyID=" + para3 + "&jobID=" + para4;
window.open(url, '_blank');
}
But actually I prefer to use the template because I want the cleaner looking URL.
My Startup routes:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "signin",
template: "{controller=Home}/{action=Index}/{agencyID}/{contactID}");
});

Related

How to pass form text value as a c# parameter on Razor Pages

I have a function that fetch the data based on the user's registration number on the active directory and print it to the textbox fields on the modal. In that case I need to send as a parameter whatever is written in the textbox instead of the field numbered 31919 in the code below.
<center>
<image style="margin-top: 20px; width: 25%;" src="/images/adduser.png"></image>
<div style="margin-top: 25px;">
<form method="post">
<label class="control-label"><b>Reg. No</b></label>
<input type="text" name="RegNo" id="RegNo" value="">
<button onclick="created(1)" style="margin-left: 15px; height: 60%;" data-toggle="modal" data-target="#AddUser1" type="button" class="btn btn-light-primary px-6 font-weight-bold">Fetch</button>
<span id="spin"><i style="position: relative; display: inline-block;" class="fas fa-sync fa-spin"></i></span>
</form>
#{
FetchDataFromAD("31919");
}
<hr />
</div>
</center>
So, basically I'm trying to do something like this:
#{
FetchDataFromAD(RegNo.Text);
}
P.S.: FetchDataFromAD just a function that modifying string expressions like that:
public void FetchDataFromAD(string RegNo)
{
System.DirectoryServices.DirectorySearcher search = new System.DirectoryServices.DirectorySearcher(directoryEntry);
search.Filter = "(postalCode=" + RegNo + ")";
foreach (System.DirectoryServices.SearchResult sResultSet in search.FindAll())
{
// Ad
FetchADPersonelName = GetProperty(sResultSet, "cn");
FetchADTitle = GetProperty(sResultSet, "title");
FetchADNetworkN = GetProperty(sResultSet, "samaccountname");
FetchADEmail = GetProperty(sResultSet, "mail");
FetchADAdress = "2";
// FetchADDepartman = GetProperty(sResultSet, "department");
}
}
How can I achieve that? Thank you for any suggestions.
Consider to use the following:
<script>
function ApplyFilter() {
var regno = document.getElementById("RegNo").value;
$.ajax({
type: "GET",
url: '#Url.Action("FetchDataFromAD", "Home")',
contentType: "application/json;charset=utf-8",
data: { regno },
dataType: "json",
success: function (data) {
}
});
};
</script>
<div style="margin-top: 25px;">
<form method="post">
<label class="control-label"><b>Reg. No</b></label>
<input type="text" name="RegNo" id="RegNo" value="">
<button onclick="ApplyFilter()" style="margin-left: 15px; height: 60%;" data-toggle="modal" data-target="#AddUser1" type="button" class="btn btn-light-primary px-6 font-weight-bold">Fetch</button>
<span id="spin"><i style="position: relative; display: inline-block;" class="fas fa-sync fa-spin"></i></span>
</form>
<hr />
</div>
And the FetchDataFromAD() method signature update to be called from JavaScript:
public JsonResult FetchDataFromAD(string RegNo)
{
... your code here
return Json("Filter is applied", JsonRequestBehavior.AllowGet);
}

C# MVC Adding a record to a table with form and parameters

I am having an issue with my add to a database record.
What I am attempting to do is add a record with parameters sent from a form. I am grabbing an item from a table giving a quantity and them adding it to an orders table.
I am adding it to the OrderDetails table so I need the orderId. Which I grab from the Url.
Below is my code, It is not working. It could probably be simplified but I am not sure where to modify this.
Form on Page:
#{ var OrderId = Request.Url.Segments[3];}
<td>
<form method="GET" action="~/OrderManager/AddToOrder/#OrderId" _lpchecked="1">
<div class="row ">
<div class="input-group mb-3 col-xs-6 col-md-6">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Qty</span>
</div>
<input style="max-width:75px;" aria-label="Qty" aria-describedby="inputGroup-sizing-default" type="number" class="form-control" id="quantity" min="1" name="quantity">
</div>
<div class="col-xs-6 col-md-6">
<button class="btn btn-primary btn-sm" type="submit" id="submit" onchange="usercheck">Add To Order</button>
</div>
</div>
</form>
</td>
Here is my Controller actions:
public ActionResult Add(int id)
{
try
{
GeneralEntities db = new GeneralEntities();
var result = db.Extras.ToList().OrderByDescending(x => x.CreatedDate);
return View(result);
}
catch (Exception ex)
{
throw ex;
}
}
public ActionResult AddToOrder(int OrderId, string id, int quantity)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
try
{
GeneralEntities ExtrasDb = new GeneralEntities();
var addedExtra = ExtrasDb.Extras
.Single(ext => ext.ExtrasName == id);
var extra = new OrderDetail
{
OrderId = OrderId,
Extras = addedExtra.BillingExtrasId,
Quantity = quantity,
CreatedDate = DateTime.Now
};
ExtrasDb.OrderDetails.Add(extra);
sb.Append("Sumitted");
return Content(sb.ToString());
}
catch (Exception ex)
{
sb.Append("Error :" + ex.Message);
}
return Content(sb.ToString());
}
Thanks for your help!
Revised Code Update:
I changed some things. I seem to have what i need now and it says it submits but it does not save it to the table..
Revised form:
#{ var OrderId = Request.Url.Segments[3];}
<td>
<form method="POST" action="~/OrdersManager/Add/" _lpchecked="1">
<div class="row ">
<div class="input-group mb-3 col-xs-6 col-md-6">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">Qty</span>
</div>
<input data-val="true" id="OrderId" name="OrderId" type="hidden" value="#OrderId" />
<input data-val="true" id="id" name="id" type="hidden" value="#item.BillingExtrasId" />
<input style="max-width:75px;" aria-label="Qty" aria-describedby="inputGroup-sizing-default" type="number" class="form-control" id="quantity" min="1" name="quantity">
</div>
<div class="col-xs-6 col-md-6">
<button class="btn btn-primary btn-sm" type="submit" id="submit" onchange="usercheck">Add To Order</button>
</div>
</div>
</form>
</td>
Revised Controller Code:
[HttpPost]
public ActionResult Add(int OrderId, Guid id, int quantity)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
try
{
GeneralEntities ExtrasDb = new GeneralEntities();
// Retrieve the album from the database
var addedExtra = ExtrasDb.Extras
.Single(ext => ext.BillingExtrasId == id);
var extra = new OrderDetail
{
OrderId = OrderId,
Extras = addedExtra.BillingExtrasId,
UnitPrice = addedExtra.Price,
Quantity = quantity,
CreatedDate = DateTime.Now
};
ExtrasDb.OrderDetails.Add(extra);
sb.Append("Sumitted");
return Content(sb.ToString());
}
catch (Exception ex)
{
sb.Append("Error :" + ex.Message);
}
return Content(sb.ToString());
}
Add
ExtrasDb.SaveChanges();
right before the first return statement inside of the try block.
(You found the mistake and mentioned it in your comment. I'm just confirming and turning it into an answer.)

Comment boxes only post with first post in MVC

I have a view in my MVC application that is designed to show views and comments gathered from a database, and allow users to make posts and comments accordingly.
The relevant section of Html is below:
<div style="background-color:#fff1fc; height:100vh; width:810px; float:left; border-radius: 8px; margin: 5px">
<div>
<p>
<center>
#foreach (var item in Model.PostList)
{
<div style="background-color: white; height:auto; width: 810px; border-radius: 8px; margin: 5px; text-align: left; text-size-adjust: 50%; text-anchor:start; font-size: larger">
#Html.DisplayFor(modelItem => item.Profile.FirstName)
#Html.DisplayFor(modelItem => item.Profile.LastName)
#Html.DisplayFor(modelItem => item.Project.ProjectName)<br/>
<div style="text-align:center; text-size-adjust: auto">
#Html.DisplayFor(modelItem => item.Text)<br/>
</div>
<div style="text-align: right; text-size-adjust: 20%; text-anchor: end">
#Html.DisplayFor(modelItem => item.DATE)
</div>
<hr />
<div style="line-break:initial; font-size:small; text-align: left; margin: 10px; padding: 10px">
#Html.Label("Comments:")<br/>
<br/>
#foreach (var comment in Model.CommentList)
{
if (comment.PostId == item.Id)
{
#Html.DisplayFor(modelComment => comment.Profile.FirstName)
#Html.DisplayFor(modelComment => comment.Profile.LastName)
<br/>
<center>
#Html.DisplayFor(modelComment => comment.Comment1)
<hr />
<br/>
</center>
}
}
<center>
#Html.TextAreaFor(model => Model.Comment, new { #class = "height: 200px, width: 600px"})
<br />
<br />
<right>
<input type="submit" value="Comment" class="btn btn-default" />
<input type="hidden" name="PostId" value="#item.Id" />
<input type="hidden" name="ProfileId" value="#Model.ProfileList[0].Id" />
</right>
<br />
</center>
</div>
</div>
}
</center>
</p>
</div>
</div>
So, for each item in PostList, the relevant attributes of that list are displayed. With these posts, each item from the CommentList that references this post is also displayed, with a TextBox to make a new comment. This all works fine! The problem appears to be here:
<center>
#Html.TextAreaFor(model => Model.Comment, new { #class = "height: 200px, width: 600px"})
<br />
<br />
<right>
<input type="submit" value="Comment" class="btn btn-default" />
<input type="hidden" name="PostId" value="#item.Id" />
<input type="hidden" name="ProfileId" value="#Model.ProfileList[0].Id" />
</right>
<br />
</center>
For some reason, when I attempt to make a comment on my platform, it only works if commenting on the most recent/first post on the feed (The first item). Attempting to make a comment on anything other than the first item, does nothing. Here is the Post method of my controller:
public ActionResult Post(string Text, int Id, string Comment, int ProfileId, int PostId)
{
if (Text != "")
{
using (var ctx = new SocialDBEntities())
{
string userId = User.Identity.GetUserId();
Post post = new CrowdSocial2.Post();
post.ProfileId = Id;
post.DATE = System.DateTime.Now.Date;
post.Text = Text;
db.Posts.Add(post);
db.SaveChanges();
return RedirectToAction("Feed");
}
}
else if (Comment != "")
{
string userId = User.Identity.GetUserId();
Comment comment = new CrowdSocial2.Comment();
comment.PostId = PostId;
comment.ProfileId = ProfileId;
comment.Comment1 = Comment;
comment.Date = System.DateTime.Now.Date;
db.Comments.Add(comment);
db.SaveChanges();
return RedirectToAction("Feed");
}
else
{
return RedirectToAction("Feed");
}
}
The controller is passed Comment, and determines whether or not it is "null". If not, it will post the comment to the database with the accompanying postId and profileId. Since this wasn't working, I decided to put a breakpoint on the RedirectToAction both inside of the if(Comment != "") statement, and in the elseif statement to see what was happening.
Turns out, Comment for some reason is being passed as "" regardless of what was written in the comment box, the controller is seeing it as "" and hence just redirects back to the view. This makes me suspect that what is happening is that Comment is being passed from the very first comment box, which is empty.
Any ideas how I can fix this so that I can comment on any of the post items?

MVC loop in database table

I have a form with some textboxfors.
one of the textbox is for a barcode.
Now when i give in that field a barcode and i click on make a order.
Then i want loop in the database for comparing the barcode with the correct article.
I have try with a foreach loop for loop and while loop but get Always a nullreferenceexception.
How can i loop in the database table for compare a textboxfor field with the database field ?
view
#model ReservatieMVC.ViewModels.AddtocartSubmit
#using EindwerkDatabase.lib.Models
<style>
#qtyTextbox {
width: 50px;
height: 35px;
bottom: 10px;
}
.submitCart {
float: right;
background-color: lightgray;
}
</style>
<div id="quantity">
#Html.Hidden("artikelId", ViewData["artikel"])
</div>
<div>#ViewBag.ArtikelId</div>
#{Html.BeginForm("Addtocart", "Artikels");}
<script>
$( document ).ready(function() {
.test = #Model.artikelId;
})
</script>
<div>
#Html.HiddenFor(m => m.artikelId, new { #class = "logger" })
<b>Barcode Student #Html.TextBoxFor(m => m.StudentBarCode)</b>
<b>Start UileenDatum: #Html.TextBoxFor(m => m.startdatum, new { id = "datepicker" }) #*<input type="text" id="datepicker" style="width:150px"*# </b>
<br /> <br />
<b>Teruggave: #Html.TextBoxFor(m => m.einddatum, new { id = "datepicker2" }) #*<input type="text" id="datepicker2" style="width:150px"*# </b>
</div>
<input class="submitCart" type="submit" value="Voeg toe">
#{Html.EndForm();}
controller
[HttpPost]
public ActionResult Addtocart(AddtocartSubmit model,Reservatie res)
{
Reservatie re = new Reservatie();
if (ModelState.IsValid)
{
while(model.StudentBarCode == res.Gebruiker.StudentBarCode)
{
break;
}
re.ArtikelId = model.artikelId;
//re.ArtikelId = model.artikelId;
string datumstart = model.startdatum;
string datumeind = model.einddatum;
re.startdatum = Convert.ToDateTime(datumstart);
re.einddatum = Convert.ToDateTime(datumeind);
re.GebruikerId = 3;
re.Datum = DateTime.Today;
r.Reservatie.Add(re);
r.SaveChanges();
return RedirectToAction("Index");
}
return PartialView();
}

Apply validation on textboxes in MVC using jQuery

I have a contact page in mvc . I have a 4 text box in this page and
one text area and i want to give validation using jquery the
text-box id is txtbxName, txtbxCompany, txtbxEmail, txtbxPhone ,and
txtarMessage. when user click on submit button if txtbxName is blank.
i want a message something like this "Please enter your Name!" and so
on. please help me thanks
ContactController.cs
public ViewResult Create(string Name, string Company, string Regarding, string Email, string Phone, string Message)
{
string body = "Name: " + Name + "<br>" + "\nCompany: " + Company + "<br>" + "Regarding: " + Regarding + "<br>" + "Email: " +
Email + "<br>" + "Phone: " + Phone + "<br>" + "Message: " + Message;
try
{ MailMessage mail = new MailMessage(); mail.From = new MailAddress("g#technosys.com");
mail.To.Add("p#technosys.com");
mail.Subject = "Accept Request";
mail.Body = body;
mail.IsBodyHtml = true; SmtpClient smtp = new SmtpClient("smtp.gmail.com");
smtp.Credentials = new System.Net.NetworkCredential("g#technosys.com", "1457898");
smtp.EnableSsl = true;
// smtp.UseDefaultCredentials = true;
smtp.Send(mail);
}
catch (Exception ex)
{
ViewData.ModelState.AddModelError("_FORM", ex.ToString());
}
return View();
Jquery
$("#btnSubmit").click(function (event) {
var data = { Name: $("#txtbxName").val(), Company: $("#txtbxCompany").val(), Regarding:
$("#ddlRegarding").val(), Email: $("#txtbxEmail").val(), Phone: $("#txtbxPhone").val(), Message:
$("#txtarMessage").val()
}
$.ajax({
type: "POST",
url: "/Contact/Create", // the method we are calling
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
dataType: "html",
success: function (result) {
$("#txtbxName").val("");
$("#txtbxCompany").val("");
$("#txtbxEmail").val("");
$("#txtbxPhone").val("");
$("#txtarMessage").val("");
alert(result);
// Or if you are returning something
alert('I returned... ' + result.WhateverIsReturning);
},
error: function (result) {
$("#txtbxName").val("");
$("#txtbxCompany").val("");
$("#txtbxEmail").val("");
$("#txtbxPhone").val("");
$("#txtarMessage").val("");
alert('Thanks for sending info');
return false;
}
});
});
Index .cshtml
<div class="parteners">
<div class="block" style="width: 270px;">
<div class="block" style="width: 295px; padding: 3px;">
Name :
</div>
<div class="block" style="width: 320px; padding: 3px;">
<input type="text" class="textbox" name="textfield" alt="Type our Name here" />> <br />
</div>
<div class="block" style="width: 295px; padding: 3px;">
Company :
</div>
<div class="block" style="width: 295px; padding: 3px;">
<input type="text" class="textbox" name="textfield2" />
</div>
<div class="block" style="width: 295px; padding: 3px;">
Regarding :
</div>
<div class="block" style="width: 295px; padding: 3px;">
<select name="select" class="textbox">
<option>General Inquiry</option>
<option>Programming Related Question</option>
<option>Website Quote Request</option>
<option>Feedback</option>
<option>Help and Support</option>
</select>
</div>
</div>
<div class="block" style="width: 270px;">
<div class="block" style="width: 295px; padding: 3px;">
Email :</div>
<div class="block" style="width: 295px; padding: 3px;">
<input type="text" class="textbox" name="textfield3" />
</div>
<div class="block" style="width: 295px; padding: 3px;">
Phone :
</div>
<div class="block" style="width: 295px; padding: 3px;">
<input type="text" class="textbox" name="textfield4" />
</div>
</div>
<div class="block" style="width: 600px; padding: 3px;">
Enter your Suggestions / Comments / Feedback here :
</div>
<br />
<div class="block" style="width: 600px; padding: 3px;">
<textarea class="textarea" name="textarea"></textarea><br />
<br />
</div>
<div class="block" style="width: 600px; padding: 3px;">
<input id="Button1" type="Button" value="Submit" />
</div>
</div>
Set class to all the textboxes like below
<input type="text" class="valcheck" title="Name" id="your_name_field_id" name="your_name_field_name" />
do the same for all the 6 textboxes.
$("#btnSubmit").click(function (event) {
$(".valcheck").each(function(){
var id = this.id;
var field_value = $("#"+id).val();
if(field_value=="")
{
var field_name = $("#"+id).attr('title');
$("#error_display_div").append("Please enter "+field_name+"<br />");
}
//Show hide error_display_div accordingly, you can clear out the div using
// $("#error_display_div").html('');
});
});
You should look into the jQuery validation plugin: http://bassistance.de/jquery-plugins/jquery-plugin-validation/
You should consider using a ViewModel like this:
public class MessageVM
{
public string CompanyName {get;set;}
[Required]
public string Name {get;set;}
public string Regarding {get;set;}
public string Message {get;set;}
[Required]
public string Email {get;set;}
}
Which uses DataAnnotations. You use this in your view to bind to like so:
#Model Your.Namespace.ViewModels.MessageVM
#using(Html.BeingForm("create"))
{
#Html.LabelFor(x => x.Name)
#Html.TextBoxFor(x => x.Name)
#Html.LabelFor(x => x.CompanyName)
#Html.TextBoxFor(x => x.CompanyName)
#Html.LabelFor(x => x.Regarding)
#Html.TextBoxFor(x => x.Regarding)
#Html.LabelFor(x => x.Email)
#Html.TextBoxFor(x => x.Email)
#Html.LabelFor(x => x.Message)
#Html.TextBoxFor(x => x.Message)
<button type="submit">Send!</button>
}
And then you can set up a method on your controller something like the below
public ActionResult Create(MessageVM message)
{
if (!ModelState.IsValid)
{
return View(message);
}
//else do whatever you need, send the email etc.
}
Bit more here

Categories