Asp Mvc 4 : Add Child to new Parent - asp.net-mvc-4

I need some help,
I'll do it simply. I have an object Client that has many Appointments. Something Like:
public partial class Client
{
...
public virtual IList<Appointment> Appointments{ get; set; }
}
Is there a way in asp to create a new client with appointments in same page?
P.S: For now, I can add appointments to an existing customer by passing to a partialview the Client id and using ajax and partialView. But, new clients haven't Id. What I've to do?
UPDATE : Precisions
This is what I've in my edit view:
<p>
#Ajax.ActionLink("NewMeeting", "NewAppointmentFrm", new { clientId = Model.Id }, new AjaxOptions { UpdateTargetId = "appointmentPopup", OnSuccess = "displayFormInPopup('#appointmentPopup','" + "NewMeeting") + "',600,'auto');" })
</p>
<div style="display:none;width:600px" id="appointmentPopup"></div>
In the controler I have
Appointment appointment = new Appointment()
{
Client = GetClientById(clientId)
};
return PartialView("NewAppointmentFrm", appointment);
And by submitted the PartialView (NewAppointmentFrm - Appointments Details), I do :
public ActionResult CreateClientAppointment(int clientId, Appointment appointment)
{
var client = GetClientById(clientId);
client.Appointments.add(appointment)
SaveClient(client);
return RedirectToAction("Edit", new { id = candidateId });
}
Thanks for your help

The pattern that MVC4 has in mind is each model in its own page.
If you want to add a new model its done in a separate page.
More or less as shown here :
http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-5
If you try to deviate from that pattern, it's a real pain.
So, I would suggest to put the client in a view and adding an appointment in a separate view
And let MVC do the rest.

Related

Check record if exist (instantly) in MVC

I want to check instantly, after i type something in text box, if a record exist in my database. I managed to return on my page number of how many times record exist in database, but i want to return a message (if exists or not).
So, the question is: How can I display a message if record exist or not?
PS. I`m using ASP.NET MVC
Here is my code:
Model class:
public class AdminModel
{
[Remote("IsUniq", "Home", HttpMethod = "POST")]
public string FirstName { get; set; }
}
My controller action(HomeController):
[HttpPost]
public JsonResult IsUniq(string FirstName)
{
IPAdressProgramEntities r = new IPAdressProgramEntities();
var user = r.spLineExist(FirstName);//spLineExist - procedure in SQL- return how many time record exist in database
return Json(user); //return on my page how many times record exists
}
And this is my view:
#using (Html.BeginForm())
{
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
}
PS WebConfig is configured and also scripts are included in my view.
Thank you.
If you simply want to show message when your count is greater than 0, Add an Error message property to your data annotation.
[Remote("IsUniq", "Home", HttpMethod = "POST", ErrorMessage = "Exist")]
public string FirstName { get; set; }
and return true of false from your action method. To show the error message, you need to return false from the method.
var responseToSend = user!=0; //user is the count returned by your existing code
return Json(responseToSend);
If you want to show both the messages (Exists/ Not exists), you may consider handling the check yourself with a little jQuery ajax call than relying on the remote data annotation. So simply remove the data annotation.
And listen to the keyup event on this input field, read the value, send to server to check it exist or not, based on the result, show appropriate message
$(function () {
$("#FirstName")
.keyup(function () {
$.post('/Home/IsUniq?FirstName=' + $(this).val(), function (res) {
if (res) {
$("span[data-valmsg-for='FirstName']").text("Not Available")
} else {
$("span[data-valmsg-for='FirstName']").text("Available")
}
})
});
});
Make sure you return True or False from your action method.
[HttpPost]
public JsonResult IsUniq(string FirstName)
{
//If exists
return Json(true);
else
return Json(false);
}

Asp.net core Custom routing

I am trying to implement custom routing on an asp.net core application.
The desired result is the following:
http://Site_URL/MyController/Action/{Entity_SEO_Name}/
Entity_SEO_Name parameter will be a unique value saved into the database that it is going to help me identify the id of the entity that I am trying to display.
In order to achieve that I have implemented a custom route:
routes.MapMyCustomRoute(
name: "DoctorDetails",
template: " {controller=MyController}/{action=TestRoute}/{name?}");
public class MyTemplateRoute : TemplateRoute
{
public override async Task RouteAsync(RouteContext context)
{
//context.RouteData.Values are always empty. Here is the problem.
var seo_name = context.RouteData.Values["Entity_SEO_Name"];
int entityId = 0;
if (seo_name != null)
{
entityId = GetEntityIdFromDB(seo_name);
}
//Here i need to have the id and pass it to controller
context.RouteData.Values["id"] = entityId;
await base.RouteAsync(context);
}
}
My controller actionresult:
public ActionResult TestRoute(int id)
{
var entity = GetEntityById(id);
return Content("");
}
The problem with this approach is that the context.RouteData.Values are always empty.
Any ideas on how to move forward with this one ?
Your solution too complicated. You can have route template like
template: "{controller=Home}/{action=Index}/{seo?}"
and controller action just like
public ActionResult TestRoute(string seo)
{
var entity = GetEntityBySeo(seo);
return Content("");
}
It is enough, asp.net mvc is smart enough to bind seo variable to the parameter from url path.

ASP.NET mvc Ajax Helper DropDownListFor send selected item value as parameter to controller

Problem
I want my Ajax form to pass the value of the selected DropDownListFor to the controller but I can't figure out why the controller is not taking any value.
I am working with ASP.NET MVC and I would like to stick with the helper functions as much as I can.
View
#using (Ajax.BeginForm(new AjaxOptions {
HttpMethod = "Get",
UpdateTargetId = "UserResults",
InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace }))
{
#Html.DropDownListFor(Model => Model.Roles, new SelectLi(ViewBag.Groups
as System.Collections.IEnumerable, "Value", "Text"), "Select a group",
new { id = "Value", onchange = "$(this.form).submit();" })
}
#Html.Partial("_UsersGroup", ViewData)
Controller
public ActionResult test(int? selectGroup)
{
// Generate dropdownlist Groups
List<SelectListItem> groupList = new List<SelectListItem>();
var query = from s in db.Roles select s;
if (query.Count() > 0)
{
foreach (var v in query)
{
groupList.Add(new SelectListItem { Text = v.Name, Value =
v.ID.ToString() });
}
}
ViewBag.Groups = groupList;
// End
// This part is supposed to take the passed value as parameter
if (selectGroup == null)
{
// To do code comes here, which takes selectGroup as parameter
}
Details
The form should pass a value based on the selection to the controller which takes it as "selectGroup".
ps. this is my first time asking a question, I'm sorry if I made mistakes.
The parameter of you method needs to match the name of the control which is name="Roles" so the method should be
public ActionResult test(int? roles)
Other potential issues with your code
Your controller generates List<SelectListItem> for use by the dropdownlist. There is no need for the unnecessary extra overhead of then creating a new SelectList (which is IEnumerable<SelectListItem>) from it. The view code can simply be #Html.DropDownListFor(m => m.Roles, (IEnumerable<SelectListItem>)ViewBag.Groups, "Select a group")
Do not use Model (capital M) in the expression. If you make any other reference to the model in your view (e.g. #Model.SomeProperty) you will get an error. Using lower case model => model.somProperty is OK but you can simply use m => m.someProperty
The helper will generate an id attribute (in you case id="Role") so it seems unclear why you are adding new { id = "Value", ..}, especially since you don't appear to be referencing the element by its id anywhere
Learn to use Unobtrusive Javascript rather than polluting you mark up with behavior. Remove the onclick attribute and use $('#Roles').change(function() { $('form').submit(); });

Developing a user search page in asp.net MVC 4 using Activedirectory

I am developing a ASp.net MVC 4 Intranet application.
So when I login I can see my account getting displayed.
Now to authorise the account I have developed a custom authorization provider by following the below link :http://www.codeproject.com/Articles/607392/Custom-Role-Providers
now my problem is after the initial authorization I add myself to superadmin role who has acess to Index.cstml where there is a text box and a search button.
basically here on this page I want to search user from active directory and display it so that I can assign some roles to the user.
How do I do that?
please provide the code how to connect to Active directory, where to provide the connection string for LDAP and the excat method which will help me in searching the user from active directory and dispaly it on the index view.
Below is what I have tried:
Entities: ADuser->property UserLoginName ,UserDispalyName
Model: has a method that returns the serch user from AD and add it to entity
public class ADUserModel
{
public List<ADUser> GetUserFromAD(string name) //Get Network Users (AD)
{
//ArrayList searchUser = new ArrayList();
var domainContext = new PrincipalContext(ContextType.Domain);
var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, "Domain Users");
UserPrincipal user = new UserPrincipal(domainContext);
user.Enabled = true;
user.Name = name + "*";
PrincipalSearcher pS = new PrincipalSearcher();
pS.QueryFilter = user;
PrincipalSearchResult<Principal> results = pS.FindAll();
var list = new List<ADUser>();
//searchUser.Add(results);
foreach (var item in results)
{
var users = new ADUser();
users.UserLoginName = item.SamAccountName;
users.UserDisplayName = item.DisplayName;
list.Add(users);
//searchUser.Add(users);
}
return list;
}
}
Controller: has an action method that will return the view
public class ManageUsersController : Controller
{
//
// GET: /ManageUsers/
public ActionResult Search(string searchString)
{
ADUserModel model = new ADUserModel();
var list = new List<ADUser>();
if (searchString != null)
{
list = model.GetUserFromAD(searchString);
return View("Search");
}
else
{
return View("Search");
}
}
}
View: Search.cshtml
#model IEnumerable<FMSKendoUI.Entities.ADUser>
#{
ViewBag.Title = "Search";
}
#Html.BeginForm("Search","ManageUsers",FormMethod.Get)
{
#Html.TextBox("Search") <input type="submit" value="Search" />
}
#if (Model.Count() != 0)
{
#foreach (FMSKendoUI.Entities.ADUser model in Model)
{
#Html.DisplayFor(m => model.UserLoginName)
#Html.DisplayFor(m => model.UserDisplayName)
}
}
But my problem is:
During my first page load I would need only the textbox and search button.
and on the search button click I need to call the controller search method.
Since during the first time my entity is null it is giving me null exception.
my entity get loaded only after I provide the search string and call the model method.
I am unable to achieve this. Please help me on this.

Url.Action is how to reformat URL

I am creating an MVC4 application.
In my contract controller overview page i have an Url.Action
int teller = 0;
foreach (var item in Model)
{
<a href="#Url.Action("Details", "Contract",new { id = teller })">
<tr>
<td>#Html.DisplayFor(modelItem => item.ContractMSFNo)</td>
<td>#Html.DisplayFor(modelItem => item.StageCode)</td>
<td>#Html.DisplayFor(modelItem => item.ValidFromView)</td>
<td>#Html.DisplayFor(modelItem => item.ValidToView)</td>
</tr>
</a>
teller++;
}
I need to pass the id. I am using id in the ActionLink details in Contract Controller
my controller is
public ActionResult Details(int id)
{
//code
return View(contract);
}
When i click on the link Url generated is
http://localhost:4826/Contract/Details/0
/0 is the id
i want my Url to be http://localhost:4826/Contract/Details
i know this can be acheived thru Html.Actionlink but it is my compulsion to use Url.Action. Can it be acheived with Url.Action
It can't be done by routing or ActionLink. But you may try to use session.
1) Add to your controller new method to save your id to session:
public JsonResult Save(int id)
{
Session["ID"] = id;
return Json("Success");
}
2) Add jQuery method to save data in session from View and delete parameter from Url.Action:
<a class="mylink" href="#Url.Action("Details", "Contract")"></a>
<script>
$(".mylink").click(function(){
var data = { id : teller}; //**teller is from your example
$.get("#Url.Action("Details", "Contract")", data)
});
</script>
3) Change your Details ActionResult to get id from session:
public ActionResult Details()
{
var id = (int)Session["ID"];
//code
return View(contract);
}
P.S: Ask your client, how he expects to give sombody external links. It will be impossible if url doesn't have a parameter. And it is very bad for SEO.
If you want your URL without the id parameter, simply don't pass it to the Url.Action() method, as follows:
#Url.Action("Details", "Contract")
If you add like {id=teller} then route automatically add id parameters end of the link. If you don't need id parameters for this url you need to remove
new { id = teller }
Final version like this
#Url.Action("Details", "Contract")
OK, reading this comment: "no actually there are many ids ... code is foreach (var item in Model) { ", I am not sure I understand what you really want to achieve. You are passing a parameter to the view, which can have only one value. Are you sure that you are not looking for something like:
foreach (var item in Model)
{
<a href="#Url.Action("Details", "Contract",#item.ID>
...
}
instead? The fact the ID is visible or not in the URL seems to be another problem, no ?