Partial view action send parameter - asp.net-mvc

How do I send array parameters to the action method?
How do I create a array variable?
partialView.page
I tried that but it did not work.
#{ Html.RenderAction("GetDefinationType", "Crew", new { category = "Competency","crew",Person" }); }
Thank you

you can do like this in View:
#{
var temp = new[] { "Competency", "crew", "Person" };
}
#Html.Action("GetDefinationType", "Crew",new{category =temp })
Action:
public ActionResult GetDefinationType(string[] category)
{
return Content("");
}

At the method GetDefinationType you have to let it accept a parameter with the name CategoryOptions, this will be the class (parameters) you are passing.
public class CategoryOptions
{
string[] myArray { get; set; }
}
This is how to call and use it:
#{ Html.RenderAction("GetDefinationType", "Crew", new { category = new CategoryOptions { myArray = new string [] {"Competency","crew","Person"}} }); }

The other two answers were almost right, but over-complicated.
If you want to pass an array of strings as a parameter, just pass an anonymously typed array of strings as your named category parameter:
#{Html.RenderAction("GetDefinationType", "Crew", new { category = new [] {"Competency","crew","Person"} });}
Use Html.Action, not HTML.RenderAction
Note: RenderAction is for use in code blocks (as you have added), but you can just use the simpler #Html.Action for inline Razor code:
#Html.Action("GetDefinationType", "Crew", new { category = new [] {"Competency","crew","Person"} })
In either case the controller action method just needs to accept a parameter called category of type string[].
e.g.
public ActionRresult GetDefinationType(string[] category)
{
// do something with the list of categories
}
Also, unless you mean the slang combination of defamation and definition, "defanation" please spell it definition :)

Related

passing dynamic model in MVC5 Razor View [duplicate]

This question already has answers here:
Dynamic Anonymous type in Razor causes RuntimeBinderException
(12 answers)
Closed 6 years ago.
I'm trying to pass dynamic results to View from Controller, method ShowColor returns dynamic results. In View I try to loop through the collection but I'm getting error
'object' does not contain a definition for 'ColorID'.
I have the following code in Controller and View
public class myColor
{
public int ID { get; set; }
public string Name { get; set; }
public string Like { get; set; }
}
public dynamic ShowColor()
{
IList<myColor> color = new List<myColor>();
color.Add(new myColor { ID = 1, Name = "Red", Like = "***" });
color.Add(new myColor { ID = 2, Name = "Green", Like = "*****" });
color.Add(new myColor { ID = 3, Name = "Blue", Like = "**" });
color.Add(new myColor { ID = 4, Name = "Yellow", Like = "*" });
var select = (from c in color
select new
{
ColorID = c.ID,
ColorName = c.Name
}).ToList();
return select;
}
public ActionResult DBDynamic()
{
return View(ShowColor());
}
View
#model dynamic
#{
ViewBag.Title = "DBDynamic";
}
<h2>DBDynamic</h2>
<p>
<ul>
#foreach (var m in Model)
{
<li> #m.ColorID</li>
}
</ul>
</p>
Found the solution here and a nice blog here:
public static ExpandoObject ToExpando(this object anonymousObject)
{
IDictionary<string, object> expando = new ExpandoObject();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
{
var obj = propertyDescriptor.GetValue(anonymousObject);
expando.Add(propertyDescriptor.Name, obj);
}
return (ExpandoObject)expando;
}
And call it like this
var select = (from c in color
select new
{
ColorID = c.ID,
ColorName = c.Name
})
.AsEnumerable()
.Select(x => x.ToExpando());
return View(select);
An anonymous object is not the same thing as a dynamic. If you want to use it like a dynamic then cast it to that:
#foreach (dynamic m in Model)
However, dynamics are best avoided if at all possible. You lose all compile-time checking and even intellisense. You won't know if you fat-fingered a property name until runtime or even if you've accidentally used the wrong type of thing the wrong way until runtime. If something is broken, you want to know about it at compile-time, not when it's already live and affecting users, when you may not even know that an error has occurred unless a user notifies you. That's a horrible situation for your app to be in.
Long and short, use strong types. If you want something with properties, ColorID and ColorName, create a view model with those properties and select your query into instances of that type. Then, everything will be nice and strongly-typed and you'll know well in advance if there's some error or problem with your code.

How to pass values - controller to controller?

I am using MVC and want to pass values, controller to controller
My code:
public ActionResult Index()
{
List<string> SportsName = new List<string>();
var sport = Db.Universities.Where(ud => ud.Contact.UserName.ToLower().Trim() == User.Identity.Name.ToLower().Trim()).SingleOrDefault();
var spt = Db.Departments.Where(i => i.UniversityID == sport.UniversityID && i.DepartmentCodeID == 4).SingleOrDefault();
unvId = int.Parse(sport.UniversityID.ToString());
List<Sport> dept = Db.Sports.Where(s => s.DepartmentID == spt.DepartmentID).ToList();
foreach (var sname in dept.ToList())
{
var name = Db.SportsCodes.Where(s => s.SportsCodeID == sname.SportsCodeID).First();
SportsName.Add(name.SportsName);
}
ViewBag.SportsName = SportsName;
return View();
}
public ActionResult Create(string sports)
{
ViewBag.SportsName = sports;
int s = unvId;
return View();
}
I want the 'sport' value in create action also. How to get the value of 'sport' in create action?
What I guess from your question is You want to pass the SportsName from Index to Create.
From Index View (.cshtml) when you call the Create method through AJAX call, pass the value of the ViewBag.Sports as a parameter.
For Example :
$('#Link').click(function () {
$.ajax({
url: http://localhost/Sports/Create,
type: 'GET',
data: {
sports: "#ViewBag.SportsName"
},
success: function () {
},
error: function () {
}
});
[Note : Here it is considered that name of your controller is Sports]
This answers to your question.
You have a number of options. If only individual action methods need that value, fetch the value in each action method that needs it:
public ActionResult SomeMethod()
{
var sport = Db.Universities.Where(ud => ud.Contact.UserName.ToLower().Trim() == User.Identity.Name.ToLower().Trim()).SingleOrDefault();
// ...
}
If the repeated code seems unsightly, abstract it to a helper method:
public ActionResult SomeMethod()
{
var sport = GetSport();
// ...
}
private SomeType GetSport()
{
return Db.Universities.Where(ud => ud.Contact.UserName.ToLower().Trim() == User.Identity.Name.ToLower().Trim()).SingleOrDefault();
}
If it should be accessible anywhere in the class and is logically a class-level member, make it a class-level member:
private SomeType sport = Db.Universities.Where(ud => ud.Contact.UserName.ToLower().Trim() == User.Identity.Name.ToLower().Trim()).SingleOrDefault();
public ActionResult SomeMethod()
{
// sport is accessible here
// ...
}
Though now that I notice it, this begs the question "What is Db"? If that's a database context then it looks like you've expanded the scope of it beyond what it really should be. Database contexts and connections should be kept in as small a scope as possible. Each method that needs one should create it, use it, and destroy it. Sharing them at a larger scope without explicitly knowing what you're doing is inviting a whole host of problems. In this case, the class-level member would be initialized in the constructor:
private SomeType sport;
public YourController()
{
using (var Db = BuildYourDBContext())
sport = Db.Universities.Where(ud => ud.Contact.UserName.ToLower().Trim() == User.Identity.Name.ToLower().Trim()).SingleOrDefault();
}
public ActionResult SomeMethod()
{
// sport is accessible here
// ...
}
Any way you look at it, the point is that being a controller doesn't really make a difference. The controller is an object like any object in an object-oriented system. It shares members exactly the same way.

List of class properties

I have ASP.NET MVC 4 application with one view model class and about 20 views representing this view model. This views differs only by fields which user can edit. I want to merge all that views to one and define list of properties available to editing in strongly-typed manner. Ideally, I want something like this:
// Action
public ActionResult EditAsEngineer(int id)
{
//...
viewModel.PropertiesToChange = new List<???>()
{
v => v.LotNumber,
v => v.ShippingDate,
v => v.Commentary
};
return View(viewModel);
}
// View
if (#Model.PropertiesToChange.Contains(v => v.LotNumber)
{
#Html.TextBoxFor(m => m.LotNumber)
}
else
{
#Model.LotNumber
}
Is it possible to do something like this? Or is there a better solution?
Thank you.
Why note something like this (its pseudo code)
public class Prop{
string PropertyName {get;set;}
bool PropertyEditable {get;set;}
}
public ActionResult EditAsEngineer(int id)
{
viewModel.PropertiesToChange = new List<Prop>()
{
new Prop{PropertyName = LotNumber, PropertyEditable = true}
};
return View(viewModel);
}
#foreach (var pin Model.PropertiesToChange)
{
if(p.PropertyEditable){
#Html.TextBoxFor(p)
}else{
#Html.DisplayFor(p)
}
}
This will solve HALF of your problem. You will also need to create a IEqualityComparer<Expression> for your code to work (the default is to check for ref-equals).
return from p in typeof(T).GetProperties()
let param = System.Linq.Expressions.Expression.Parameter(typeof(T), "x")
let propExp = System.Linq.Expressions.Expression.Property(param, p)
let cast = System.Linq.Expressions.Expression.Convert(propExp, typeof(object))
let displayAttribute = p.CustomAttributes.OfType<System.ComponentModel.DataAnnotations.DisplayAttribute>()
.Select(x => x.Order).DefaultIfEmpty(int.MaxValue).FirstOrDefault()
orderby displayAttribute
select System.Linq.Expressions.Expression.Lambda<Func<T, object>>(cast, new [] {param});
This will list out ALL the properties for T. You would also probabily want to use Expression<Func<T, object>> as the type for defining your list of properties.
This will allow you to create a generic view over all properties.
Also you will want to wrap this in some kind of a cache, as this code is SLOW.

ASP.NET MVC show collection of data in View inside of TextArea

I access data with:
public ActionResult Index()
{
//IEnumerable<ChatLogs> c = from p in db.ChatLogs select p;
//return View(c);
using (var db = new ChatLogContext())
{
var list = db.ChatLogs.ToList();
return View(list);
}
}
I would like to know how to save this collection of data inside of TextArea in View? When we used webforms we could just textBox.Text = textBox.Text + "some data from database";
View:
#model IEnumerable<Chat.Models.ChatLogs>
#Html.TextArea("chatScreen", new { #Class = "chatScreen" })
Thank you.
I'd suggest that you create a view model. For example:
class ChatLogsViewModel
{
public string LogListString { get; set; }
}
Pass that to the view, instead of passing the raw list:
var list = db.ChatLogs.ToList();
var vm = new ChatLogsViewModel { LogListString = /* convert list to single string here */ };
return View(vm);
And in the view, just do something like this:
#model Your.Namespace.ChatLogsViewModel
#Html.TextAreaFor(model => model.LogListString)
Using view models will make your life easier as soon as you decide that you want to pass more information to the view than what a single domain model can carry.
In you .cshtml view, you can access data using #Model
Now, since you have a list, I'd recommend you join it and then assign it to TextArea like
#{var strList = string.Join(" ", Model)}
#Html.TextArea("myTextArea",strList)

ASP.NET MVC: Server Validation & Keeping URL paramters when returning the view

I currently have the following code for the POST to edit a customer note.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditNote(Note note)
{
if (ValidateNote(note))
{
_customerRepository.Save(note);
return RedirectToAction("Notes", "Customers", new { id = note.CustomerID.ToString() });
}
else
{
var _customer = _customerRepository.GetCustomer(new Customer() { CustomerID = Convert.ToInt32(note.CustomerID) });
var _notePriorities = _customerRepository.GetNotePriorities(new Paging(), new NotePriority() { NotePriorityActive = true });
IEnumerable<SelectListItem> _selectNotePriorities = from c in _notePriorities
select new SelectListItem
{
Text = c.NotePriorityName,
Value = c.NotePriorityID.ToString()
};
var viewState = new GenericViewState
{
Customer = _customer,
SelectNotePriorities = _selectNotePriorities
};
return View(viewState);
}
}
If Validation fails, I want it to render the EditNote view again but preserve the url parameters (NoteID and CustomerID) for something like this: "http://localhost:63137/Customers/EditNote/?NoteID=7&CustomerID=28"
Any ideas on how to accomplish this?
Thanks!
This action is hit by using a post. Wouldn't you want the params to come through as part of the form rather than in the url?
If you do want it, I suppose you could do a RedirectToAction to the edit GET action which contains the noteId and customerId. This would effectively make your action look like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditNote(Note note)
{
if (ValidateNote(note))
{
_customerRepository.Save(note);
return RedirectToAction("Notes", "Customers", new { id = note.CustomerID.ToString() });
}
//It's failed, so do a redirect to action. The EditNote action here would point to the original edit note url.
return RedirectToAction("EditNote", "Customers", new { id = note.CustomerID.ToString() });
}
The benefit of this is that you've removed the need to duplicate your code that gets the customer, notes and wotnot. The downside (although I can't see where it does it here) is that you're not returning validation failures.

Resources