How to get Auto-completion in ASP.NET MVC? - asp.net-mvc

In ASP.NET MVC, we don't have controls which can do stuffs such as autocompletion (we don't have controls at all from Visual Studio like in web forms).
But, Is it possible to still get 'Auto-completion' with a text box in ASP.NET MVC (like with the textbox found on the Google's Home page)?
If this is the case, what's the best way to do so? JQueryUI? or there's someother way of getting that functionality?
Thanks for helping.

You mean like the one in the jquery ui?
http://jqueryui.com/demos/autocomplete/

To use JQuery Autocomplete with ASP.NET MVC you can do the following:
Step 1 : Create the textbox
<%= Html.TextBox("searchBox",null,new { #class="large", autocomplete="on"}) %>
Step 2 : Create action to do search function (I am using NHibernate to query DB, but the key is to return an string with each result delimited by a newline)
public ActionResult Autocomplete(string q) {
var programs = programRepository
.Search(q)
.ToList()
.ConvertAll(x => x.ProgramName)
.ToArray();
return new ContentResult {Content = string.Join("\n", programs) };
}
Step 3: turn on autocomplete functionality in your HTML (place inside a script block)
$(document).ready(function() {
$('#searchBox').autocomplete("/Controller/Autocomplete", { autoFill: true, minChars: 2 });
});

Related

Can I Convert a Index.cshtml in asp.net MVC to PDF using html2pdf?

I am facing a problem in converting a view in asp.net MVC to PDF using html2pdf library and jquery,
so please can anyone help ?
thanks in advance.
I'm using Rotativa, it's seems good
Rotativa is an open source package which uses the web kit engine which is used by Chrome browser to render the HTML. Most of the HTML tags and styles are supported by this framework.
it contains many classes you can use to convert to pdf like :
ActionAsPdf
PartialViewAsPdf
UrlAsPdf
ViewAsPdf
for example
<div style="text-align:right">#Html.ActionLink("Print Employee",
"PrintEmployee", new { id=Model.ID })</div>
public ActionResult PrintEmployee(int id)
{
var report = new Rotativa.ActionAsPdf("Employee", new { id=id });
return report;
}

How to get claim inside Asp.Net Core Razor View

I did it in my rc1 project like:
User.Claims.ElementAt(#).Value
But after I switched to rtm it wouldn’t work anymore. When I debug the Razor view the object looks the same but User.Claims is just empty. Any idea what the reason could be.
Assuming you have claims attached to the current principal. In your Razor view:
#((ClaimsIdentity) User.Identity)
This will give you access to the ClaimsIdentity of the current user. In an effort to keep your claims fetching clean you may want to create an extension method for searching claims.
public static string GetSpecificClaim(this ClaimsIdentity claimsIdentity, string claimType)
{
var claim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == claimType);
return (claim != null) ? claim.Value : string.Empty;
}
Then you can just access whatever claim you want with:
#((ClaimsIdentity) User.Identity).GetSpecificClaim("someclaimtype")
Hope this helps.
Quick search for claims identity in razor view came up with a similar question and answer:
MVC 5 Access Claims Identity User Data
Tested in .net core 2.2
in the razor page :
#User.FindFirst("nameOfClaim").Value
In Core 3.0, use view authorization.
In Startup.cs:
services.AddAuthorization(options =>
{
options.AddPolicy("Policy_Name", x => x.RequireClaim("Policy_Name"));
});
At the top of your UI file where you are inserting the conditional element, insert:
#using Microsoft.AspNetCore.Authorization
#inject IAuthorizationService AuthorizationService
Then inside the body use:
#if ((await AuthorizationService.AuthorizeAsync(User, "Policy_Name")).Succeeded){
//show ui element
}
View-based authorization in ASP.NET Core MVC
You can achieve this with the following code in your view :
if(User.FindFirst("MyClaim")?.Value == "some_value")
{
... Show concerned UI block
}
Altough, if you use policies (as it's the recommended way), I suggest to define policies in your Startup.cs/Program.cs and use injected IAuthorizationService to call AuthorizeAsync :
if((await AuthorizationService.AuthorizeAsync(User, "MyClaim")).Succeeded)
{
... Show concerned UI block
}
This way is better as it use defined policies, which can validates many different values.

Replace partialview after action in ASP.Net MVC

I'm still quite new to ASP.NET MVC and wonder how-to achieve the following:
On a normal view as part of my master page, I create a varying number of partial views with a loop, each representing an item the user should be able to vote for. After clicking the vote-button, the rating shall be submitted to the database and afterwards, the particular partial view which the user clicked shall be replaced by the same view, with some visual properties changed. What is the best practice to achieve this?
Here's how I started:
1. I defined the partial view with an if-sentence, distinguishing between the visual appearance, depending on a flag in the particular viewmodel. Hence, if the flag is positive, voting controls are displayed, if it's negative, they're not.
I assigned a Url.Action(..) to the voting buttons which trigger a controller method. In this method, the new rating is added to the database.
In the controller method, I return the PartialView with the updated ViewModel. UNFORTUNATELY, the whole view get's replaced, not only the partial view.
Any suggestions how-to solve this particular problem or how-to achieve the whole thing would be highly appreciated.
Thanks very much,
Chris
Trivial (but by all means correct and usable) solution to your problem is Ajax.BeginForm() helper for voting. This way you change your voting to ajax calls, and you can easily specify, that the result returned by this call (from your voting action, which will return partial view with only 1 changed item) will be used to replace old content (for example one particular div containing old item before voting).
Update - 11/30/2016
For example:
#using (Ajax.BeginForm("SomeAction", "SomeController", new { someRouteParam = Model.Foo }, new AjaxOptions { UpdateTargetId = "SomeHtmlElementId", HttpMethod = "Post" }))
ASP.NET MVC is a perfect framework for this kind of needs. What I would do if I were in your possition is to work with JQuery Ajax API.
Following blog post should give you a hint on what you can do with PartialViews, JQuery and Ajax calls to the server :
http://www.tugberkugurlu.com/archive/working-with-jquery-ajax-api-on-asp-net-mvc-3-0-power-of-json-jquery-and-asp-net-mvc-partial-views
UPDATE
It has been asked to put a brief intro so here it is.
The following code is your action method :
[HttpPost]
public ActionResult toogleIsDone(int itemId) {
//Getting the item according to itemId param
var model = _entities.ToDoTBs.FirstOrDefault(x => x.ToDoItemID == itemId);
//toggling the IsDone property
model.IsDone = !model.IsDone;
//Making the change on the db and saving
ObjectStateEntry osmEntry = _entities.ObjectStateManager.GetObjectStateEntry(model);
osmEntry.ChangeState(EntityState.Modified);
_entities.SaveChanges();
var updatedModel = _entities.ToDoTBs;
//returning the new template as json result
return Json(new { data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) });
}
RenderPartialViewToString is an extension method for controller. You
need to use Nuget here to bring down a very small package called
TugberkUg.MVC which will have a Controller extension for us to convert
partial views to string inside the controller.
Then here is a brief info on how you can call it with JQuery :
var itemId = element.attr("data-tododb-itemid");
var d = "itemId=" + itemId;
var actionURL = '#Url.Action("toogleIsDone", "ToDo")';
$("#ajax-progress-dialog").dialog("open");
$.ajax({
type: "POST",
url: actionURL,
data: d,
success: function (r) {
$("#to-do-db-list-container").html(r.data);
},
complete: function () {
$("#ajax-progress-dialog").dialog("close");
$(".isDone").bind("click", function (event) {
toggleIsDone(event, $(this));
});
},
error: function (req, status, error) {
//do what you need to do here if an error occurs
$("#ajax-progress-dialog").dialog("close");
}
});
There needs to be some extra steps to be taken. So look at the blog post which has the complete walkthrough.

ASP.NET MVC, a plugin architecture and id collisions

So I have been waxing lyrical about a ASP.NET MVC to a friend who is about to start development of a new user interface....
He asked me if you could solve the following problem with ASP.NET MVC:
Imagine a web app that supports plugins. In the current ASP.NET WebForms app the pluggin developer provides a usercontrol and some JQuery.
The IDs of the controls are unique so that the JQuery can always select the correct DOM elements and so that the code behind can deal with the correct control collections.
I suggested that in MVC since we can have any number of forms... each plugin could be implemented as a partialView.
Each partialView would be wrapped by its own form so the relevant Controller Action and therefore would only receive form data defined in the partialView - so from this point of view we dont care about DOM id collisions.
However the HTML would be invalid if ID collision did occur and hence JQuery written by the plugin developer could fail!
I'm not sure how we could get round this...
I dont like the idea of parsing the partialView for collisions when the plugin is added and I dont like the idea of restricting the ids that the plugin developer has access to.
Maybe the the ids could be augmented with a prefix at run time and the model binders could be provided with this prefix?
You could just wrap the contents of the plugin within a DIV or FORM element and give that a unique ID on the page. Then just use jQuery to only select elements that are within this "parent" DIV or FORM element.
You could probably auto generate a GUID to use as the unique ID at runtime, but this would require some effort by the person writing the plugin. Although, you could probably architect it out in a way to make it automatically generate the "parent" DIV and ID, then you could just access the ID within the view as a Property of the Plugin.
Just some thoughts, I haven't built a an ASP.NET MVC plugin based system like this yet, but it doesn't seem too difficult.
Here's an example of a PartialView that uses a custom ViewUserControl base class:
ViewUserControl1.ascx:
<%# Control Language="C#" Inherits="MvcPluginPartialView.PluginViewUserControl" %>
<input class="txtText" type="text" value="<%=this.ID %>" />
<input class="txtButton" type="button" value="Show Alert" />
<script type="text/javascript">
jQuery(function() {
// This is the Unique ID of this Plugin on the Page
var pluginID = "<%=this.ID %>";
// Attach the OnClick event of the Button
$("#" + pluginID + " .txtButton").click(function() {
// Display the content of the TextBox in an Alert dialog.
alert($("#" + pluginID + " .txtText").val());
});
});
</script>
MvcPluginPartialView.PluginViewUserControl:
namespace MvcPluginPartialView
{
public class PluginViewUserControl : ViewUserControl
{
public PluginViewUserControl()
{
this.ID = "p" + Guid.NewGuid().ToString().Replace("-", "");
}
public override void RenderView(ViewContext viewContext)
{
viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);
//this.ID = Guid.NewGuid().ToString();
RenderViewAndRestoreContentType(containerPage, viewContext);
}
internal static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext)
{
string contentType = viewContext.HttpContext.Response.ContentType;
containerPage.RenderView(viewContext);
viewContext.HttpContext.Response.ContentType = contentType;
}
private sealed class ViewUserControlContainerPage : ViewPage
{
public ViewUserControlContainerPage(ViewUserControl userControl)
{
this.Controls.Add(userControl);
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("<div id='" + this.Controls[0].ID + "'>");
base.Render(writer);
writer.Write("</div>");
}
}
}
}
Then to place the View on the page you can use the "Html.RenderPartial" method as usual, plus you can place as many of them on the Page as you want and they'll all work as expected.
<%Html.RenderPartial("ViewUserControl1"); %>
<%Html.RenderPartial("ViewUserControl1"); %>
<%Html.RenderPartial("ViewUserControl1"); %>

MVC User Controls + ViewData

Hi im new to MVC and I've fished around with no luck on how to build MVC User Controls that have ViewData returned to them. I was hoping someone would post a step by step solution on how to approach this problem. If you could make your solution very detailed that would help out greatly.
Sorry for being so discrete with my question, I would just like to clarify that what Im ultimatly trying to do is pass an id to a controller actionresult method and wanting to render it to a user control directly from the controller itself. Im unsure on how to begin with this approach and wondering if this is even possible. It will essentially in my mind look like this
public ActionResult RTest(int id){
RTestDataContext db = new RTestDataContext();
var table = db.GetTable<tRTest>();
var record = table.SingleOrDefault(m=> m.id = id);
return View("RTest", record);
}
and in my User Control I would like to render the objects of that record and thats my issue.
If I understand your question, you are trying to pass ViewData into the user control. A user control is essentially a partial view, so you would do this:
<% Html.RenderPartial("someUserControl.ascx", viewData); %>
Now in your usercontrol, ViewData will be whatever you passed in...
OK here it goes --
We use Json data
In the aspx page we have an ajax call that calls the controller. Look up the available option parameters for ajax calls.
url: This calls the function in the class.(obviously) Our class name is JobController, function name is updateJob and it takes no parameters. The url drops the controllerPortion from the classname. For example to call the updateJob function the url would be '/Job/UpdateJob/'.
var data = {x:1, y:2};
$.ajax({
data: data,
cache: false,
url: '/ClassName/functionName/parameter',
dataType: "json",
type: "post",
success: function(result) {
//do something
},
error: function(errorData) {
alert(errorData.responseText);
}
}
);
In the JobController Class:
public ActionResult UpdateJob(string id)
{
string x_Value_from_ajax = Request.Form["x"];
string y_Value_from_ajax = Request.Form["y"];
return Json(dataContextClass.UpdateJob(x_Value_from_ajax, y_Value_from_ajax));
}
We have a Global.asax.cs page that maps the ajax calls.
public class GlobalApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "EnterTime", action = "Index", id = "" } // Parameter defaults (EnterTime is our default controller class, index is our default function and it takes no parameters.)
);
}
}
I hope this gets you off to a good start.
Good luck
I am pretty sure view data is accessible inside user controls so long as you extend System.Web.Mvc.ViewUserControl and pass it in. I have a snippet of code:
<%Html.RenderPartial("~/UserControls/CategoryChooser.ascx", ViewData);%>
and from within my CategoryChooser ViewData is accessible.
Not sure if I understand your problem completely, but here's my answer to "How to add a User Control to your ASP.NET MVC Project".
In Visual Studio 2008, you can choose Add Item. In the categories at the left side, you can choose Visual C# > Web > MVC. There's an option MVC View User Control. Select it, choose a name, select the desired master page and you're good to go.

Resources