In my solution "WebApp1" has two projects "WebApp1.Web" and "WebApp1.Api", in each project has two controllers "AccountsController" and "ApplicationsController" (same name)
In WebApp1.Web there are views:
In the create application view it's calling the correct controller WebApp1.Web.ApplicationsController
<form asp-controller="Applications" asp-action="Create" method="post">
Translates to
<form method="post" action="/Applications/Create" novalidate="novalidate" _lpchecked="1">
This is the correct behavour
But ... in the create account view it is calling the wrong controller WebApp1.Api.AccountsController
<form asp-controller="Accounts" asp-action="Create" method="post">
Translates to
<form method="post" action="/api/Accounts" novalidate="novalidate" _lpchecked="1">
Its not suppose to post to /api/Accounts, its suppose to post to /Accounts/Create
Question
Why is the view calling the wrong controller? its not calling the web controller inside the same webapp1.web? How do I specific the view to use the controller webapp1.web?
You can specify where to post a form in .NET MVC like this:
#using (Html.BeginForm("Create", "Accounts", new object { }, FormMethod.Post, new { enctype = "multipart/form-data" })) {
<!-- Your content goes here -->
}
Related
I have the following bits from my test application.
A method used for posting the data from a partial view.
public IActionResult AddPayor(Payor newPayor)
{
if (ModelState.IsValid)
{
mvSrv.SaveOnePayor(newPayor);
return RedirectToAction("Index", "Payor");
}
else
{
return View();
}
}
And index cshtml view where I want to have a list of item plus the ability to add more.
Notice the model class PayorView; it contains a list of payors to use in the ViewPayor view and a single payor to use in the AddPayor view. I do it this way so that the AddPayor can have an object passed down even when the list is empty. Earlier I tried to have only the list as the model but sending the [0] element failed when list was empty.
#addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
#model FSA_Tracker.ViewModels.PayorView
#{
Layout = "_Layout";
}
<partial name="ViewPayor" for="payors" />
<partial name="AddPayor" for="payor" />
The partial view for AddPayor is just an input form. The model object is pass down from the parent view.
#addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
#model FSA_Tracker.Models.Payor
<fieldset>
<form asp-action="AddPayor" method="post">
<div asp-validation-summary="ModelOnly" class="input-validation-error"></div>
<div id="formContainer">
<p>
<label asp-for="Name"></label>
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
</p>
<p>
<button type="submit">Add Payor</button>
</p>
</div>
</form>
</fieldset>
My problem is that the newPayor argument in my post method does not get initialized, but rather what gets initialized is the PayorView.payor property in the parent view model object. So I can make it work if I change to
and I extract the payor from there.
Is there a way to prevent my partial view from binding its object to the parent view model? Preferably from the parent view.
Thanks
try passing in the payor model into your partial view like:
<partial name="ViewPayor" model="#Model.Payor" />
Got it. I needed to instantiate and pass the new new model into the partial. Now I see what Matthias L meant. I just didn't know I could go to a different namespace than the one in the declaration section. This will give the partial view a new Provider object rather than an attribute from the parent view.
#{
var provider = new FSA_Tracker.Models.Provider();
<partial name="AddProvider" model="#provider" />
}
I go to a View, submit data via POST, but the redirect cannot find the Controller method. What am I doing wrong here? After submitting the form I get:
404 error: cannot find page. URL is: http://localhost:52008/InternalController/UpdateCardFormPost
Snippet from InternalController.cs:
public ActionResult UpdateCardFormView()
{
var CardToUpdate = new CardView();
return View(CardToUpdate);//return implementation of Cards.cshtml with the empty model that was passed to it
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UpdateCardFormPost(CardView c)
{
CardModelIO.WriteCard(c);//#TODO: IMPLEMENT
return View("CardDetailView", c);
}
UpdateCardFormView.cshtml (the view with the form I am submitting):
#using LeanKit.API.Client.Library.TransferObjects
#model CardView
<!DOCTYPE html>
<html>
<!--Form used to change a card
STARTING DISPLAY called by in Internal/UpdateCardFormView
ENDING DISPLAY (post) called by UpdateCardForm in InternalController a specified below-->
<head>
</head>
<body>
#Html.BeginForm("UpdateCardFormPost", "InternalController", FormMethod.Post)
#Html.TextBoxFor(c => c.AssignedUserName);
<input type="submit" value="Submit Changes" />
</body>
</html>
Heres the CardDetailView.cshtml (the view I should be redirected to):
#using LeanKit.API.Client.Library.TransferObjects
#model IEnumerable<CardView>
<!--used for displaying an individual card in detail view
referenced in UpdateCardFormPost() method of Internal controller-->
<!DOCTYPE html>
<html>
<head>
</head>
<body>
CardView j = Model;
<p>j.AssignedUserId</p>
</body>
</html>
You've specified the controller name as InternalController but it's probably just called "Internal".
Try changing
#Html.BeginForm("UpdateCardFormPost", "InternalController", FormMethod.Post)
to
#Html.BeginForm("UpdateCardFormPost", "Internal", FormMethod.Post)
you are missing closing form tag
you should do it like
using (#Html.BeginForm("UpdateCardFormPost", "InternalController", FormMethod.Post))
{
...
}
#using(Html.BeginForm())
{
#Html.TextBoxFor(c => c.AssignedUserName);
<input type="submit" value="Submit Changes" />
}
<form method="post" class="search-form" action="?">
<fieldset>
<input class="search home_input_search" placeholder="Поиск" type="search" />
<input type="submit" class="subm but_search" value="" />
</fieldset>
</form>
I have a form - search, this is layout and my task consistent in creation link to the controller with params like Products/index?search_name=something. And I dont know how I can transfer value textbox in my link.
Add onsubmit event handler to form, it should:
create Url with query string ?search_name= value from input
set window.location.href to created url
return false
EDIT: Of course, you can implement that in different way, the form is not needed in that case.
You have to give inputs the name they should have on posting and set the right action on the form. The name on the input determines what the key will be in the URL (since you use the GET method). Setting the action on the form will indicate where to send it to.
<form method="post" class="search-form" action="Products/index" method="GET">
<fieldset>
<input name="search_name" class="search home_input_search" placeholder="Поиск" type="search" />
<input type="submit" class="subm but_search" value="" />
</fieldset>
</form>
First of all there it'll be better to call controller paramter "searchName" instead of "search_name". That corresponds with code conventions.
Next, when you call Proudcts/index?search_name=somethink in browser you are initiating GET request. GET requests have no body and communicate with query parameters.
When you create new form and submit 'em to the server you are initiating POST request (by default). Post request has the body-section which contains request parameters.
Then we should start from View. If you want to use query-string you should explicitly create GET-form:
#using (Html.BeginForm("ControllerMethodName", "ControllerName", FormMethod.Get))
{
}
Next you should add name attribute to your input with the same name as in the controller method parameter:
<input class="search home_input_search" name="searchName" placeholder="Поиск" type="search" />
Or you can use HtmlHelper method to generate html:
#Html.TextBox("searchName", string.Empty, new Dictionary<string, object> { { "class", "search home_input_search" }, { "placeholder", "Поиск" } })
Finally you can have as many parameters as you need:
#using (Html.BeginForm("ControllerMethodName", "ControllerName", FormMethod.Get))
{
#Html.Label("Поиск")
#Html.TextBox("searchName", string.Empty, new Dictionary<string, object> { { "class", "search home_input_search" }, { "placeholder", "Поиск" } })
#Html.Label("Включая вложенные")
#Html.CheckBox("includeNested", true)
}
Hi i have this project where i have an string parameter on a page the form make the post to
/booking/confirm
but it need to post to
/Booking/Confirm?guid=013b0053-5840-4866-97c2-d544d8b6a34c
i could ofcourse just write
#using (Html.BeginForm())
but i need an class on the form for an jquery function
so my using looks like this
#using (Html.BeginForm("Confirm", "Booking", FormMethod.Post, new { #class = "sigPad"}))
Write html without using the helper
<form action="#Url.Action("Prods","Products", new { guid=013b0053-5840-4866-97c2-d544d8b6a34c })" method="POST" class="sigPad">
...
</form>
#using (Html.BeginForm("Confirm", "Booking", new { guid=013b0053-5840-4866-97c2-d544d8b6a34c }
I have a new MVC4 project.
In my _Layout.cshtml I have the following:
<div class="container maincontent">
<div class="row">
<div class="span2 hidden-phone">
#*
In here is a RenderSection featured. This is declared in a section tag in Views\Home\Index.cshtml.
If this is static text for the whole site, don't render a section, just add it in.
You should also be able to use #Html.Partial("_LoginPartial") for example.
This _LoginPartial will need to be a cshtml in the Shared Views folder.
*#
#{ Html.RenderPartial("_NewsFeed"); }
</div>
<div class="span10">
#RenderBody()
</div>
</div>
</div>
My partial view is
<div class="row newsfeed">
NEWS FEED
#foreach (var item in ViewData["newsfeed"] as IEnumerable<NewsItem>)
{
<div class="span2 newsfeeditem">
<h3>#item.NewsTitle</h3>
<p>#item.NewsContent</p>
#Html.ActionLink("More", "NewsItem", "News", new {id=#item.Id}, null)
</div>
}
Is there a way I can make the partial view make the data call. Currently I have to do the following in my controller for every action:
ViewData["newsfeed"] = _db.NewsItems.OrderByDescending(u => u.DateAdded).Where(u => u.IsLive == true).Take(4);
return View(ViewData);
I come unstuck where I already pass in a model to a view as I cannot then pass this into it as well.
I know I am doing something wrong, just not sure what or where.
I just want to be able to make a render call in my _layout and then the partial view to know to collect the data and then render itself. Or have I got the wrong end of the stick? I suppose I am trying to use it like an ascx...
You should switch from using a RenderPartial to a RenderAction. This allows you to go through the pipeline again and produce an ActionResult just like a partial, but with server side code. For example:
#Html.RenderAction("Index", "NewsFeed");
Then you make a NewsFeedController and provide an Index action method:
public class NewsFeedController : Controller
{
public ActionResult Index()
{
var modelData = _db.NewsItems.OrderByDescending(...);
// Hook up or initialize _db here however you normally are doing it
return PartialView(modelData);
}
}
Then you simply have your CSHTML like a normal view in your Views/NewsFeed/Index.cshtml location.