#Html.BeginForm Displaying "System.Web.Mvc.Html.MvcForm" on Page - asp.net-mvc-3

I have a razor view that I added a delete button to inside of an 'if' statement and when the view is rendered in the browser it is displaying "System.Web.Mvc.Html.MvcForm" next to the delete button.
How do I get rid of it?
Here is the code:
<div id="deletestatusupdate">
#if (update.User.UserName.Equals(User.Identity.Name, StringComparison.OrdinalIgnoreCase))
{
#Html.BeginForm("deleteupdate", "home")
#Html.Hidden("returnUrl", Request.Url.ToString())
<button name="id" value="#update.StatusUpdateId">Delete</button>
}
</div>
Here is how it shows up in the rendered Razor View:
System.Web.Mvc.Html.MvcForm [Delete Button]
pretend that [delete button] is a an actual button, didn't feel like taking a screen shot.
Thank you for your help.

The recommended way to generate a form is the following:
<div id="deletestatusupdate">
#if (update.User.UserName.Equals(User.Identity.Name, StringComparison.OrdinalIgnoreCase))
{
using(Html.BeginForm("deleteupdate", "home"))
{
#Html.Hidden("returnUrl", Request.Url.ToString())
<button name="id" value="#update.StatusUpdateId">Delete</button>
}
}
</div>
Alternatively you could do this:
<div id="deletestatusupdate">
#if (update.User.UserName.Equals(User.Identity.Name, StringComparison.OrdinalIgnoreCase))
{
Html.BeginForm("deleteupdate", "home");
#Html.Hidden("returnUrl", Request.Url.ToString())
<button name="id" value="#update.StatusUpdateId">Delete</button>
Html.EndForm();
}
</div>
The reason why your original approach did not work is because BeginForm() writes directly to the output.

Please use #using instead of using the issue will resolved I am using MVC 4
#using(Html.BeginForm("deleteupdate", "home"))
{
#Html.Hidden("returnUrl", Request.Url.ToString())
<button name="id" value="#update.StatusUpdateId">Delete</button>
}

Get right for this we can use them
Using(Html.Beginform("Delete", "Home", new { Id = item.id } ))
{
#* We right the code. *#
}

Related

Razor Pages Net Core auto reload partial view on set frequency

I am still trying to get to grips with Razor Pages for Net Core and seem to be a bit stuck on this. I have my Index.cshtml:
#page
#model IndexModel
<input type="hidden" name="hdnPageSelector" id="hdnIndexPage" />
<div class="text-center">
<p>Welcome to</p>
<h1 class="display-4">"My Web App"</h1>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<partial name="IndexPartials/_Navigation" />
</div>
<div class="form-group col-md-1">
</div>
<div class="form-group col-md-6">
<partial name="IndexPartials/_Body" />
</div>
<div class="form-group col-md-1">
</div>
<div id="refreshMembers" class="form-group col-md-2">
<partial name="IndexPartials/_Members" />
</div>
</div>
Note the last div has an id="refreshMembers".
The partial view (_Members) that is loaded there looks like this:
#model IndexModel
<label>Members</label>
<br />
#{
foreach (ApplicationUser user in Model.AppUsersList)
{
if (user.IsLoggedIn)
{
<label>#user.FirstName #user.LastName </label>
<span class="dot"></span>
}
else
{
<label>#user.FirstName #user.LastName</label>
}
}
}
Within the controller I have a property called:
public IList<ApplicationUser> AppUsersList { get; set; }
And this is populated on OnGetAsync() as follows:
AppUsersList = _userManager.Users.OrderBy(x => x.FirstName).Where(y => y.UserName != currentUser.UserName).ToList();
This is fine, the page loads with the partial view populated as expected. I now want the partial to refresh every 5 seconds so I have put this piece of Javascript/JQuery in place:
$(function () {
setInterval(function () {
$("#refreshMembers").load("/Index?handler=RefreshMembers");
}, 5000);
});
with the following method setup:
public async Task<IActionResult> OnGetRefreshMembers()
{
var currentUser = await _userManager.GetUserAsync(User);
AppUsersList = _userManager.Users.OrderBy(x => x.FirstName).Where(y => y.UserName != currentUser.UserName).ToList();
return new PartialViewResult
{
ViewName = "_Members",
ViewData = new ViewDataDictionary<List<ApplicationUser>>(ViewData, AppUsersList)
};
}
However the partial view doesn't get refreshed. If I put a breakpoint within this method I can see it is being hit every 5 seconds, despite Devtools stating there is an error on each attempt:
In a nut shell, I just can't seem to get my partial view to be reloaded every 5 seconds. It feels like I am close but just missing something and don't know what that is.
Having been reminded to check the Output window in VS a bit better, I found the cause of my problems... Well two things actually. This is the corrected method:
public async Task<IActionResult> OnGetRefreshMembers()
{
var currentUser = await _userManager.GetUserAsync(User);
AppUsersList = _userManager.Users.OrderBy(x => x.FirstName).Where(y => y.UserName != currentUser.UserName).ToList();
return new PartialViewResult
{
ViewName = "IndexPartials/_Members",
ViewData = new ViewDataDictionary<IndexModel>(ViewData, this)
};
}
Where...
I didn't include the folder that the partial lives in when naming it on the PartialViewResult
I need to return the entire IndexModel object - having updated the AppUserList property, and not just the list of AppUsers.

ValidationSummary inside a partial view not showing errors

I have a partial view like this (simplified):
#model Portal.Models.LoginModel
<div class="login-container k-block">
<section id="login-form" class="">
#using (Html.BeginForm(actionName, controllerName, new { ReturnUrl = ViewBag.ReturnUrl }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset id="login-form-list-items">
<ol>
<li>
#Html.LabelFor(m => m.CardNumber)
#Html.TextBoxFor(m => m.CardNumber, new { #class="k-textbox"})
<div class="k-error-colored">
#Html.ValidationMessageFor(m => m.CardNumber)
</div>
</li>
<li>
#Html.LabelFor(m => m.Pin)
#Html.PasswordFor(m => m.Pin, new { #class="k-textbox"})
<div class="k-error-colored">
#Html.ValidationMessageFor(m => m.Pin)
</div>
</li>
<input id="login-input-submit" class="k-button" type="submit" value="Enter" />
</fieldset>
</div>
And in my login view I call this partial view like:
#model Portal.Models.LoginModel
#Html.Partial("_LoginFormNoRegistration", Model, new ViewDataDictionary { { "actionName", "Login" }, { "controllerName", "Account" } })
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The problem is that when the login method in the controller adds an error like:
public ActionResult Login(LoginModel model, string returnUrl)
{
//...
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
The message is not show in the validation summary... I don't understand why... What could be the problem? Some javascript library missing?
Update
I also found that the form generated as the novalidate attribute set:
<form action="/" method="post" novalidate="novalidate">
//...
</form>
I don't know why.
I found the problem.
I was passing a new ViewData in the RenderPartial which was overriding the ViewData of the parent view, so the model state was lost, as explained here: Pass Additional ViewData to an ASP.NET MVC 4 Partial View While Propagating ModelState Errors.
Changing the main view to:
#model Portal.Models.LoginModel
#{
ViewData.Add("actionName", "Login");
ViewData.Add("controllerName", "Account");
Html.RenderPartial("_LoginFormNoRegistration", Model, ViewData);
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Did the trick!
Also, if you want to show a general error message for the model in the validationsummary, be sure to add the error with an empty string as key:
ModelState.AddModelError("error", "The user name or password provided is incorrect."); - doesn't work
ModelState.AddModelError("", "The user name or password provided is incorrect."); - works
Remove the true argument in #Html.ValidationSummary()
It could be a few different things off the top of my head. First off you may not be including the required JavaScript. You may not need all of these but i include these in almost all of my layout views.
<script src="#Url.Content("~/Scripts/jquery-1.8.3.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
Also, could you show the code for your partial view? If you are referencing values that are inside a child class in your model the validation can act a little wonky sometimes.
Lastly, this sounds silly but as you did not post the code for your login model make sure you are using the proper data annotations for the values that you want the validation to show up for.

Html.RenderPartial and Ajax.BeginForm -> Submit is called twice

I have the following index view:
#model BoringStore.ViewModels.ProductIndexViewModel
#{
ViewBag.Title = "Index";
}
<h2>Produkte</h2>
<div id='addProduct'>
#{ Html.RenderPartial("Create", new BoringStore.Models.Product()); }
</div>
<div id='productList'>
#{ Html.RenderPartial("ProductListControl", Model.Products); }
</div>
The "productList" is just a list of all products.
The addProduct renders my Create View:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<div id="dialog-confirm" title="Produkt hinzufügen" style="display:none">
#using (Ajax.BeginForm("Index_AddItem", new AjaxOptions { UpdateTargetId = "productList" }))
{
#Html.Raw(DateTime.Now.ToString());
<div>
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
</div>
<br />
<div>
#Html.LabelFor(model => model.Price)
#Html.EditorFor(model => model.Price)
</div>
<br /><br />
<div>
<input type="submit" value="Produkt hinzufügen" />
</div>
}
When submitting the form, the Index_AddItem-method in my controller is called. Unfortunately the form always calls the method twice. :(
Can someone help me out?
Don't include scripts inside your partial views! They should go the your "main" views or your _layout.cshtml.
Your problem is that you have included the jquery.unobtrusive-ajax.min.js twice in your page. Once in your Create partial and once somewhere else. Because if you include that script multiple times it will subscribe on the submit event multiple times so you will get multiple submit with a single click.
So make sure that you have include that script only once in a page. So move the jquery.unobtrusive-ajax.min.js reference into your index view.
insure that you dont have jquery.unobtrusive-ajax.min.js file duplicated in the layout
as mentioned above, and you can check this using browser Inspectors
Another problem which may cause this error that i have encountered is resting a form using jquery in the ajax request as following
$("form").trigger("reset"); //just remove this line

Formcollection doesn't extract data from form MVC

I have trouble with formcollection.
I have some form in view, and two submit buttons both with unique name="". On debug I get on controller in formcollection all data except "name" of submitted button... I don't know why, 'cos I use this in other forms and there it works good. So I look at the code, but I couldn't find any differencies in using formcollection on not working formcol and working formcol. I tried rename buttons, move them, add referencies which I thought that could help... Nothing. On every submit skip my condition because it give me back only "false" and formcollection my "upload" or "save" button on onclick doesn't contain...
So I would like to ask you for help with this. Can you tell me where could be an error? Thanks to all!
This is in controller:
[HttpPost]
public ActionResult EditUser(EditUserVM model, int id, FormCollection c)
{
//c["upload"] is everytime set to null, 'cos c does't contain it
if (c["upload"] != null)
{
//.... some code
return RedirectToAction("Index", "Home");
}
if (ModelState.IsValid)
{
//.... next code
}
return View("EditUser", model);
}
This is in View:
#model PrukazOnline.ViewModels.EditUserVM
#{
ViewBag.Title = "EditUser";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>
#using (Html.BeginForm("EditUser", "User", null, FormMethod.Post, new { #class = "form-horizontal", id = "formstep", enctype = "multipart/form-data" }))
{
#*Here is some code - #Html.TextBoxFor(x => x.something) and #Html.ValidationMessageFor(x => x.something) - all of these are in formcollection*#
.
.
.
.
<div>
<input type="submit" value="Nahrát" class="upl" name="upload" id="upload" />
</div>
<div class="submit_buttons">
<input type="submit" name="save" id="save" value="Uložit" />
</div>
}
Issue is in multiple submit inputs in single form. There will only clicked button in FormCollection.
I suppose you try to vary form processing base on clicked button, in this case it's better to use different Actions for each button like this:
View:
<div>
<input type="submit" value="Nahrát" class="upl" name="upload" id="upload" />
</div>
<div class="submit_buttons">
<input type="submit" name="save" id="save" value="Uložit" />
</div>
Controller:
[HttpParamAction]
[HttpPost]
public ActionResult Upload(EditUserVM model)
{
...
}
[HttpParamAction]
[HttpPost]
public ActionResult Save(EditUserVM model)
{
...
}

MVC3 RenderPage never renders content

So I have this master/detail setup with a WebGrid. All is well until I try and use RenderPage to display the detail when a record is clicked:
<div class="innerbox">
#{
if(gdEligibility.HasSelection){
#RenderPage("~/Views/Eligibility/EligibilityPolicyDetailView.cshtml",
new { Customer = gdEligibility.SelectedRow })
}
}
</div>
Everything works, if I put a break point I can step through the detail view's cshtml file no problem, no errors. But nothing is ever rendered between the outer div's. Ever. Why doesn't RenderPage return anything? I even tried adding .ToHtmlString() on the end of the line but still nothing.
The detail cshtml:
#{ foreach(TravelInsurance.Models.Policy p in Page.Customer.Policies){
<fieldset>
<legend>Policy</legend>
<div class="display-label">Policy Number</div>
<div class="display-field">
#Html.DisplayFor(model => p.PolicyNumber)
</div>
<div class="display-label">Premium</div>
<div class="display-field">
#Html.DisplayFor(model => p.Premium)
</div>
</fieldset>
}}
This question suggests that RenderPage will use the parent model...
Maybe try using
#{Html.RenderPartial("EligibilityPolicyDetailView", new { Customer = gdEligibility.SelectedRow });}
or
#Html.Partial("EligibilityPolicyDetailView" ,new { Customer = gdEligibility.SelectedRow })
Pl. try again by removing the attribute "ajaxUpdateContainerId" in the grid definition and it should work.

Resources