MVC 3 multiple forms model passing to dictionary - c#

I'm quite new to MVC 3 and I'm stuck on an issue. The main layout look like this:
<body>
<div id="conteiner_body">
<div id="conteiner_main">
<div id="container_top">
#{ Html.RenderPartial("Basket"); }
#{ Html.RenderPartial("MenuTop"); }
</div>
<div id="left_side_border">
<div id="left_side">
#{ Html.RenderPartial("SearchBox"); }
#{ Html.RenderAction("Index", "LeftMenu"); }
</div>
</div>
<div id="content">
#RenderBody()
</div>
#{ Html.RenderPartial("Footer"); }
</div>
</div>
</body>
I have 3 forms on the page. First is in MenuTop view:
#model Models.LogOnModel
<div id="conteiner_menu_top">
<div id="menu_top">
<div id="login">
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#{
using (Html.BeginForm("LogOn", "Account"))
{
#Html.TextBoxFor(m => m.UserName)
#Html.PasswordFor(m => m.Password)
#Html.CheckBoxFor(m => m.RememberMe)
<input type="submit" value="Login" />
<input type="button" value="Registr" onclick="document.location.href = '/Account/Register'" />
}
}
</div>
</div>
</div>
The second is in SearchBox:
#using (Html.BeginForm("Search", "SearchBox"))
{
<div id="search_box">
<h2>Search</h2>
<input name="searchWord" class="text" type="text" />
Advanced
<input class="submit" type="submit" value="Search" />
</div>
and of course the form in RenderBody, which changes according to the context.
Problem is, when I post some form from RenderBody(), eg. Registration, I recieve following error:
The model item passed into the dictionary is of type
'Models.RegisterModel', but this dictionary requires a model item of
type 'Models.LogOnModel'.
I've tried to add to MenuTop and SearchBox their own dictionary:
Html.RenderPartial("MenuTop", new ViewDataDictionary(Models.LogOnModel))
Html.RenderPartial("SearchBox", new ViewDataDictionary(IEnumerable<Product>))
But in this case I get following error:
CS0119: 'Models.LogOnModel' is a 'type', which is not valid in the given context
Has anybody any idea, how to solve this? Thanks a lot.

#{Html.RenderPartial("MenuTop", new Models.LogOnModel());}
#{Html.RenderPartial("SearchBox", Enumerable.Empty<Product>());}

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);
}

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

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}.

how to set dynamic controller name in the partial page

I have a partial page it is using two View page different controller but there have same Edit Action method. i need to set controller name dynamically for particular page in the run time . how can i do it ?
My partial page _SearchProduct in the shared folder it is working only for WomanController action method Edit:
<div class="row">
<div class="col-md-6">
#using (Html.BeginForm("Edit", "Woman", FormMethod.Get))
{
<p>
Find by Product Id : #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
</div>
<div class="col-md-6">
<span style="color:green">#ViewBag.ProductName </span>
</div>
<span style="color:red"> #ViewBag.FindResult </span>
</div>
My WomanController EDIT page :
#model MKL.Models.WomanProduct
<hr />
#Html.Partial("~/Views/Shared/_SearchProduct.cshtml")
<hr />
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.WomanProductId)
#if (ViewBag.ProductId != null)
{
#Html.Hidden("ProductId", (int)ViewBag.ProductId)
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
My ManController EDIT page :
#model MKL.Models.ManProduct
<hr />
#Html.Partial("~/Views/Shared/_SearchProduct.cshtml")
<hr />
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.ManProductProductId)
#if (ViewBag.ProductId != null)
{
#Html.Hidden("ProductId", (int)ViewBag.ProductId)
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
SO need to dynamically set Partial view Controller name Man and Woman
#using (Html.BeginForm("Edit", "", FormMethod.Get)){}
You can pass a model to the partial controller:
#Html.Partial("~/Views/Shared/_SearchProduct.cshtml", Model)
In _SearchProduct.cshtml, Model will be of type WomanProduct or ManProduct, depending on the view that called Partial. Then, choose controller depending on the model type:
#{
var ctrl = Model is WomanProduct ? "Woman" : "Man";
}
#using (Html.BeginForm("Edit", ctrl, FormMethod.Get))
Well, I would suggest you to use #Html.Action to render your partialview. Consider below example.
#Html.Action("GetSearchPartial", "Controller", new {controller = "Women"})
//in the Women Edit View
#Html.Action("GetSearchPartial", "Controller", new {controller = "Man"})
//in the Man Edit View
Now write an action which returns ParialViewResult.
public PartialViewResult GetSearchPartial(string controller)
{
ViewBag.Controller=controller;
return PartialView("_SearchProduct");
}
in your _SearchProduct - PartialView get the ViewBag data and assign it as controller.
#{
string controller=ViewBag.Controller;
}
<div class="row">
<div class="col-md-6">
#using (Html.BeginForm("Edit", controller, FormMethod.Get))
{
<p>
Find by Product Id : #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
</div>
<div class="col-md-6">
<span style="color:green">#ViewBag.ProductName </span>
</div>
<span style="color:red"> #ViewBag.FindResult </span>
</div>
Let know if you face any issues
Try this way
#using (Html.BeginForm("Edit", #HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString(), FormMethod.Get)){}
instead of the actual location of the partial view. so dynamically set Man or Woman controller name

Calling an Action in MVC when redirected from a partial view

I'm having this issue in which I have a log in screen and a register screen in different cshtml files, but the register view is called as a #Html.Partial. The code in the log in screen is as follows:
<div class="panelLogIn left #if (ViewBag.register) { Write("hidden"); }">
#using (Html.BeginForm()) {
<div>
<div class="validationMessage" style="padding-bottom:10px;">#Html.ValidationMessage("loginFailed")</div>
<div class="field">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">User</span>
#Html.TextBoxFor(a => a.UserName, new { #class = "textField" }) <div class="absolute validationMessage">#Html.ValidationMessageFor(u => u.UserName)</div>
</div>
<div class="field relative">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">Password</span>
#Html.PasswordFor(a => a.Password, new { #class = "textField" }) <div class="absolute validationMessage">#Html.ValidationMessageFor(u => u.Password)</div>
</div>
<div class="em0-9" style="margin-bottom: 20px;">
<input class="submitButton cursorHand" style="margin-top: 10px;" type="submit" value="Enter" />
</div>
<div class="em0-9">
<span class="guestLink bold linkBlue underline cursorHand">Register Free</span>
</div>
</div>
}
</div>
<div class="panelGuest left #if (!ViewBag.register) { Write("hidden"); }">
#Html.Partial("RegisterUser", Model.NewUser)
</div>
And the Register view is as follows:
#using (Html.BeginForm("Register", "Account"))
{
/* The text boxes and form elements */
<div class="em0-9" style="margin-bottom:20px;">
<input class="submitButton cursorHand" style="margin-top:10px;" type="submit" value="Register" />
</div>
}
Basically, the issue is that when I try to Register a new user, it redirects me to localhost/Account/Register and when I go back to the LogIn screen (which is in the same view) I can't call any other action aside from the register one.
Any help with this will be greatly appreciated.
Try fully specifying the action of your first Html Form, as you have done in the Partial:
#using (Html.BeginForm("Index", "Account")) {
//
}
You should probably have a different view for resgister. It looks like you have one view which contains the login box(username / password fields) & also new user registration fields.
but the register view is called as a #Html.Partial
If you are familiar with user controls in the web forms programming model, Html partials would be somewhat similar to user controls.
So code in login screen would be just
<div class="panelLogIn left #if (ViewBag.register) { Write("hidden"); }">
#using (Html.BeginForm()) {
<div>
<div class="validationMessage" style="padding-bottom:10px;">#Html.ValidationMessage("loginFailed")</div>
<div class="field">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">User</span>
#Html.TextBoxFor(a => a.UserName, new { #class = "textField" }) <div class="absolute validationMessage">#Html.ValidationMessageFor(u => u.UserName)</div>
</div>
<div class="field relative">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">Password</span>
#Html.PasswordFor(a => a.Password, new { #class = "textField" }) <div class="absolute validationMessage">#Html.ValidationMessageFor(u => u.Password)</div>
</div>
<div class="em0-9" style="margin-bottom: 20px;">
<input class="submitButton cursorHand" style="margin-top: 10px;" type="submit" value="Enter" />
</div>
<div class="em0-9">
<span class="guestLink bold linkBlue underline cursorHand">Register Free</span>
</div>
</div>
}
</div>
You can have a separate register view in which you can include your register partial.
Hope this helps.

How to clear dropdown list once value is selected and submited

Hi guys i have the following code in my view:
#model Test.tblReview
#{
ViewBag.Title = "Create";
}
<div class = "under">
Add a New Review
</div>
<br />
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" />
<link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script src="http://jquery-ui.googlecode.com/svn/tags/latest/external/jquery.bgiframe-2.1.2.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/i18n/jquery-ui-i18n.min.js" type="text/javascript"></script>
<link href="../../Content/themes/base/jquery.ui.slider.css" rel="stylesheet" type="text/css" />
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.HiddenFor(model => model.ReviewID)
</div>
<div class="editor-field">
#Html.HiddenFor(model => model.ReviewID)
#Html.HiddenFor(model => model.ReviewID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Recomendation)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Recomendation, new { style = "max-width: 200px; max-height: 150px;" })
#Html.ValidationMessageFor(model => model.Recomendation)
</div>
<br />
<div class="editor-label">
#Html.LabelFor(model => model.AvoidOrBuy)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.AvoidOrBuy, new { style = "max-width: 200px; max-height: 150px;" })
#Html.ValidationMessageFor(model => model.AvoidOrBuy)
</div>
<br />
<div class="editor-label">
#*#Html.LabelFor(model => model.Posted)*#
</div>
<div class="editor-field">
#Html.HiddenFor(m => m.Posted)
#Html.ValidationMessageFor(model => model.Posted)
</div>
<br />
<div class="editor-label">
#Html.LabelFor(model => model.Score)
</div>
<br />
<div class="demo" style="width: 185px">
<div id="slider-range-max"></div>
</div>
<br />
<p>Score Added From Scroll Bar</p>
<div class="editor-field">
#Html.EditorFor(model => model.Score)
#Html.ValidationMessageFor(model => model.Score)
</div>
<br />
<div class="editor-label">
#Html.LabelFor(model => model.GameIDFK, "tblGame")
</div>
<div class="editor-field">
#Html.DropDownList("GameIDFK", String.Empty)
#Html.ValidationMessageFor(model => model.GameIDFK)
</div>
<div class="editor-label">
#Html.HiddenFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.HiddenFor(model => model.UserName)
#Html.HiddenFor(model => model.UserName)
</div>
<br />
<p>
<input type="submit" value="Create" />
</p>
}
<div>
#Html.ActionLink("Go To Reviews", "Index") | #Html.ActionLink("Go Back To Games", "Index", "Game")
</div>
<script type="text/javascript">
$(function () {
$("#slider-range-max").slider({
range: "max",
min: 1,
max: 10,
value: 1,
slide: function (event, ui) {
$("#Score").val(ui.value);
}
});
$("#Score").val($("#slider-range-max").slider("value"));
});
</script>
Everything works fine but i would like way to make the value in the drop down to clear once its been selected and the submit button is pressed, If you require addtional information please ask me thank you
the value in the drop down to clear once its been selected and the
submit button is pressed
Why do you need to do this ? I strongly believe that you should not change the value if you are going to submit it to an action method where you are going to read it for further processing. because you are not gonna get the selected value there. If you are not worried about the selected value, then you can clear that by jQuery like this
$(function(){
$("form").submit(function(){
$("#GameIDFK").empty();
return true;
});
});
Another thing came to my mind is that , If you really want to clear the drop down, but still use in your action method, you probably need to have a hidden input element in your form and using java script, you can set the selected value of drop down to that. Then in you can clear your drop down and then in your action method, you can read from the hidden input instead of the actual drop down.

Categories

Resources