MVC5 Post data from partial view being used in main view - razor

I have already tried many solutions available on web as per my understanding in context to this question but being new in MVC I am still unable to find a solution. Kindly help.
I have a view which is the home page of the website named as "Index.cshtml" and is situated under the following path:
WebsiteName/Areas/Website/Views/CypressHome/Index.cshtml
Secondly, I have a created a user trial form as partial view named as "_PartialHomeFormFreeTrial.cshtml" which is situated under the following path:
WebsiteName/Areas/Website/Shared/_PartialHomeFormFreeTrial.cshtml.
This form I have used inside my "Index.cshtml" as below:
<!--freetrialform-->
#Html.Partial("_PartialHomeFormFreeTrial")
<!--//freetrialform-->
Now, my partial page is posting data comprising of following elements:
#using (Html.BeginForm("Create", "Customer", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div>
#Html.EditorFor(model => model.CustomerName, new { htmlAttributes = new { #class = "input__field input__field--kuro" } })
#Html.ValidationMessageFor(model => model.CustomerName, "", new { #class = "text-danger" })
............
other fields such as email, phone, date, etc..
<input type="submit" id="" value="SEND REQUEST" />
</div>
}
Now, I have created a controller named "CustomerController" which has the following code to save the data of the form as used as partial view in the main view "Index.cshtml":
public class CustomerController : Controller
{
private WebsiteContext db = new WebsiteContext();
// GET: Website/Customer
public ActionResult Index()
{
return View();
}
// GET: Website/Customer/Create
public ActionResult Create()
{
ViewBag.StatusPlanID = new SelectList(db.StatusPlans, "StatusPlanID", "Status");
return View("Index");
}
// POST: Website/Customer/Create
[HttpPost]
public ActionResult Create([Bind(Include = "CustomerID,CustomerName,CustomerEmail,CustomerPhone,DateOfRegistration,StatusPlanID")] Customer customer)
{
if (ModelState.IsValid)
{
db.Customers.Add(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.StatusPlanID = new SelectList(db.StatusPlans, "StatusPlanID", "Status", customer.StatusPlanID);
return View(customer);
}
}
I have tried many changes in my controller, return in the views and
many other things but I am getting the same error always. Neither the
validations are working nor the validated data is getting saved.
The error is as below:
Server Error in '/' Application.
The view 'Create' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Areas/Website/Views/Customer/Create.aspx
~/Areas/Website/Views/Customer/Create.ascx
~/Areas/Website/Views/Shared/Create.aspx
~/Areas/Website/Views/Shared/Create.ascx
~/Views/Customer/Create.aspx
~/Views/Customer/Create.ascx
~/Views/Shared/Create.aspx
~/Views/Shared/Create.ascx
~/Areas/Website/Views/Customer/Create.cshtml
~/Areas/Website/Views/Customer/Create.vbhtml
~/Areas/Website/Views/Shared/Create.cshtml
~/Areas/Website/Views/Shared/Create.vbhtml
~/Views/Customer/Create.cshtml
~/Views/Customer/Create.vbhtml
~/Views/Shared/Create.cshtml
~/Views/Shared/Create.vbhtml
And the url is changing as below:
1. On running the system initially: http://localhost:53872/
2. On clicking on submit: http://localhost:53872/Areas/Website/Customer/Create along with the
error as stated above.
For more information my WebsiteAreaRegistration.cs file contains the below code:
public class WebsiteAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Website";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Website_home",
"",
new { controller = "CypressHome", action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"Website_default",
"Areas/Website/{controller}/{action}/{id}",
new { controller = "CypressHome", action = "Index", id = UrlParameter.Optional }
);
}
}
Though I have understood the problem but unable to figure out. Kindly help.

In your code last return statement is return View(customer). That's means after POST data it return a View (using HTTP GET method) as same name as Action that's Create. But your description you have a Create Action but you have no view page.
So please create a Create.cshtml with a Model corresponding customer Object.
Or change the return statement.
Based on your comment you can follow this Change.
1.Remove
public ActionResult Create()
{
ViewBag.StatusPlanID = new SelectList(db.StatusPlans, "StatusPlanID", "Status");
return View("Index");
}
2.then change
public ActionResult Index()
{
ViewBag.StatusPlanID = new SelectList(db.StatusPlans, "StatusPlanID", "Status");
return View(new Customer());
}
3.in Index.cshtml
#Model Customer
#Html.Partial("_PartialHomeFormFreeTrial",Model)
4.Then
return View("Index",customer);

Related

MVC Dropdown List containing Method Actions for Models, Possible?

I have several models in my application which I want to create functionality to allow users to edit/create values within the database.
Of course each controller contains the action method, but I want to be able to provide the user with a dropdown that lists all of the models so when they select an option from the dropdown it takes the user to the correct view to Edit or Ceate an item in that model.
I.e. I have models for GoverningBody, Directorate, Region, and OperationalTeam, each of them have the following elements;
.....Id (int),
.....Name (string),
Live (bit)
(Live is used as a method for soft deleting of the value in order to protect historic data) I want to have a dropdown with these listed, the user selects one from the dropdown, clicks a button, and the user is then provided the Edit view, or Create view for that selected model.
I've done a but of research on the internet but cannot find any kind of solution nor anything that explains if what I'm attempting to achieve is even possible, and its most likely down to the fact that I don't know enough to know what I should be looking for.
I'm not asking for anyone to provide me with a solution, but any advice on what/where I should be looking, what terms to look for and learn about so I can attempt something on my own.
Any advice would be most appreciated.
Thanks
In my opinion, You can create two DropdownList, One is choose model and the other is choose action, I create a simple demo to show my opinion, Hope it can help you.
First, I create two models for this demo (User, GoverningBody), Then I Use Model Name to create controller with CURD action
public class UserController : Controller
{
public IActionResult Create()
{
return View();
}
public IActionResult Edit()
{
return View();
}
public IActionResult Update()
{
return View();
}
public IActionResult Delete()
{
return View();
}
}
public class GoverningBodyController : Controller
{
public IActionResult Create()
{
return View();
}
public IActionResult Edit()
{
return View();
}
public IActionResult Update()
{
return View();
}
public IActionResult Delete()
{
return View();
}
}
HomeController
public IActionResult Index()
{
List<SelectListItem> model = new List<SelectListItem>();
model.Add(new SelectListItem { Text = "User", Value = "User" });
model.Add(new SelectListItem { Text = "GoverningBody", Value = "GoverningBody" });
ViewBag.model = model;
List<SelectListItem> action = new List<SelectListItem>();
action.Add(new SelectListItem { Text = "Create", Value = "Create" });
action.Add(new SelectListItem { Text = "Edit", Value = "Edit" });
action.Add(new SelectListItem { Text = "Update", Value = "Update" });
action.Add(new SelectListItem { Text = "Delete", Value = "Delete" });
ViewBag.action = action;
return View();
}
View
<h2>Choose a model and an action you want to do with this model</h2>
<div>
Model: <select asp-items="#ViewBag.model" name="model" id="model"></select>
Action : <select asp-items="#ViewBag.action" name="action" id="action"></select>
</div>
<button type="button" onclick=go()>Go~</button>
#section Scripts{
<script>
function go(){
var controller = document.getElementById("model").value;
var action = document.getElementById("action").value;
window.location.href= "/"+controller+"/"+action;
}
</script>
}
Demo:

post_logout_redirect_uri ASP NET Core 2.2 AzureAD Razor Class Library RCL

We have tried using the sample
https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/
Walked through the sample and all works.
We can't get it to redirect after logout process. Also, it seems the account controller is not there but it is called in _layout.chtml this must be something new.
Yes, it does redirect to the application - what I'd like it to do is redirect to a different page.
You can redirect user to another page after sign-out by setting the OnSignedOutCallbackRedirect event :
In Startup.cs add using System.Threading.Tasks;
Config your new redirect url in OnSignedOutCallbackRedirect event :
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
options.Events.OnSignedOutCallbackRedirect = (context) =>
{
context.Response.Redirect("/Home/About");
context.HandleResponse();
return Task.CompletedTask;
};
});
The account controller code is built into the framework now. You can see it in Microsoft.AspNetCore.Authentication.AzureAD.UI.AzureAD.Controllers.Internal (see https://github.com/aspnet/AADIntegration/blob/0efa96de73e3235fbfc55cfe51d9547a693010cc/src/Microsoft.AspNetCore.Authentication.AzureAD.UI/Areas/AzureAD/Controllers/AccountController.cs):
namespace Microsoft.AspNetCore.Authentication.AzureAD.UI.AzureAD.Controllers.Internal
{
[AllowAnonymous]
[Area("AzureAD")]
[NonController]
[Route("[area]/[controller]/[action]")]
internal class AccountController : Controller
{
public IOptionsMonitor<AzureADOptions> Options
{
get;
}
public AccountController(IOptionsMonitor<AzureADOptions> options)
{
this.Options = options;
}
[HttpGet("{scheme?}")]
public IActionResult SignIn([FromRoute] string scheme)
{
scheme = scheme ?? AzureADDefaults.AuthenticationScheme;
string str = base.Url.Content("~/");
return this.Challenge(new AuthenticationProperties()
{
RedirectUri = str
}, new String[] { scheme });
}
[HttpGet("{scheme?}")]
public IActionResult SignOut([FromRoute] string scheme)
{
scheme = scheme ?? AzureADDefaults.AuthenticationScheme;
AzureADOptions azureADOption = this.Options.Get(scheme);
string str = base.Url.Page("/Account/SignedOut", null, null, base.Request.Scheme);
return this.SignOut(new AuthenticationProperties()
{
RedirectUri = str
}, new String[] { azureADOption.CookieSchemeName, azureADOption.OpenIdConnectSchemeName });
}
}
}
Unfortunately, I have not be able to force a redirect after logout. Instead, I see a page that says "You have successfully signed out." I'd like to know how to redirect the user back to the Index page.
I had to override the signedOut page manually by adding this to a controller:
[AllowAnonymous]
[HttpGet]
[Route("/MicrosoftIdentity/Account/SignedOut")]
public IActionResult SignedOut()
{
return Redirect(<MyRealSignedOutRedirectUri>);
}

ASP.NET Cross session list

I'm attempting to make a simple page that will compare multiple form submissions.
I have a html page with a form, and a for-loop that generates a div for each item in a list of form submissions. The list is passed from the controller. I am trying to maintain the list in the controller rather than rely on a database.
When I try to resubmit the form, which should add another object to the list, the list re initializes.
In debugging, I see that the list is empty when the form gets submitted. I'm unsure as to the correct terminology, but it seems that the list is emptied whenever the view is rendered. Is there a way to maintain list contents?
I know there are better ways to do this, and welcome any advice. I'm still learning, so pleas go easy.
Thanks!
This is the simplified controller.
namespace MvcApplication2.Controllers
{
public class HomeController : Controller
{
List<paymentPlan> plansList = new List<paymentPlan>();
public ActionResult Index()
{
return View(plansList);
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
paymentPlan Project = new paymentPlan();
Project.customerName = Convert.ToString(collection["customerName"]);
plansList.Add(Project);
return View(plansList);
}
}
}
This is my simplified view.
#model List<MvcApplication2.Models.paymentPlan>
#using (Html.BeginForm("index", "home", FormMethod.Post, new { Id = "signupForm" }))
{
<label for="customerName">Customer Name:</label>
<input type="text" name="customerName" class="form-control required" />
#Html.ValidationSummary(true)
<input type="submit" value="Calculate" class="btn btn-primary" />
}
#{
bool isEmpty = !Model.Any();
if (!isEmpty)
{
foreach (var i in Model)
{
<div>
Name: #i.customerName
</div>
}
}
}
This is my simplified model.
namespace MvcApplication2.Models
{
public class paymentPlan
{
public string customerName { get; set; }
}
}
I think that's a question of controller and asp.Net MVC lifecycle !
A controller lifetime is the same as the request, for each request a new controller is created and once the work is done it's disposed!
So try to remove this List<paymentPlan> plansList = new List<paymentPlan>(); and work with TempData[] or ViewData[] or Session[] like this :
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
Session["plansList"] = ((List<paymentPlan>)Session["plansList"])!=null? (List<paymentPlan>)Session["plansList"] : new List<paymentPlan>();
return View((List<paymentPlan>)Session["plansList"]);
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
paymentPlan Project = new paymentPlan();
Project.customerName = Convert.ToString(collection["customerName"]);
((List<paymentPlan>)Session["plansList"]).Add(Project);
return View(plansList);
}
}
check this : http://www.asp.net/mvc/overview/getting-started/lifecycle-of-an-aspnet-mvc-5-application

MVC input data into SQL table.Website works without error but when i click ShowTableData everything is Null

Ok so im trying to input data from View to a SQL table i got no errorss but data does not show in the table
I using VisualStudio project is ASP.NET MVC 4 Web Application so it has already created models
views connectionstring controllers and it has a Site.Master so i just make new View from which i will pass data to my controller and then push it to SQL table which i have already created within "Table" folder which is created by default from the project in this "Table" folder i have tables which are needed for registration stuff already created by its own so i just added a new table to this "Table" folder called ProductTable
So ProductTable has 2 values (int)ID which is Primary Keyed and (string)Name
Ok so in "Model" folder i added new Class "ProductTable" with code inside
[Table("ProductTable")]
public class ProductTable
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
}
i have created another class there "ProductTableContext " with code inside
public class ProductTableContext : DbContext
{
public DbSet<ProductTable> Products { get; set; }
}
and in my HomeController i have
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your .";
return View();
}
public ActionResult Table()
{
return View(new ProductTable());
}
[HttpPost]
public ActionResult Table(ProductTable product)
{
if (!ModelState.IsValid)
{
return View(product);
}
using (var contex = new ProductTableContext())
{
contex.Products.Add(product);
contex.SaveChanges();
}
return View();
}
}
so Index , About and Contact are Views created by the project itself.
and View
#model Father.Models.ProductTable
#{
ViewBag.Title = "Table";
}
<h2>Table</h2>
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.Name)
#Html.EditorFor(x => x.Name)
#Html.ValidationMessageFor(x => x.Name)
</div>
<button type="submit">Create event</button>
}
So the problem is that everything works fine i have no errors but when i close the website and i press debug > stop debugging then i click ShowTableData on ProductTable in ServerExplorer all values are Nulls so its like ihave never added this Data to the table can anyone tell me whats wrong? Thank you!
Add this attribute to your ID property
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]. This will tell EF to have the database generate the Identity when you save the object.

Loading View with data upon reload error

I have a view which I load with product data. When I press the 'Add to Basket' button I'd like the same page to reload again but I'm getting errors such as:
Object reference not set to an instance of an object.
View:
#model List<Ecommerce.Models.HomeModels.Product>
#foreach (Ecommerce.Models.HomeModels.Product product in Model)
{ // above error points here!!!!!!!!!!!
using (Html.BeginForm())
{
<input type="hidden" name="productId" value="#product.ID" />
<input type="submit" value="Add to Basket"/>
}
}
Controller:
public ActionResult BuyProducts()
{
List<Models.HomeModels.Product> products = new List<Models.HomeModels.Product>();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
//Method to load data into products
}
}
TempData["products"] = products;
return View(products);
}
[HttpPost]
[AllowAnonymous]
public ActionResult BuyProducts(string productID)
{
string id = productID;
return View(TempData["products"]);
}
TempData only exists for one request, so it is gone by the time you try to send it back (Which is why you get the error - TempData["products"] is null). Either way, you should use the post redirect get pattern, like this:
[HttpPost]
[AllowAnonymous]
public ActionResult BuyProducts(string productID)
{
string id = productID;
return RedirectToAction("BuyProducts");
}
The main reason is that if the user refreshes the page and you returned a view from post, the data will be posted a second time causing duplication.
TempData isn't persisted across requests. You can either use Session or ViewData to save "products"
Try one of those and see if that fixes your issue.