I made a list with the following MVC5 C# code to create the menu
public ActionResult List()
{
List<Menu> entity = _menuService.List();
List<MenuModel> model = new List<MenuModel>();
foreach (var item in entity)
{
model.Add(new MenuModel() {
Id = item.Id,
Title = item.Title,
Priority = item.Priority
});
}
return PartialView("_List",model);
}
Next, I used the following Razor in the Index document
<h2>Menu List</h2>
<a class="badge , btn btn-success" href="/Dashboard/Menu/Create">
Create Menu
</a>
<hr />
#Html.Action("List", "Menu", new { area = "Dashboard"})
Now how can I use bootstrap classes for this Razor
Related
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()?
I am a beginner in ASP.Net MVC Web Development. And I am stuck at one place where I need to have POST request For EDIT and Delete Requests in the same page.
Behavior:
I have a page with many rows shown in tabular format, Now for each row I wanted to have "Delete", "Edit", and "Details" Button. I have done that successfully. But I read that we should never have a "GET" Request for Deleting and Editing a resource.
Issue:
I know how to make a POST Form using #Html.BeginForm(....FormMethod.POST,..), But I am confused in my case because I have many rows with each row having "Edit" and "Delete".
Below is my Attempt:
Parent View:
#model IEnumerable<Bridge.Models.Resume>
#using Bridge.ViewModels
<table class="table">
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.datetime)
</td>
#Html.Partial("_TableButtonsPartial", new SmallButtonViewModel
{
ResumeId = item.ResumeId
})
</tr>
}
</table>
TableButtonPartial View:
#model Bridge.ViewModels.SmallButtonViewModel
#using Bridge.ViewModels
<td style="width: 120px;">
<div class="btn-group" role="group">
#Html.Partial("_SmallButtonPartial",
new SmallButtonViewModel
{
Action = "Edit",
ButtonType = "btn-primary",
Glyph = "pencil",
Text = "Edit button",
ReferralId = Model.ReferralId,
})
#Html.Partial("_SmallButtonPartial",
new SmallButtonViewModel
{
Action = "Details",
ButtonType = "btn-success",
Glyph = "list",
Text = "Detail button",
ResumeId = Model.ResumeId,
})
#Html.Partial("_SmallButtonPartial",
new SmallButtonViewModel
{
Action = "Delete",
ButtonType = "btn-danger",
Glyph = "trash",
Text = "Delete button",
ResumeId = Model.ResumeId,
})
</div>
</td>
SmallButtonPartial View
#model Bridge.ViewModels.SmallButtonViewModel
<a type="button" class="btn #Model.ButtonType btn-sm"
href="#Url.Action(Model.Action)#Model.ActionParameters">
<span class="glyphicon glyphicon-#Model.Glyph">
</span><span class="sr-only">#Model.Text</span>
</a>
SmallButton ViewModel
public class SmallButtonViewModel
{
public string Action { get; set; }
public string Text { get; set; }
public string Glyph { get; set; }
public string ButtonType { get; set; }
public int? ResumeId { get; set; }
public string ActionParameters
{
get
{
var param = new StringBuilder("?");
if (ResumeId != null & ResumeId > 0)
param.Append(string.Format("{0}={1}&", "resumeId", ResumeId));
return param.ToString().Substring(0, param.Length - 1);
}
}
}
Controller
public FileContentResult Details(int? resumeId)
{
var temp = _context.Resumes.Where(f => f.ResumeId == resumeId).SingleOrDefault();
var fileRes = new FileContentResult(temp.Content.ToArray(), temp.ContentType);
fileRes.FileDownloadName = temp.FileName;
return fileRes;
}
// Todo: Need to make it a POST Request
public ActionResult Delete(int? resumeId)
{
var r = _context.Resumes.Where(c => c.ResumeId == resumeId);
_context.Resumes.RemoveRange(r);
_context.SaveChanges();
return RedirectToAction("ResumeCenter");
}
My Thinking
I want to be able to do something like below in SmallButtonView :
#model Bridge.ViewModels.SmallButtonViewModel
#Html.BeginForm(..,FormMethod.POST,..) // but I am not sure how to achieve it?
You would start by making sure the Delete action could only be reached by a POST request, using the HttpPostAttribute:
[HttpPost]
public ActionResult Delete(int? resumeId)
{
var r = _context.Resumes.Where(c => c.ResumeId == resumeId);
_context.Resumes.RemoveRange(r);
_context.SaveChanges();
return RedirectToAction("ResumeCenter");
}
Once you add that attribute, any attempts to issue a GET request to that action will result in a 404 (Not Found) response.
Then, replace this:
#Html.Partial("_SmallButtonPartial",
new SmallButtonViewModel
{
Action = "Delete",
ButtonType = "btn-danger",
Glyph = "trash",
Text = "Delete button",
ResumeId = Model.ResumeId,
})
with something like:
#using(Html.BeginForm("delete", "your controller name", FormMethod.Post, new { #class="delete-form" }))
{
<input type="hidden" name="ResumeId" value="#Model.ResumeId" />
<button type="submit" class="btn btn-danger">
<span class="glyphicon glyphicon-trash"></span>
Delete
</button>
}
You can have as many forms on a page as you like, as long as they are not nested - this generates a form on each row. I added a class here (delete-form) that you could use to hook into a jQuery event, if you wanted to handle this via AJAX instead of allowing the form to submit.
Any other actions, like "view" or "edit", would still just be GET requests, which you can leave as anchors, or use forms with the method set to GET (the end result is the same).
I have an app which has two listboxes:
#using (Html.BeginForm())
{
#Html.ListBoxFor(m => m.SelectedAttributes, Model.Attributes, new {id="listBoxAvail", SIZE = 5} )
<button type="button" id="add">MoveRight</button>
<button type="button" id="remove">"MoveLeft"></button>
<button type="button" id="remove-all">RemAll</button>
<button type="button" id="select-all">SelAll</button>
<button type="button" id="up" onclick="MoveUp()">Up</button>
<button type="button" id="down" onclick="MoveDown()">Down</button>
#Html.ListBoxFor(m => m.SelectedAttributes2, Model.SelectedItems, new { id = "listBoxSel", SIZE = 5})
<br />
<p>Item Caption Text (140 Characters. HTML not allowed.)</p>
#Html.TextAreaFor(m => m.ItemCaptionText)
<input type="submit" id="submit" value="Save"/>
}
I transfer the selected values from one listbox to the other using jQuery but I append an "L" to the value for later use:
$("#add").click(function () {
$("#listBoxAvail > option:selected").each(function () {
$(this).remove();
val = $(this).val();
temp = $(this);
temp.val('L' + val)
$(temp).appendTo("#listBoxSel");
});
});
I see the Text and Value after I transfer to the right hand listbox with the F12 Developer Tools. What I would to know is how to get that value from C# code in the Controller?
[HttpPost]
public ActionResult Index(OptInViewModel viewModel)
{
AttributeEntities db = new AttributeEntities();
IEnumerable<string> items = viewModel.SelectedAttributes2;
foreach (var item in items)
{
var temp = item;
// Save it
SelectedHarmonyAttribute attribute = new SelectedHarmonyAttribute();
attribute.CustomLabel = viewModel.ItemCaptionText;
//attribute.IsVisible = ?
//attribute.OrderNumber = ?
//attribute.HarmonyAttribute_ID
}
return View("Index");
}
The ViewModel is:
public class OptInViewModel
{
public IEnumerable<string> SelectedAttributes { get; set; }
public IEnumerable<string> SelectedAttributes2 { get; set; }
public IEnumerable<SelectListItem> Attributes { get; set; }
public IEnumerable<SelectListItem> SelectedItems { get; set; }
public string ItemCaptionText { get; set; }
}
I don't fully understand your question, but from what I gather you're trying to pass a parameter to a function call in MVC. Parameters can be added to URLs much like in PHP.
For example a function could be defined as
void Function (string value);
and the URL to call it would be
~/Controller/Function?value=HelloWorld
You can also set up routing. See this answer on StackOverflow for more information:
ASP.NET MVC - passing parameters to the controller
Edit: I see you're trying to use Form submission
Make sure you correctly format your view, not forgetting :
#model Path.To.Model
and controller information:
using (#Html.BeginForm("myMethod", "Controller", FormMethod.Post))
I am trying to display a Partial View inside a master (Index) View:
Steps:
User selects a Dropdown item from the Index View.
This displays a Partial View that has a search Form.
User fills the search Form and then clicks the Submit button.
If the search Form is valid, a new page (Results View) is displayed.
Else, the search Form Partial View should be re displayed with errors INSIDE the master View
I'm having a problem with number 4 because when the search Form submits, it only displays the partial View in a new window. I want to display the whole page : Index View + Partial View with errors.
Suggestions? This is what I have:
Image
Controller
public class AppController : Controller
{
public ActionResult Index()
{
return View(new AppModel());
}
public ActionResult Form(string type)
{
if (type == "IOS")
return PartialView("_IOSApp", new AppModel());
else
return PartialView("_AndroidApp", new AppModel());
}
public ActionResult Search(AppModel appModel)
{
if (ModelState.IsValid)
{
return View("Result");
}
else // This is where I need help
{
if (appModel.Platform == "IOS")
return PartialView("_IOSApp", appModel);
else
return PartialView("_AndroidApp", appModel);
}
}
}
Model
public class AppModel
{
public string Platform { get; set; }
[Required]
public string IOSAppName { get; set; }
[Required]
public string AndroidAppName { get; set; }
public List<SelectListItem> Options { get; set; }
public AppModel()
{
Initialize();
}
public void Initialize()
{
Options = new List<SelectListItem>();
Options.Add(new SelectListItem { Text = "IOS", Value = "I" });
Options.Add(new SelectListItem { Text = "Android", Value = "A"});
}
}
Index.cshtml
#{ ViewBag.Title = "App Selection"; }
<h2>App Selection</h2>
#Html.Label("Select Type:")
#Html.DropDownListFor(x => x.Platform, Model.Options)
<div id="AppForm"></div> // This is where the Partial View goes
_IOSApp.cshtml
#using (Html.BeginForm("Search", "App"))
{
#Html.Label("App Name:")
#Html.TextBoxFor(x => x.IOSAppName)
<input id="btnIOS" type="submit" value="Search IOS App" />
}
AppSearch.js
$(document).ready(function () {
$("#Platform").change(function () {
value = $("#Platform :selected").text();
$.ajax({
url: "/App/Form",
data: { "type": value },
success: function (data) {
$("#AppForm").html(data);
}
})
});
});
You need to call the search method by ajax too.
Change the index.html and then
1- if Form is valid replace the whole html or the mainContainer( The div that i have added to view).
2- else just replace the partial view.
#{ ViewBag.Title = "App Selection"; }
<div id="mainContainer">
<h2>App Selection</h2>
#Html.Label("Select Type:")
#Html.DropDownListFor(x => x.Platform, Model.Options)
<div id="AppForm"></div> // This is where the Partial View goes
</div>
Remove the form tag from your partial view just call an ajax call method for searching.
May be easiest way to handle this problem is using MVC unobtrusive ajax.
I would say use inline Ajax to submit this form.
#using (Html.BeginForm("Search", "App"))
{
#Html.Label("App Name:")
#Html.TextBoxFor(x => x.IOSAppName)
<input id="btnIOS" type="submit" value="Search IOS App" />
}
change upper given code into following code
#using (
Ajax.BeginForm(
"Form", "App",
new AjaxOptions()
{
UpdateTargetId = "App",
HttpMethod = "Post"
}
)
)
{
<div class="editor-label">
#Html.Label("App Name:")
</div>
<div class="editor-field">
#Html.TextBoxFor(x => x.IOSAppName)
</div>
<input id="btnIOS" type="submit" value="Search IOS App" />
}
//in controller change the parameter of the given method from string type to model object which will be posted by ajax form.
public ActionResult Form(AppModel appModel)
{
if (appModel.type == "IOS")
return PartialView("_IOSApp", new AppModel());
else
return PartialView("_AndroidApp", new AppModel());
}
How can I make the following code be a list of links instead of a list of buttons?
#foreach (var item in #Model)
{
using (Html.BeginForm(new { action = "GetL", controller = "L" }))
{
<input name="fileLocation" type="submit" value="#item" />
}
}
#foreach (var item in #Model)
{
using (Html.BeginForm(new { action = "GetL", controller = "L" }))
{
<a name="fileLocation" href="#item">#item</a>
}
}
You can use Html.ActionLink helper method to generate anchor tag
#foreach (var item in #Model)
{
using (Html.BeginForm(new { action = "GetL", controller = "L" }))
{
#Html.ActionLink(item,"yourAction","YourController")
}
}
If you want to pass some parameters ( Ex : Id ) to the Action method, you can do it with this override
#Html.ActionLink(item,"yourAction","YourController",
new { #id="someVal"} ,null)