Automatic Logout on Ajax call in ASP.net - asp.net

I have a dropdownlist with different soccer Clubs from my database. When I select one, an ajax call will be made to show all the Games that Club will play in.
The problem is whenever I'm logged on as an AspNetUser I automatically get logged off the second I submit the dropdownlist.
When I'm not logged in everything works as it should.
I'm really confused why exactly this happens.
Controller
[Authorize]
public class WedstrijdController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
ploegService = new PloegService();
ViewBag.PloegId = new SelectList(ploegService.All(),
"Id", "Naam");
return View();
}
[AllowAnonymous]
public ActionResult IndexAjax(int? ploegId)
{
if (ploegId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
wedstrijdService = new WedstrijdService();
var wedstrijden = wedstrijdService.WedstrijdenByPloeg(Convert.ToInt16(ploegId));
return PartialView("_SearchWedstrijdenPartial", wedstrijden);
}
}
Index.cshtml
#{
ViewBag.Title = "Lijst";
}
<h2>Wedstrijden</h2>
<div class="panel panel-default">
<div class="panel-heading">Kies een wedstrijd</div>
<div class="panel-body">
#using (Ajax.BeginForm("IndexAjax", "Wedstrijd",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
LoadingElementId = "ajax-loader",
UpdateTargetId = "searchresults",
}))
{
<div class="form-horizontal">
<div class="form-group">
#Html.Label("Ploeg", htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-md-10">
#Html.DropDownList("PloegId", null, "---Kies ploeg---", htmlAttributes: new { #class = "form-control" })
<img id="ajax-loader"
src="#Url.Content("~/content/Images/ajax-loader.gif")"
style="display: none" />
</div>
</div>
</div>
}
<div id="searchresults"></div>
</div>
</div>
#section scripts
{#Scripts.Render("~/bundles/jqueryUnobtrusive")
<script>
$("#PloegId").on("change",
function() {
$("form").trigger("submit");
});
</script>
}
_SearchWedstrijdenPartial.cshtml
#model IEnumerable<VoetbalMVC.Models.Wedstrijd>
<table class="table">
<tr>
<th>
Thuisploeg
</th>
<th>
Bezoekersploeg
</th>
<th>
#Html.DisplayNameFor(model => model.Stadion)
</th>
<th>
#Html.DisplayNameFor(model => model.Datum)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Ploeg1.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.Ploeg.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stadion.Naam)
</td>
<td>
#Html.DisplayFor(modelItem => item.Datum)
</td>
<td>
#Html.ActionLink("Order tickets", "Detail", new { wedstrijdId = item.Id })
</td>
</tr>
}
</table>

Indeed, by using the $("form") jQuery selector you are targeting all form elements on the page. You can verify the forms being submitted from the client to the server with tools like Fiddler, Postman, or the developer tools of your browser (by hitting F12 or CTRL+Shift+I on Windows/Linux, or Command+Option+I on Mac).
As far as the logout form is concerned, if you haven't customized the folder/file structure of your MVC project, it should be located in Views/Shared/_LoginPartial.cshtml:
#using Microsoft.AspNet.Identity
#if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", #class = "navbar-right" }))
{
// ...
}
}
..so it is generating a form with an ID of #logoutForm, but since you are submitting all forms at once, you are subsequently logging out the user each time.
This means you need to modify the call to only submit the form you want. Assuming the ID of your form being AjaxForm, you would do:
$("#AjaxForm").trigger("submit");

This piece of code was causing the error
$("form").trigger("submit");
As you can see this includes all forms. I suspect this means the logout button is included in some sort of form which triggers this action when logged in. Simply add an Id to your AjaxForm and only trigger the submit of that AjaxForm.

Related

Asp.net MVC action link to post with routed parameters

Hi I have the following data table in which u can click move button , the issue is that it always use get link instead of post how to apply post with parameters
<div class="box-body">
#using (#Html.BeginForm("QueueDetails", "Home", FormMethod.Post))
{
<table id="example1">
<tbody>
#foreach (var errorMesseage in Model.ErrorMesseages)
{
<tr>
<td>#errorMesseage</td>
<td>
#Html.ActionLink(
"Move",
"QueueDetails",
new { errorMesseage = #errorMesseage, model = Model },
new { #class = "saveButton", onclick = "return false;" })
</td>
</tr>
}
</tbody>
</table>
}
</div>
$(document).ready(function () {
createChart();
$('.saveButton').click(function () {
if(confirm('Are you sure you wish to Move this messeage back?'))
{
$(this).closest('form')[0].submit();
}
});
});
it always redirect to the get with url like Home/QueueDetails?errorMesseage=Error%20messeage%201&model=xxxx

How to use partial views from different models in ASP.NET MVC 5?

Hi I am trying to code a simple blog with using ASP.NET MVC 5 Framework. I have done CRUD operations of Posts. I mean I can add new articles and manage them. When I wanted to add comments to articles, I stuck. Comments will be added to Details pages of articles. So I should add Create comment page to Details page.
I used Code First model and I have two models. Articles and Comments. I decided to use partial views to enter comments. But result is an error:
The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.Article but this dictionary requires a model item of type 'Blog.Models.Comment'. Comments can not be added. I created 2 PartialViews, one of them is _CreateComments PartialView and other one is _Index PartialView
Details View:
#model Blog.Models.Article
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Article</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Title)
</dt>
<dd>
#Html.DisplayFor(model => model.Title)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Author)
</dt>
<dd>
#Html.DisplayFor(model => model.Author)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Date)
</dt>
<dd>
#Html.DisplayFor(model => model.Date)
</dd>
<dt>
#Html.DisplayNameFor(model => model.ArticleContent)
</dt>
<dd>
#Html.DisplayFor(model => model.ArticleContent)
</dd>
</dl>
</div>
<div class="jumbotron">
#Html.Partial("~/Views/Comments/_CreateComments.cshtml", new Blog.Models.Comment())
#Html.Partial("~/Views/Comments/_Index.cshtml", new List<Blog.Models.Comment> { new Blog.Models.Comment() })
</div>
_CreateComment PartialView
#model Blog.Models.Comment
#using (Html.BeginForm("Create"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Comment</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CommentContent, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CommentContent, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CommentContent, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
_Index PartialView
#model IEnumerable
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Date)
</th>
<th>
#Html.DisplayNameFor(model => model.CommentContent)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.CommentContent)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.CommentId }) |
#Html.ActionLink("Details", "Details", new { id=item.CommentId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.CommentId })
</td>
</tr>
}
</table>
You have to use a ViewModel for that purpose. In POST, it will get the needed information. And in GET you will send the needed information.
For example: in GET you will send the article and needed areas. But in POST you will get the comment and commenter's name and date etc.
There are numerous issues with your code.
#using (Html.BeginForm()) means it will post back to the
Details() method (assuming that's the action which generated the
view), so it would need to be #using (Html.BeginForm("Create"))
The controls your generating will have name attributes such as
name="Item2.Date" which have no relationship to your Comment
class (Comment does not have a property named Item which is a
complex object with a property named Date)
The default value of a DateTime property is 1.1.0001 00:00:00
meaning that you have not initialized the value (e.g. Date =
DateTime.Today;) but its not clear why you would need the user to
enter a date anyway - surely that would be set to today's date in
the controller immediately before you save the comment.
You have not indicated what scripts
#Scripts.Render("~/bundles/jqueryval") is generating, but assuming
you using the jQueryUI datepicker, you will need at least
jquery-{version}.js and jquery-ui-{version}.js (plus jquery.validate.js and jquery.validate.unobtrusive.js for validation)
You have a table in your form which will not display anything other
that the initial values of a new Comment (and exactly the same as
is being displayed in the textboxes) so it seems a bit pointless
Note also your view does not display any existing comments for an article which seems unusual.
There a numerous ways so solve this including ajax so the user could stay on the same page and continue to add more comments, but based on what appears to be your current UI, then the model in Details view should be just Article and use a partial to render a form for a new Comment
Controller
public ActionResult Details(int? id)
{
....
Articles article = db.Articles.Find(id);
....
return View(article);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Comment model)
{
if (ModelState.IsValid)
{
model.Date = DateTime.Today; // set date before saving
db.Comments.Add(model);
db.SaveChanges();
return RedirectToAction("Index");
}
....
}
View
#model yourAssembly.Article
// Render properties of Article
....
// Add form for creating a new comment
#Html.Partial("_Comment", new yourAssembly.Comment)
// Add required scripts including jquery ui
and the partial view (_Comment.cshtml)
#model yourAssembly.Comment
#using (Html.BeginForm("Create"))
{
#Html.LabelFor(m => m.Content, new { #class = "control-label col-md-2" })
#Html.TextBoxFor(m=> .m.Content, new { #class = "form-control" } })
#Html.ValidationMessageFor(m=> m.Content, new { #class = "text-danger" })
<input type="submit" value="Create" class="btn btn-default" />
}
Side notes:
Do not use Tupple in your views, especially for a view that
involves editing since it generates name attributes which have no
relationship to your model. Always use view models.
You do not generate a control for the CommentId property so there
is no point including it in you [Bind] attribute (and in fact
means someone could post back a value and result in your code
throwing an exception.
Using <dl>, <dt> and <dd> tags are not appropriate in your
view (they are for A description list, with terms and
descriptions). Use <div> and <span> elements.

how can i navigate between views and pass a model in view without getting error in asp.net mvc 4

i have a MvcApplication for Store WebSite and i want when user go to Products and when click on Buy for each of product,go to a view that will reviews Buy List and make sure's user are accepted,then after user clicked on IAccept return to Index View with a Message
now my problem is this,i can't use passed product object in my View,error message is this:"#Model.name is null"
here is my Product,Buy ActionResult and Buy,Product View
public ActionResult Product()
{
var pmodel = db.posts.ToList();
product pro = new product()
qrcode = 2455174,
name = "hub",
color_id = 3,
category_id = 3,
price = 10,
maker_code = 1,
offer_id = 0
};
db.products.Add(pro);
db.SaveChanges();
if (pmodel != null)
{
return View(pmodel);
}
return View();
}
Product View:
#model IEnumerable<MvcApplication1.Models.post>
#{
ViewBag.Title = "Product";
Layout = "~/Views/Shared/_LayoutHome.cshtml";
}
<h3>Products</h3>
<html>
<head><title></title>
<script type="text/javascript">
function enlarge(el) {
if (el.width = 300)
{
el.width = 50;
el.height = 50;
}
el.width = 300;
el.height = 240;
}
</script>
</head>
<body>
<table>
<tr>
<td style="font-weight:bold">
Image:
</td>
<td style="font-weight:bold">
Name:
</td>
<td style="font-weight:bold">
Description:
</td>
</tr>
#foreach(var item in Model) {
<tr>
<td>
<img src="~/Resources/image_2.jpg") id="x"
width="50" height="50" onclick="enlarge(this)"
alt="Click To See Image Larger">
</td>
<td>
#Html.DisplayFor(modelItem => item.title)
</td>
<td>
#Html.DisplayFor(modelItem => item.text)
</td>
<td>
#using (Html.BeginForm()){
<p>
#Html.ActionLink("Buy Now!", "Buy")
</p>
}
</td>
</tr>
}
</table>
</body>
</html>
Buy ActionResult:
[HttpPost]
public ActionResult Buy(user users,product products,post p)
{
var prod = db.products.Single(pro => pro.qrcode == products.qrcode);
DateTime date = DateTime.Now;
factor fact = new factor() {description=p.text,factor_id=products.qrcode,count=1
,product_name=products.name,product_qrcode=products.qrcode,status=
"Buy with Balance fFunds",date=date.ToString()};
return View(prod);
}
[HttpGet]
public ActionResult Buy(product products)
{
return View(products);
}
And Here is Buy View:
#model MvcApplication1.Models.product
#{
ViewBag.Title = "Buy";
Layout = "~/Views/Shared/_LayoutHome.cshtml";
}
<h2>Review</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Are you sure to buy this stuff?</legend>
</fieldset>
<div class="display">
#Html.DisplayFor(model => model.name)
</div>
<div class="display">
#Html.DisplayFor(model => model.price)
</div>
<div class="display">
#Html.DisplayFor(model => model.qrcode)
</div>
<p>
<input type="submit" value="Accept" />
</p>
}
my problem summary is,when user go to products and see the products post's and try to buy something (by clicking on "Buy Now!" link)then will be Redirect to Buy View,then user must reviews and Accept stuff details then Redirect to Index with a Message from complete operation or something like that!!But it doesn't show stuff details.

Can only update the first record of a result set in MVC

I have taken over support of an MVC application, but unfortunately have pretty much zero experience or knowledge of MVC, so I apologise in advance if this is a stupid question.
We are placing every single result into a listed item in the HTML, then hiding all but one record, so you can filter through the different entries using First/Prev/Next/Last buttons, all via jQuery:
$("a#next").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":last-child")) {
return false;
}
nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":first-child")) {
return false;
}
nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});
This is fine, and displays the records without any problem, however when you try to edit any record but the first, you get a "System.ArgumentNullException: Value cannot be null." error.
Here's the code in the controller for the edit function:
[HttpPost]
public ActionResult Edit(RecordsView rv)
{
if (ModelState.IsValid)
{
repository.EditRecord(rv.Records.FirstOrDefault().DogIncident);
}
return RedirectToAction("Index");
}
This is defined at the start of the cshtml file:
#using (Html.BeginForm("Edit", "Home", FormMethod.Post,new {#class="record-view"}))
And finally, here is how the HTML is generated on the view:
<li class="first" id="record-1805">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
<li class="record" id="record-1804">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
<li class="record" id="record-1803">
<form action="/Home/Edit" class="record-view" method="post">
<ul>
[form elements]
<li><input type="submit" style="margin: 18px 0;" value="Save"></li>
</ul>
</form>
</li>
Does anyone please know why I can only edit the first record that is displayed and not the others? Even if I go through the records using the next/back buttons and back to the first record to submit it, it updates fine, but updating any other record generates an error.
Referencing Darin's post: Pass a parameter to a controller using jquery ajax takes you halfway. He's using an input val in jQuery and passing it to the Controller Action.
Typically you'd provide one input link or #Html.ActionLink per record to be clicked for editing and MVC will bind to the controls parameter to your action (ID or what ever you want) just use the same name on the action link as the parameter and it will be mapped during the post.
data: { input: $('#caption').val() },
Change the signature of your controller action , or add another that takes an 'int' as shown below.
[HttpPost]
public ActionResult Edit(int ID = 0)
{
if (ModelState.IsValid)
{
repository.EditRecord(rv.Records.Where(r => r.ID == ID).DogIncident);
}
return RedirectToAction("Index");
}
Can you post the complete view so we can complete a solution ?
Was expecting the cshtml view. Here's an example:
#model IEnumerable<yourModelName>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.NID)
</th>
<th>
#Html.DisplayNameFor(model => model.CreatedOn)
</th>
<th>
#Html.DisplayNameFor(model => model.ExtensionAttribute15)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.yourElement1)
</td>
<td>
#Html.DisplayFor(modelItem => item.yourElement2)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
</td>
</tr>
}
</table>
#section Scripts{
<script type="text/javascript">
$("a#next").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":last-child")) {
return false;
}
nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
var nextli = $("li.first");
if ($(nextli).is(":first-child")) {
return false;
}
nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});
</script>
}

Use dropdownlistfor with foreach in Asp.Net MVC View?

I have a View with a foreach loop for a list property of the model. Now, I want to be able to let the user set the value of each of the items in the list using a dropdownlist. But I'm not sure how to do that. I've used something like this when it is not in a foreach loop:
#Html.DropDownListFor(model => model.Level, new SelectList(new[] { 1, 2, 3, 4, 5 }, Model.Level))
But how do I do this when I need to reference item.Level in the loop instead? Here's my View code:
<div id="formDiv">
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Ny arbetserfarenhet</legend>
<table>
<tr>
#*<th></th>*#
<th>
Program
</th>
<th>
Nivå
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#item.Program.Name
</td>
<td>
#item.Level
</td>
</tr>
}
</table>
</fieldset>
}
</div>
I have a View with a foreach loop for a list property of the mode
I would recommend you to avoid writing loops in your views in favor of editor templates. So:
#model IEnumerable<AppName.Models.ModelName>
<div id="formDiv">
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Ny arbetserfarenhet</legend>
<table>
<tr>
<th>
Program
</th>
<th>
Nivå
</th>
</tr>
#Html.EditorForModel()
</table>
</fieldset>
}
</div>
and in the corresponding editor template (~/Views/Shared/EditorTemplate/ModelName.cshtml):
#model AppName.Models.ModelName
<tr>
<td>#Model.Program.Name</td>
<td>
#Html.DropDownListFor(
model => model.Level,
new SelectList(
Enumerable.Range(1, 5).Select(x => new { Value = x, Text = x }),
"Value",
"Text"
)
)
</td>
</tr>
So the editor template will be rendered for each element in your model (which is a collection of some type). The important part is that the editor template must be located in ~/Views/Shared/EditorTemplates and named XXX.cshtml where XXX is the type name used in your main view model collection.
Have you tried:
#Html.DropDownListFor(m => item.Level, new SelectList(new[] { 1, 2, 3, 4, 5 }, item.Level))
use this syntax:
#Html.DropDownListFor(model => model.Level, new SelectList(Model.level as System.Collections.IEnumerable, "VALUE_FIELD", "TEXT_FIELD", YOUR PROPERTY NAME)
MVC will create the loop. Just use an editor template, partial view in special folder, and the rest works like magic.
Editor Template
#model Models.AdditionalAccountingLine
#Html.HiddenFor(m => m.IsRequired)
#Html.DropDownListFor(m => m.FieldValue, new SelectList(#Model.FieldValueOptions, "Key", "Value"), "")
View
#Html.EditorFor(m => m.AdditionalAccountingLines);

Resources