#Html.AntiForgeryToken() with url.Action() - c#

There is method in controller:
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult RemoveFlag(Guid[] selected)
{
_presenter.RemoveFlag(selected);
return Json(new { Success = true });
}
It works fine with:
#using (Html.BeginForm("RemoveFlag", "controller", new { Area = "Area" }, FormMethod.Post))
{
#Html.AntiForgeryToken();
...
...
...
}
But this method is also used in my project's code with #Url.Action():
<ul>
<li>
<a
href="#Url.Action("RemoveFlag", "controller", new { Area = "Area"})"
data-target="km_grid_body"
data-redirect="#Url.Action("ManageCollections", "controller", new { Area = "Area" })"
>
Remove flag
</a>
</li>
</ul>
And this code doesn't work. Is there any ways to use Anti Forgery token validation within the #Url.Action()?

Related

Passing Value to Controller in .Net Core

I have a requirement to pass value from view to controller in the Html.BeginForm()
#using (Html.BeginForm("ChangeRole", "Login", null, FormMethod.Post, null, new { id = "SubmitRole" }))
{
#Html.AntiForgeryToken()
#foreach (var item in (#HttpContextAccessor.HttpContext.Session.GetObjectFromJson<UserRoleLevelDetails>("GetAllUsersList")))
{
//..
if (#vr != #HttpContextAccessor.HttpContext.Session.GetString("Role").ToString())
{
<a class="#vr" id=#string.Format("{0}", #item.Role_Level_Name) onclick="Change_Role(this)">#vr</a><br />
}
//..
}
}
function Change_Role(e) {
var ChangedRole = $(e).attr('class');
$('#UserMainRole').val(ChangedRole);
$("#SubmitRole").submit();
e.preventDefault();
};
So, while submitting I need to pass value of ChangedRole to the controller.

MVC Ajax Partial View call returns partialview site without "parent"

i worked on a partial reload page via Ajax.
This is what i have:
Controller:
public class EmailController : Controller
{
//
// GET: /Email/
[Authorize]
public ActionResult Index(string id)
{
//.. Some Code here to get my Email List
return View(emails);
}
[Authorize]
public PartialViewResult EmailPartial(string id = "1,2")
{
//.. Some Code here to get my Email List with the new filter
return PartialViewResult(emails);
}
}
Main View:
#model IEnumerable<namespace.Emailgesendetview>
#{
ViewBag.Title = "Index";
AjaxOptions ajaxOpts = new AjaxOptions
{
UpdateTargetId = "emailBody"
};
Layout = "~/Views/Shared/_Default.cshtml";
}
// .... uninteresting html code
<div id="emailBody">
#Html.Action("EmailPartial", new { selectedRole = Model })
</div>
// .... uninteresting html code
// Here comes my action link:
<li>
#Ajax.ActionLink("martin",
"EmailPartial",
"Email",
new { id = "3"},
new AjaxOptions()
{
HttpMethod = "GET",
AllowCache = false,
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "emailBody"
})
</li>
Partial View:
#model IEnumerable<namespace.Emailgesendetview>
<div class="mail-body">
<ul class="mail-list">
#{
foreach (var userMail in Model)
{
//... Code vor showing the models
}
}
</ul>
</div>
If i click on the link now, he starts the function: EmailPartial, but he didn't add (or replace i tryed both) the content. He Opens the EmailPartial view alone?!
In this post:
How to render partial view in MVC5 via ajax call to a controller and return HTML
the Partial function is not a PartialViewResult it's a ActionResult, but i already tryd that.
Would be great i you could show me my error or misstake.
Thanks a lot and have a nice day :)
Because you have not included jquery-unobtrusive-ajax.js in your view or layout so its making a normal redirect. – Stephen Muecke Mar 31 at 10:30

ViewBag for video upload?

I am working with sample from codeproject http://www.codeproject.com/Tips/1011040/Upload-and-Delete-Video-File-to-Microsoft-Azure-Bl
I have created an index.cshtml in the way of
that is
#model List<string>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("Add", "Blob", FormMethod.Post, new
{enctype = "multipart/form-data" }))
{
<div>
<input type="file" name="pic" id="pic" />
<input type="submit" value="Upload Now" id="s1" />
</div>
}
<ul>
#foreach (var item in Model)
{
<li>
<input type="button" name="b1" id="b1"
value="Delete"
onclick="Remove('#item')" />
<video src="#item" height="200" width="200" controls />
</li>
}
</ul>
#section scripts{
<script>
function Remove(x) {
alert(x);
var uri = "/Blob/remove";
$.post(uri, { name: x }, function (y) {
window.location.href = "/blob/index";
alert(y);
});
}
</script>}
and my Controller class is :
public class BlobsController : Controller
{
//
// GET: /Blobs/
BlBlobs objbl = new BlBlobs();
public ActionResult Index()
{
//return View();
return View(objbl.GetBlobList());
}
[HttpPost]
public ActionResult Add(HttpPostedFileBase pic)
{
objbl.AddBlob(pic);
return RedirectToAction("Index");
}
[HttpPost]
public string Remove(string name)
{
objbl.DeleteBlob(name);
return "Blob Removed Successfully";
}
}
That give me pretty nice browse/upload form, but fails on upload click with 404 error. The question is - how to call the add method correctly in this index.cshtml file?
Your controller is called BlobsController so that would give you a route of /blobs/{action} with the default route, however in your view your actions are looking for a controller called blob. Either change the name of your controller
public class BlobController : Controller
{
//...
}
Or update your views to use the correct controller name.
Html.BeginForm("Add", "Blobs", FormMethod.Post, new
{enctype = "multipart/form-data" }))

ASP MVC5 Partial view authentification redirection

I'm quite new with ASP so be tolerant :)
I've got a view with a search form in it.
View
<div id="search-form" class="row search-form">
#using(Ajax.BeginForm("Search",
"Home",
new AjaxOptions
{
UpdateTargetId = "result",
InsertionMode = InsertionMode.Replace,
LoadingElementId = "ajax_loader"
},
new { #class = "form-horizontal col-sm-offset-3 col-sm-6" }
))
{
<div class="form-group">
<div class="col-sm-10">
#{string query = string.Empty;}
#Html.EditorFor(x => query, new { htmlAttributes = new { #class = "form-control" } })
</div>
<input id="submitbtn" type="submit" value="Search" class="btn btn-primary col-sm-2" />
</div>
}
</div>
<div id="ajax_loader" style="display:none">
<img src="~/Content/Images/ajax_loader.gif" alt="Ajax Loader" />
</div>
<div id="result"></div>
Controller
[AllowAnonymous]
public ActionResult Index()
{
ViewBag.Title = "serach form";
return View();
}
public async Task<ActionResult> Search(string query)
{
WinesApiController winesCtrl = new WinesApiController();
var listOfWines = await winesCtrl.Get(query);
return PartialView("_WineResult", listOfWines);
}
The Search method in my controller returns a PartialView. When I decorate all the methodsin the controller with the [AllowAnonymous] attribute, everything works very well. But what I would like it to display the form for anybody, but as long as you click on the search button, you need to be logged in. So I deleted all the AllowAnonymous attributes but on the Index method (the one which render my View). Now, the result of my call is not shown anymore (which is quite ok) but I am not redirected to the login view.
My question is then, why the call to the partial view does not redirect me to the login view ? I guess that authentification is performed because I cannot see the results of the submit action, but why am I not redirected ?
You are making an ajax call to the Search Action right? The default asp.net mvc AuthorizeAttribute does not return an appropriate response when authorization fails on ajax calls.
You could write your own Authorization Filter, that returns a better response, like this:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public sealed class YourAuthorizeAttribute : AuthorizeAttribute {
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
var httpContext = filterContext.HttpContext;
var request = httpContext.Request;
var response = httpContext.Response;
if (request.IsAjaxRequest()) {
response.SuppressFormsAuthenticationRedirect = true;
response.StatusCode = (int)HttpStatusCode.Unauthorized;
response.End();
}
base.HandleUnauthorizedRequest(filterContext);
}
}
With this filter, you could have a default javascript code to handle all unauthorized scenarios:
$.ajaxSetup({
statusCode: {
401: function (response) {
var returnUrl = encodeURI(window.location.pathname + window.location.search);
var loginUrl = '/custumer/login?ReturnUrl=' + returnUrl;
window.location.href = loginUrl;
}
}
});
What happens if you put an Authorize attribute on the action?
[Authorize()]
public async Task<ActionResult> Search(string query)
{
WinesApiController winesCtrl = new WinesApiController();
var listOfWines = await winesCtrl.Get(query);
return PartialView("_WineResult", listOfWines);
}

Get Button Id on the controller using Ajax.BeginForm

The Objective:
I have a post with an Ajax.BeginForm and my objective is to get The Button Id on the controller. I've seen examples using Html.BeginForm, But I need an Ajax form,
The Code: C# MVC3
View:
#using (Ajax.BeginForm("Save", "Valoration", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "HvmDetailTabStrip", OnSuccess = "OnSuccessSaveValoration" }))
{
<div id ="HvmDetailTabStrip">
#(Html.Partial("_ValorationDetail"))
</div>
<button type="submit" style="display:none" id="db1"></button>
<button type="submit" style="display:none" id="db2"></button>
}
Controller:
[HttpPost]
public ActionResult Save(ValorationModel model)
{
if ("db1")
{
var result = ValorationService.Save(ValorationModel);
}
else
{
// ....
}
return PartialView("_ValorationDetail", ValorationModel);
}
You can get your buttons' values like this:
#using (Ajax.BeginForm("Save", "Valoration", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "HvmDetailTabStrip", OnSuccess = "OnSuccessSaveValoration" }))
{
<div id ="HvmDetailTabStrip">
#(Html.Partial("_ValorationDetail"))
</div>
<button type="submit" name="submitButton" value="db1"></button>
<button type="submit" name="submitButton" value="db2"></button>
}
And in your controller you can write:
[HttpPost]
public ActionResult Save(ValorationModel model)
{
string buttonValue = Request["submitButton"];
if(buttonValue == "db1"){
var result = ValorationService.Save(ValorationModel);
}else
{
....
}
return PartialView("_ValorationDetail", ValorationModel);
}
Or if count of parameters you pass in method doesn't matter, you can use this:
[HttpPost]
public ActionResult Save(ValorationModel model, string submitButton)
{
if(submitButton == "db1"){
var result = ValorationService.Save(ValorationModel);
}else
{
....
}
return PartialView("_ValorationDetail", ValorationModel);
}
Other way how you can solve your problem is here ASP.Net MVC - Submit buttons with same value

Categories