Using Json Result from one action to another action - c#

I am having previously defined action which return the List<T>() int Json Format using JsonResult.
I want to use the same action's JSON result into another action.
For better understanding,
My Common Action is::
public JsonResult GetReferences(long CustomerID)
{
var CustomerReference = new List<ReferenceViewModel>();
//Code to push data into CustomerReference
return Json(CustomerReference.OrderBy(x=>x.ReferenceName));
}
I want to use the above JsonResult into my other Action as::
public ActionResult MassUpdate(List<long> CustomerIDs, List<long> DocumentIDs)
{
List<ReferenceViewModel> JsonCustomerReference = GetReferences(CustomerID);
}
But I am not able to access the JsonResult here. How can I do that?

GetReferences is returning a JSONREsult which is not a List. why dont you try abscracting this a bit:
private IEnumerable<ReferenceViewModel> getReferences(long CustomerID)
{
var customerReferences = new List<ReferenceViewModel>();
//Code to push data into CustomerReference
return customerReferences;
}
public JsonResult GetReferences(long CustomerID)
{
return Json(customerReference(CustomerID).OrderBy(x=>x.ReferenceName));
}
public JsonResult MassUpdate(List<long> CustomerIDs, List<long> DocumentIDs)
{
var allData = CustomerIDs.SelectMany(x => customerReference(x)).OrderBy(x=>x.ReferenceName);
return Json(alldata);
}
I am making some assumptions here. But i think this is what you are kind of going for. you could also change the return type of getReferences to an IEnumerable and do the sorting in each Action if that is what you are going for. I updated my answer to reflect that change.

I hope that you want something like this.
JsonResult hold data in Data Property. Which is object so you need to cast it back.
List JsonCustomerReference = (List)((JsonResult)GetReferences(CustomerID)).Data;

Related

.NET MVC Controller not binding to object type

Very straight forward $.post(url, data)
data is this object
var model = {
applNo: pdAppNo,
amount: 999,
schldDate: new Date(),
userId: "corey",
tdcId: "234234234"
};
Calling an MVC controller that is setup like
[HttpPost]
public JsonResult PostScheduleMakeUpPayment(object model)
{
//return _updateTdc.ProcessMakeUpPayment(applNo, amount, schldDate, userId, tdcId);
return Json("Success:True");
}
Inside the 'model' of the controller its not showing the json data, only '{object}'
So MVC won't allow me to post json to object type?
You need the create named class.
public class TestModel
{
public string applNo {get;set;}
public int amount{get;set;}
public DateTime schldDate{get;set;}
public string userId{get;set;}
public string tdcId{get;set;}
}
[HttpPost]
public JsonResult PostScheduleMakeUpPayment(TestModel model)
{
//return _updateTdc.ProcessMakeUpPayment(model.applNo, model.amount, model.schldDate, model.userId, model.tdcId);
return Json("Success:True");
}
A Json string is a collection of pairs key-value. You can post your object as a json string and use a function to add to a dictionary its values, and then use it in controller function. For example:
public static Dictionary<string,object> BinderModel(string model)
{
Dictionary<string,JToken> result = new Dictionary<string,object>();
JObject jObject = JObject.Parse(model);
foreach (JProperty x in (JToken)jObject )
{
result.Add(x.Name,x.Value);
}
return result;
}
and then your controller function like this
[HttpPost]
public JsonResult PostScheduleMakeUpPayment(string model)
{
Dictionary<string,object> values = BinderModel(jsonString);
//return _updateTdc.ProcessMakeUpPayment(values["applNo"], values["amount"], values["schldDate"], values["userId"], values["tdcId);
return Json("Success:True");
}
The type of model values depends on the types of ProcessMakeUpPayment input parameters. You may need to do some conversion before you call it or in it
I guess object type parameters on MVC controllers are not supported/bad design. Along with MVC not supporting generic types on its view/Razor syntax.

How to properly call JsonResult method in controller from view model?

From the oddity in my question, I suspect I'm not going in the right direction.
Supposed I have a view that has a paginated list among several other items. On first load, the list is loaded with the first page of the list (this is where I'm attempting to call my JsonResult method in the controller from the model).
public class FooListViewModel
{
public FooListViewModel()
{
DateTime today = DateTime.Today;
DateTime later = DateTime.Today.AddDays(5);
// Here I need to make call to my JsonResult method
// in the controller to populate fooItems
}
public IEnumerable<FooItem> fooItems { get; private set; }
public IEnumerable<DateTime> dates { get; private set; }
}
In controller
[HttpGet]
public JsonResult GetItems(DateTime start, DateTime end)
{
var fooItems = domainServices.Foo.GetAllFooItems();
// Add predicates to filter between start and end dates.
return Json(fooItems, JsonRequestBehavior.AllowGet);
}
On each page button click, it will reload ONLY the list with another call to the JsonResult method in the controller via AJAX, but this has already been done.
It's easier to just simulate the button click on the client when the page just loads, then you only have one routine to do all the getting data, inserting into page and correctly formatting it.
Otherwise, create a GetData function that your controller routine (Index?) calls and your GetJSON routine calls to get whatever data you need. The index method will stick this in the model to pass to the view, and the GetJSON routine just returns the result as json.
Sample code:
public ActionResult Index()
{
MyViewModel model = new MyViewModel();
model.data = GetData();
return View(model);
}
public JsonResult GetJson(DateTime startDate,DateTime endDate)
{
var result=GetData(startDate,endDate);
return Json(result);
}
private IEnumerable<MyData> GetData(DateTime startDate=null,DateTime endDate=null)
{
return something;
}
You really shouldn't be calling action methods in any way other than via a HTTP request (since what you get back should he a HTTP response). This is, in a sense, like asking your server-side code to send a request to a page, which is all backwards.
If you have logic that you need in both in your controller and in your model constructor, you should probably be abstracting this logic from your presentation layer, exposing it in your business layer and just consuming it in both places:
public class FooProvider
{
public List<Foo> GetFilteredFoos (/* whatever you need */)
{
// filter and return foos
}
}
Controller:
public JsonResult GetItems(DateTime start, DateTime end)
{
var fooItems = domainServices.Foo.GetFilteredFoos(/* some params */);
return Json(fooItems);
}
Model:
public FooListViewModel()
{
DateTime today = DateTime.Today;
DateTime later = DateTime.Today.AddDays(5);
var ds = DomainServices();
fooItems = ds.Foo.GetFilteredFoos(/* some params */);
}
Here, I assume that DomainServices.Foo is an instance of a class called FooProvider.
Having said this, however, I would avoid having this kind of login in your view model at all, where possible. Why not simply make the call in the controller when you first initialize the model?
public ActionResult Index()
{
var model = FooListViewModel();
model.fooItems = ds.Foo.GetFilteredFoos(/* things */);
return View(model);
}
Then, update via AJAX as normal.

How to pass List in Redirecttoaction

I want to pass more then one parameter from RedirectToAction method
how can I pass?
My One Action Method
[HttpPost, ActionName("SelectQuestion")]
public ActionResult SelectQuestion(string email,List<QuestionClass.Tabelfields> model)
{
List<QuestionClass.Tabelfields> fadd = new List<QuestionClass.Tabelfields>();
for (int i = 0; i < model.Count; i++)
{
if (model[i].SelectedCheckbox == true)
{
List<QuestionClass.Tabelfields> f = new List<QuestionClass.Tabelfields>();
fadd.Add(model[i]);
}
}
return RedirectToAction("Question", new { email = email, model = fadd.ToList() });
}
My another Action Method
[HttpGet]
public ActionResult Question(string email,List<QuestionClass.Tabelfields> model)
{
}
I am not getting values in model.
You cannot pass a collection of complex objects in urls when redirecting.
One possibility would be to use TempData:
TempData["list"] = fadd.ToList();
return RedirectToAction("Question", new { email = email});
and then inside the Question action:
var model = TempData["list"] as List<QuestionClass.Tablefields>;
The way that I solved this problem was to serialize the list to a JSON object using the JsonConvert method from the Newtonsoft.Json nuget package. Then the serialized list can be passed as a parameter and then deserialized again to re-create the original list.
So in your SelectQuestion method you would use this code:
return RedirectToAction("Question",
new {
email = email,
serializedModel = JsonConvert.SerializeObject(fadd.ToList())
});
And in your Question method, you would use this code to deserialize the object.
[HttpGet]
public ActionResult Question(string email, string serializedModel)
{
// Deserialize your model back to a list again here.
List<QuestionClass.Tabelfields> model = JsonConvert.DeserializeObject<List<QuestionClass.Tabelfields>>(serializedModel);
}
Important, this adds the model as a query string parameter to your url, so only do this with really simple small objects, otherwise your url will be too long.
This is probably not even active anymore, but I'll leave how I did it here to maybe help someone else.
I solved this using a simple Redirect instead of a RedirectToAction:
List<int> myList = myListofItems;
var list = HttpUtility.ParseQueryString("");
myList.ForEach(x => list.Add("parameterList", x.ToString()));
return Redirect("/MyPath?" + list);
Then, on your other method:
public ActionResult Action(List<int> parameterList){}
RedirectToAction method Returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action.
You should either keep the data in a temporary storage like TempData / Session . TempData uses Session as the backing storage.
If you want to keep it real Stateless, you should pass an id in the query string and Fetch the List of items in your GET Action. Truly Stateless.
return RedirectToAction("Question", new { email = email,id=model.ID });
and in your GET method
public ActionResult Question(string email,int id)
{
List<QuestionClass.Tabelfields> fadd=repositary.GetTabelFieldsFromID(id);
//Do whatever with this
return View();
}
Assuming repositary.GetTabelFieldsFromID returns a List of TabelFields from the Id

How to send array to another controller method in asp.net mvc?

customers is a List<string>.
RedirectToAction("ListCustomers", new { customers = customers });
And when I send the list it contains 4 items, but when I receive it in my controller method it has only one item and it's of type generic list. That seems not be what I want. But how to pass more complex data than strings and integer between controller methods?
You cannot send complex objects when redirecting. When redirecting you are sending a GET request to the target action. When sending a GET request you need to send all information as query string parameters. And this works only with simple scalar properties.
So one way is to persist the instance somewhere on the server before redirecting (in a database for example) and then pass only an id as query string parameter to the target action which will be able to retrieve the object from where it was stored:
int id = Persist(customers);
return RedirectToAction("ListCustomers", new { id = id });
and inside the target action:
public ActionResult ListCustomers(int id)
{
IEnumerable<string> customers = Retrieve(id);
...
}
Another possibility is to pass all the values as query string parameters (be careful there's a limit in the length of a query string which will vary among browsers):
public ActionResult Index()
{
IEnumerable<string> customers = new[] { "cust1", "cust2" };
var values = new RouteValueDictionary(
customers
.Select((customer, index) => new { customer, index })
.ToDictionary(
key => string.Format("[{0}]", key.index),
value => (object)value.customer
)
);
return RedirectToAction("ListCustomers", values);
}
public ActionResult ListCustomers(IEnumerable<string> customers)
{
...
}
Yet another possibility is to use TempData (not recommended):
TempData["customer"] = customers;
return RedirectToAction("ListCustomers");
and then:
public ActionResult ListCustomers()
{
TempData["customers"] as IEnumerable<string>;
...
}

return a list of string as JSONResult

how would I return a list of string in a json result in C# asp.net MVC?
I have this controller
public JsonResult AutoCompletePart(string id)
{
AutoCompleteService srv = new AutoCompleteService();
string[] parts = srv.AutoCompleteItemMaster(id);
//how do i return parts as JSON?
}
Thanks
Like this:
return Json(parts, JsonRequestBehavior.AllowGet);
This will return a simple Javascript string array.
If you want to return specific format, please provide more detail.

Categories

Resources