Replace a PartialView with another one (ASP NET CORE MVC) - c#

I'm using ASP NET CORE MVC 5.
I have a View ("ChooseServices") which, depending on the parameter passed, displays 1 or N PartialViews (Forms):
ChooseServices.cshtml:
<div class="col">
#if (Model.OfferServiceA)
{
<partial name="_FormA" />
}
#if (Model.OfferServiceB)
{
<partial name="_FormB" />
}
#if (Model.OfferServiceC)
{
<partial name="_FormC" />
}
</div>
After answering each Form individually, I want to display a default message which is another PartialView ("_confirmation.cshtml") in place of the Form.
Something like this:
(after submit Form-A)
(and after submit Form-C)
In summary, after submitting a Form (partial view), I want it be replaced by another PartialViews, all inside the View "ChooseServices".
[EDIT - Some code]
CONTROLLER:
public class SomeServiceController : Controller
{
// A survey brings to here.
public IActionResult ChooseServices(SuggestedServicesDTO dto)
{
return View(dto);
}
}
VIEWS (ignoring css)
ChooseServices.cshtml
#model SuggestedServicesDTO
<section >
<div class="container">
<div class="row">
<div class="col">
#if (Model.OfferServiceA)
{
<partial name="_FormA" />
}
#if (Model.OfferServiceB)
{
<partial name="_FormB" />
}
#if (Model.OfferServiceC)
{
<partial name="_FormC" />
}
</div>
</div>
</div>
</section>
_Form{x}.cshtml
{x} is the service name.
<div class="card">
<div class="card-body">
<h3>THIS IS THE FORM-{x}.</h3>
<form asp-action="??IDK what put here">
<div>
<label>Select an option:</label>
<!-- Radio buttons Begin -->
<div>
<label for="service{x}Opt{N}">
<input type="radio" name="optionsService{x}" id="service{x}Opt{N}" value="someValue1">
<span>Option QWERTY</span>
</label>
</div>
<div>
<label for="service{x}Opt{N}">
<input type="radio" name="optionsService{x}" id="service{x}Opt{N}" value="someValue2">
<span>Option ASDFGH</span>
</label>
</div>
<!-- others options here -->
<!-- Radio buttons end-->
</div>
<div>
<input type="submit" value="Submit {x}"/>
</div>
</form>
</div>
</div>
_Confirmation.cshtml
(Just a message, nothing important)
<div class="card">
<div class="card-body">
<div>
<h3>Thanks for answering!</h3>
<p>bla bla bla bla</p>
<button type="button" onclick="window.open('someurl', '_blank').focus();">
Do something...
</button>
</div>
</div>
</div>
I don't know what to do after submit de Forms{x}.

Related

Data annotation validation happening on page load in ASP.Net Core

I am facing the issue of data validation being executed on load of a new page even though it is clearly coming from a Get method. Is there something that's triggering the validations on page load?
I have a button on a view to add a new Student record in the new screen :
View :
<a type="button" id="btnAddStudent" href='#Url.Action("Details","Student")' class="btn btn-tertiary" title="Add Student">Add Student</a>
The controller code for the Details action method in Student Controller is as follows.
[HttpGet]
public ActionResult Details(StudentInfo model)
{
//This is populating the model parameters as expected.
helper.StudentInfo(ref model);
return View(model);
}
The view for the Details screen is as follows. The page loads but is throwing validation errors even though it's a Get method.
<form id="frmSubmit" asp-action="Details" asp-controller="Student" method="post">
<input type="hidden" asp-for="StudentId" />
<div class="row">
<div class="col-xs-12">
#Html.ValidationSummary("", new { #class = "alert alert-danger validation" })
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label asp-for="Name">*StudentName</label><br />
<input asp-for="Name" class="form-control" maxlength="100" placeholder="Enter student name..." />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label asp-for="AddressLine1"></label><br />
<input asp-for="AddressLine1" class="form-control" placeholder="Enter address..." />
<span asp-validation-for="AddressLine1" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label asp-for="AddressLine2"></label><br />
<input asp-for="AddressLine2" class="form-control" maxlength="100" />
<span asp-validation-for="AddressLine2" class="text-danger"></span>
</div>
</div>
</div>
<div class="box">
<div class="form-group pull-right">
<button type="submit" class="btn btn-primary" value="save"> Save</button>
</div>
</div>
Is there something I am doing wrong? I have verified that the debug control goes to the Get method.There's alos no on load scripts which are doing any sort of validation.
1.Your get method contains the model parameter, when the request hit the method it will judge the ModelState by default. And when you hit the get method by your shared <a>, it send request without any data, so the ModelState is invalid.
2.Default Tag helper displays ModelState's value not Model.
In conclusion, you will render the ModelState error although it is a get method.
Two ways you can resolve this problem. The first way is that you can add ModelState.Clear() before you return View:
public ActionResult Details(StudentInfo model)
{
ModelState.Clear(); //add this....
helper.StudentInfo(ref model);
return View(model);
}
The second way is do not add the model as parameter:
public ActionResult Details()
{
var model = new StudentInfo();
helper.StudentInfo(ref model);
return View(model);
}

HttpPost Model ID is always 0

I have an Update page getting a ViewModel containing my Model. When I load it to the page everything works fine but when I submit the changes my Model's ID is ALWAYS 0, I mean LITTERALY ALWAYS. I am following a tutorial, I did exactly what he did and STILL 0.
This is my POST method where I'm passing the VM in parameter.
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(ExpenseVM obj)
{
if (ModelState.IsValid)
{
_db.Expenses.Update(obj.Expense);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(obj);
}
And here is my HTML/C# code for the ID
<input type="hidden" asp-for="Expense.Id" value="#Model.Expense.Id" name="Id"/>
When I load my page my ID is loaded and everything works fine.
During debugging this is what I have in my HTML :
<input type="hidden" value="1" name="Id" data-val="true" data-val-required="The Id field is required." id="Expense_Id">
I found out why it didn't work.
My HTML was like this
<form method="post" asp-action="Update">
<div class="border p-3">
<div class="form-group row">
<h2 class="text-black-50 pl-3">Update Expense</h2>
</div>
<div class="row">
<input type="hidden" asp-for="Expense.Id" value="#Model.Expense.Id" name="Id"/>
<div class="col-12">
... BLABLABLA
</div>
</div>
</div>
</form>
So I just moved the input line from inside <div class="row> to <form method="post" asp-action"Update"> and removed all these useless tags like name="Id" value="#Model.Expense.Id" type="hidden"
And now it looks just like this
<form method="post" asp-action="Update">
<input asp-for="Expense.Id" hidden/>
<div class="border p-3">
<div class="form-group row">
<h2 class="text-black-50 pl-3">Update Expense</h2>
</div>
<div class="row">
<div class="col-12">
... BLABLABLA
</div>
</div>
</div>
</form>
And it works fine.
Now please DO NOT ask me why because I don't know, but if ANYONE has the answer to WHY? I'm all ears.

C# Razor pages Partial View Model is null on submit

I am new to Razor pages and trying to create a page with a partial view. The partial view has a dropdownlist and a text input for Quantity field and a submit button. The Partial View renders correctly but when I click on the Submit button the Model passed to the Code behind has no value.
Here is the code I have
_PartialAddons.cshtml
#*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*#
#{
}
#model Public.Areas.Register.AddonListDto
<form method="post">
#Html.HiddenFor(Model => Model.Quantity)
<div style="padding:5px;">
<b>NZD $45</b>
</div>
<div>
<div style="padding:5px;">
<select id="skuSelect" asp-for="SelectedSkus" asp-items="#(new SelectList(Model.AddonSkus,"SkuId","SkuName"))" class="form-control">
<option>Please select one</option>
</select>
</div>
<div style="padding:5px;">
<input type="hidden" name="handler" value="Quantity" />
<input asp-for="Quantity" name="Quantity" class="form-control ng-untouched ng-pristine ng-valid" max="999" min="0" style="width:150px;" type="number" value="0" id="#Model.Id">
</div>
</div>
<div style="padding:5px;">
<a class="btn green" asp-page-handler="AddToCart">Add to Cart</a>
</div>
</form>
This is the Main Page
#foreach (var addons in Model.StoreAddonList)
{
<div class="panel card panel-default" style="margin-top:10px;">
<div class="panel-heading card-header" role="tab">
<div class="panel-title">
<div class="accordion-toggle" role="button" aria-expanded="true">
<div accordion-heading="" style="width:100%;">
#addons.Title
<i class="pull-right float-xs-right glyphicon glyphicon-chevron-down"></i>
</div>
</div>
</div>
</div>
<div class="panel-collapse collapse in show" role="tabpanel" style="overflow: visible; height: auto; display: block;" aria-expanded="true" aria-hidden="false">
<div class="panel-body card-block card-body">
<div style="padding-top:10px;background-color:#ffffff;clear:both;">
<div style="width:100%">
<div style="float:left;width:20%;text-align:left;">
Name
</div>
<div style="float:left;width:30%;padding-left:10px;">
#addons.Description
</div>
</div>
<div style="float:left;width:40%;padding-left:10px;">
<div>
#{
await Html.RenderPartialAsync("_PartialAddons.cshtml", addons);
}
</div>
</div>
<div style="clear:both;">
</div>
</div>
</div>
</div>
</div>
}
This is the Index.cshtml.cs to handle the submit
public ActionResult OnGetAddToCart(AddonListDto addOnList)
{
var sass = Quantity;
var tass = SelectedSkus;
return null;
}
The AddonListDto is null on the OnGetAddToCart Method. Have been trying to get this working for the past two days. Any help would be greatly appriciated
If you want to submit your data, you need to use OnPost instead of OnGet in razor pages and set the handler name in the <form> tag. For example:
handler:
public ActionResult OnPostAddToCart(AddonListDto addOnList)
partial view:
#model Public.Areas.Register.AddonListDto
<form method="post" asp-page-handler="AddToCart">
#Html.HiddenFor(Model => Model.Quantity)
<div style="padding:5px;">
<b>NZD $45</b>
</div>
<div>
<div style="padding:5px;">
<select id="skuSelect" asp-for="SelectedSkus" asp-items="#(new SelectList(Model.AddonSkus,"SkuId","SkuName"))" class="form-control">
<option>Please select one</option>
</select>
</div>
<div style="padding:5px;">
<input type="hidden" name="handler" value="Quantity" />
<input asp-for="Quantity" name="Quantity" class="form-control ng-untouched ng-pristine ng-valid" max="999" min="0" style="width:150px;" type="number" value="0" id="#Model.Id">
</div>
</div>
<div style="padding:5px;">
<input type="submit" value="Add To Cart" class="btn btn-primary" />
</div>
</form>

ReactJS.Net Server Side Rendering Not Initializing Handlers

New to reactjs.net. I did my best to follow the instructions on the https://reactjs.net/guides/server-side-rendering.html website but i am still getting the following reference error re: my component: Signup is not defined. The page renders but the Signup component doesnt seem to be there. What am I doing wrong?
ReactConfig.cs:
public static void Configure()
{
ReactSiteConfiguration.Configuration
.AddScript("~/Scripts/jsx/welcome.jsx")
.AddScript("~/Scripts/jsx/navbar.jsx")
.AddScript("~/Scripts/jsx/login.jsx")
.AddScript("~/Scripts/jsx/Signup.jsx")
.AddScript("~/Scripts/jsx/about.jsx")
.AddScript("~/Scripts/jsx/contact.jsx");
}
SignUp.cshtml:
#{
ViewBag.Title = "Sign Up";
}
#Html.React("Signup", new { })
#section scripts{
#Scripts.Render("~/bundleSignUp")
#Html.ReactInitJavaScript()
}
class Signup extends React.Component {
constructor(props) {
super(props);
this._onSubmit = this._onSubmit.bind(this);
}
_onSubmit(e) {
console.log("HERE WE GO");
}
render() {
return (
<div>
<NavBar />
<form className="container container-fluid">
<div className="pullDown">
<div className="row">
<div className="col-lg-6 col-md-7 col-sm-8">
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input type="email" className="form-control" id="exampleInputEmail1" placeholder="Enter email" ref="email" />
</div>
</div>
</div>
<div className="row">
<div className="col-lg-6 col-md-7 col-sm-8">
<div className="form-group">
<label htmlFor="exampleInputPassword1">Password</label>
<input type="password" className="form-control" id="exampleInputPassword1" placeholder="Enter Password" ref="passWd" />
</div>
</div>
</div>
<div className="row">
<div className="btn btn-success" onClick={this._onSubmit}>Submit</div>
</div>
</div>
</form>
</div>
);
}
}

Mail sending using Razor form

I have a form in my razor cshtml file. I need to send a mail on button click. How can we write the code in the same razor file?
For now my code checks the IsPost property and shows a javascript alert if true, but the alert is not showing. How can we get the values by clicking the submit button?
#inherits RazorFunction
#using System;
#{
if (IsPost)
{
<script>
alert('aaaa');
</script>
}
}
#{
<form method="post">
<div class="form_main">
<div class="col-md-6">
<input type="text" id="txtName" name="yourname" placeholder="الإسم" />
</div>
<div class="col-md-6">
<input type="text" id="txtEmail" placeholder="لبريد الإلكتروني" />
<div class="col-md-6">
<input type="text" id="txtPhone" placeholder="رقم الهاتف" />
</div>
<div class="col-md-6">
<input type="text" id="txtSubject" placeholder="الموضوع" />
</div>
<div class="col-md-12">
<input type="text" id="txtMsg" placeholder="تعليق" textmode="MultiLine" />
</div>
<div class="col-md-12">
<input type="button" id="btnSubmit" value="Submit" class="form_main_button11" data-dismiss="modal" />
<input type="button" id="btnCancel" value="Clear" class="form_main_button11" />
</div>
</div>
</div>
</form>
}
I good option to send e-mail using Razor's view engine is MvcMailer:
Sample.cshtml view:
Hello #ViewBag.Name:<br />
Welcome to MvcMailer and enjoy your time!<br />
Action to send the e-mail:
public virtual MvcMailMessage Sample()
{
ViewBag.Name = "Test";
return Populate(x =>{
x.viewName = "Sample";
x.To.Add("test#example.com");
});
}
More details on this step-by-step guide.

Categories

Resources