I have a view that contain two partial views. One of them for creating, and the other is list of created(companies). My problem is that, when I try create HttpPost method does not work and calls only Index method again. Please help me to fix this problem.
This is my Index view
#model InvoiceModel.HelperClasses.CompanyViewModel
#{
ViewBag.Title = "Companies";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="companies">
<div id="create">#Html.Partial("CreateCompany", Model.Create)</div>
<div id="list">#Html.Partial("CompanyTable", Model.Companies)</div>
</div>
Use #Html.BeginForm() to define your Model that you are creating so when you post it is all mapped up properly.
#using (Html.BeginForm("(Action)", "(Controller)", FormMethod.Post, null))
{
(Your model here)
<input type="submit" value="Save" />
}
<div id="list">#Html.Partial("CompanyTable", Model.Companies)</div>
Related
I am using this form to post data to the controller once the data is saved I wanted to display this Success view but I am getting a 404 page not found. Any idea why I am getting this error?
View
#using (Html.BeginFormSitefinity("Save", "Preference", FormMethod.Post, new { id = "preferencesForm" }))
{
<div class="row">
<div class="text-center">
<button type="submit" class="btn btn-primary px-4 float-center">Save</button>
</div>
</div>
controller
public ActionResult Save(PreferenceViewModel model)
{
SaveData(model);
return View("~/Mvc/Views/Preference/Success.cshtml");
}
Does your code hit the Save method? I don't see it marked with the [HttpPost] attribute.
Also, if this is your Preference widget, then you can simply use this:
return View("Success");
Sitefinity will look for success.cshtml in the correct folder.
I am trying to navigate the user to a new page with a button click. I am having issues with rendering the new view. Any time I do click on the button, I either get an error for a dropdown on my page, or I get the home page view but with my desired route in the URL. I wanted to note that the user will be navigating to this page from the home page, which I made into my new landing page on the app. I wanted to point that out in case something I did here can be modified.
How I created a new landing page
I want to navigate from my landing page to my book inventory page.
My View (On the landing page):
<form method="post" asp-controller="Home" asp-action="Home" role="post">
<div class="form-group">
<label asp-for="bookName"></label>
<select name="bookName" asp-items="#(new SelectList(ViewBag.message, "ID", "bookName"))">
</select>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</form>
<div class="row">
<div class="form-group">
<a asp-controller="BookInventory" asp-action="Index">
<input type="button" value="Book Inventory Page" />
</a>
</div>
</div>
My Controller (On my landing page)
public void GetBooksDDL()
{
List<BookModel> bookName = new List<BookModel>();
bookName = (from b in _context.BookModel select b).ToList();
bookName.Insert(0, new BookModel { ID = 0, bookName = "" });
ViewBag.message = bookName;
}
[HttpGet("[action]")]
[Route("/Home")]
public IActionResult Home()
{
GetBooksDDL()
return View();
}
My Controller (On my book inventory page):
[HttpGet("[action]")]
[Route("/Index")]
public IActionResult Index()
{
return View();
}
I wanted to note that my breakpoint on my book inventory controller does hit the 'return View()', but it will still render the items from the homepage.
The error I get with the book dropdown says:
ArgumentNullException: Value cannot be null. (Parameter 'items')
Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.ctor(IEnumerable items, string dataValueField, string dataTextField, IEnumerable selectedValues, string dataGroupField).
I'm wondering why I'm getting this error when I'm trying to navigate to a different page. Since this is the new landing page, is it possible that it is passing along all of its data to the rest of the pages?
ArgumentNullException: Value cannot be null. (Parameter 'items')
Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.ctor(IEnumerable
items, string dataValueField, string dataTextField, IEnumerable
selectedValues, string dataGroupField).
About this error, it means that you didn't set the value for the select element, before return to the view, please check the ViewBag.message value, make sure it contains value.
Note: Please remember to check the post method, if the Http Get and Post method returns the same page, make sure you set the ViewBag.message value in both of the action methods.
I wanted to note that my breakpoint on my book inventory controller
does hit the 'return View()', but it will still render the items from
the homepage.
In the BookInventory Controller Index action method, right click and click the "Go to View" option, make sure you have added the Index view.
Based on your code, I have created a sample using the following code, it seems that everything works well.
Code in the Home Controller:
[HttpGet("[action]")]
[Route("/Home")]
public IActionResult Home()
{
GetBooksDDL();
return View();
}
[HttpPost("[action]")]
[Route("/Home")]
public IActionResult Home(BookModel book, string bookName)
{
GetBooksDDL();
//used to set the default selected value, based on the book id (bookName) to find the book.
List<BookModel> booklist = (List<BookModel>)ViewBag.message;
book = booklist.Find(c => c.ID == Convert.ToInt32(bookName));
return View(book);
}
Code in the Home view:
#model BookModel
#{
ViewData["Title"] = "Home";
}
<h1>Home</h1>
<form method="post" asp-controller="Home" asp-action="Home" role="post">
<div class="form-group">
<label asp-for="bookName"></label>
<select name="bookName" asp-items="#(new SelectList(ViewBag.message, "ID", "bookName", Model == null? 0:Model.ID))">
</select>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</form>
<div class="row">
<div class="form-group">
<a asp-controller="BookInventory" asp-action="Index">
<input type="button" value="Book Inventory Page" />
</a>
</div>
</div>
Code in the BookInventory controller:
public class BookInventoryController : Controller
{
[HttpGet("[action]")]
[Route("/Index")]
// GET: BookInventory
public ActionResult Index()
{
return View();
}
The screenshot as below:
If still not working, please check your routing configuration, perhaps there have some issue in the routing configure.
Your anchor tag formation is incorrect. You cannot write a button within anchor tag.
Do something like this:
<a asp-action="Index" asp-controller="BookInventory" class="btn btn-primary">Book Inventory Page</a>
Here the class will help your anchor tag look like buttons. I hope you have used bootstrap in your project. If not, then use it.
Hope this helps.
Here is another simple way:
<button type="button" class="btn" onclick="window.location.href = '/YourPage'">Button Title</button>
Please can you help on the below query.
I have got a main view and partial view. In main view looping through based on the count of model, the partial views will be rendered. The Partial View is as per below
-----------------Partial View----------------------
#using (Html.BeginCollectionItem("books"))
{
<div id="bookRow" class="bookRow">
<div class='container'>
<div class="align-left">
<h1>Book Name</h1>
<h2>#Html.TextBoxFor(m => m.BookName)</h2>
</div>
<div class="align-right">
<h1>Author</h1>
<h2>#Html.TextBoxFor(m => m.Author)</h2>
</div>
<div class="align-right">
<h1>Publisher</h1>
<h2>#Html.TextBoxFor(m => m.Publisher)</h2>
</div>
<div class="align-right">
#Html.CheckBoxFor(model => model.isConfirm)
#Html.Hidden("Id", #Model.Id)
</div>
Delete
</div>
</div>
}
-------------------Main View----------------------
#model IEnumerable<TDLProject.Models.BookViewModel>
<fieldset>
<legend>Books</legend>
<div id="new-Book">
#foreach (var model in Model)
{
#Html.Partial("_DynamicPartialView", model)
}
</div>
<div>
<input type="button" id="addBook" name="addBook" value="Add Book" />
<br />
</div>
<br />
</fieldset>
#using (Html.BeginForm())
{
<div>
<input type="submit" id="submitButton" value="Submit" />
</div>
}
-------------Controller--------------
[HttpPost]
public ActionResult Contact(IEnumerable<BookViewModel> bookModel)
{
// To do: do whatever you want with the data
return View();
}
The Problem is I am not receiving the data posted from View to the Controller on Click of Submit button. I have multiple partial views of same model on the main view and when click of submit button I need all the partial view data to posted to controller. In Partial View I am using BeginCollectionItem. Please can you help on this.
A form only posts back the name/value pairs of its successful controls, and your not generating the form controls inside the <form> tags.
Change the code to move the #Html.Partial() code inside the <form> (simplified)
#model IEnumerable<TDLProject.Models.BookViewModel>
#using (Html.BeginForm())
{
#foreach (var model in Model)
{
#Html.Partial("_DynamicPartialView", model)
}
<input type="button" id="addBook" name="addBook" value="Add Book" />
<input type="submit" id="submitButton" value="Submit" />
}
You also need to change the POST method signature to
public ActionResult Contact(IEnumerable<BookViewModel> books)
to match the name you use in the #using (Html.BeginCollectionItem("books")) method.
I am using ASP.NET 5 RC1
_MyPartial
#model MyViewModel
<div class="panel panel-primary">
<div class="panel-body">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.MyHtmlHelperRow(model => model.ShortDistrictName)
#Html.MyHtmlHelperRowSaveButton(model => model.Id)
</div>
}
</div>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
cshtml View
#model MyViewModel
#{
ViewBag.Title = "Edit";
}
<h2>#ViewBag.Title</h2>
#Html.RenderPartialAsync("_MyPartial", Model)
#section Scripts {
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
the line
#Html.RenderPartialAsync("_MyPartial", Model)
apart from it rendering in html, renders
System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult]
text in the html directly below the last content rendered by the partial page.
If I change the partial line reference to non async
#Html.Partial("_MyPartial", Model)
then I don't get this text line.
Questions:
Why do I get the text line in my html
How do I get rid of it and still be able to use RenderPartialAsync?
You need to use await to call asynchronous methods. ASP.NET 5 adds the ability to use await in Razor:
#{await Html.RenderPartialAsync("_MyPartial", Model);}
using the syntax in the accepted answer gave me this error:
Argument 1: cannot convert from 'void' to 'object'
#await Html.RenderPartialAsync("_ProductList", Model)
in RC1 I had to use curly braces and a semicolon:
#{await Html.RenderPartialAsync("_ProductList", Model);}
RenderPartialAsync writes directly to the response and returns void (technically Task), which the view compiler can't print as a string.
created a MVC4 ASP.NET application with razor view
--view code here - iframe and the form with 2 fields on it. Enter ID and click the Search button does invokes the Index Action of the HomeController
#model BusinessApp.Models.SearchViewModel
<iframe id="photomural" name ="mural" src="http://www.mywebfind.com/search" scrolling="yes" width ="75%"> </iframe>
#using (Html.BeginForm("Index", "Home", FormMethod.Get)) {
#Html.ValidationSummary(false)
<fieldset>
<legend>Contact Search </legend>
<div>
#Html.LabelFor(model => model.SomeID)
</div>
<div >
#Html.EditorFor(model => model.SomeID)
#Html.ValidationMessageFor(model => model.SomeID)
</div>
<p>
<input name="SearchButton" type="submit" value="Search" />
</p>
</fieldset>
}
-- based on the user values entered in the search box - the Index action of the home controller is executed.
-- based on some logic that is then executed in the action I would like to have the "src" of the Iframe to be loaded with the link to some website
--CODE in action Method of Home Controller to change the "src" of the IFrame. Could someone please give me some pointers.
public class HomeController : Controller
{
public ActionResult Index(SearchViewModel searchVM)
{
if (searchVM.SomeID != null)
{
//Execute some logic to determine the ID of the URL below that will be passed to Iframe
}
???? Code to change the IFrame src to some url like
"http://OrderManagementSystem/ShowOrder.aspx?ID=10248" based on above logic
return ???
}
}
I appreciate any help I can get from any of the experts out there.
I had the same issue and couldn't find an answer anywhere. Then realized I could set the target in the #using statement to the id of your iframe and return your normal view. Hope this helps someone!
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { target = "photomural"} ))