IEnumerable<Twitter Status> View Output MVC 5 - asp.net-mvc

I am trying to output a set of tweets with a certain hashtag.
I have the following code in the controller:
public ActionResult Test() {
var service = new TwitterService("xxx", "xxx");
service.AuthenticateWith("xxx", "xxx");
var options = new SearchOptions { Q = "#test" };
TwitterSearchResult tweets = service.Search(options);
IEnumerable<TwitterStatus> status = tweets.Statuses;
ViewBag.Tweets = status;
//var tweets = service.Search(options);
return View();
}
I want to output the results that are in the IEnumerable in a view.
But I am finding it difficult to output these results in a view. Can anyone help please?

Your question is a bit vague but I think I understand your problem.
You'll want to pass the data into your view from your action.
public ActionResult Test() {
var service = new TwitterService("xxx", "xxx");
service.AuthenticateWith("xxx", "xxx");
var options = new SearchOptions { Q = "#test" };
TwitterSearchResult tweets = service.Search(options);
IEnumerable<TwitterStatus> status = tweets.Statuses;
//var tweets = service.Search(options);
return View(status);
}
Notice I pass in the status object into the view.
Now in your view you can just bind that object.
#model IEnumerable<TwitterStatus>
#foreach(var status in Model){
<div>
#status.Id #*Id is an exmaple property. Use the actual properties inside "TwitterStatus"*#
</div>
}
Edit:
If you want to have multiple things inside your page you'll have to use Partial Views.
You'll need a view that will encompass all your other partial views. To do this, just define a action for your twitter info that will be your parent view.
public ActionResult AllInfo() {
return View();
}
Then your razor:
//AllInfo.cshtml
#Html.Action("Test", "YourController")
In AllInfo.cshtml we call the action "Test" inside "YourController". We'll change "Test" to return a PartialView instead of a View.
public ActionResult Test() {
var service = new TwitterService("xxx", "xxx");
service.AuthenticateWith("xxx", "xxx");
var options = new SearchOptions { Q = "#test" };
TwitterSearchResult tweets = service.Search(options);
IEnumerable<TwitterStatus> status = tweets.Statuses;
return PartialView(status);
}
The razor stays the same for your partial view:
//Test.cshtml
#model IEnumerable<TwitterStatus>
#foreach(var status in Model){
<div>
#Model.Id #*Id is an exmaple property. Use the actual properties inside "TwitterStatus"
</div>
}
You can call #Html.Action() as many times as you want in your AllInfo.cshtml page and add all the PartialViews you need.

Related

.Net 6 Razor View Not Updating after Post

I am passing a complex model to a Razor View. The data in the model is used in a for-each loop in the view to display a list of products that are for sale in bootstrap cards. There are no forms on the view.
On the left side of the page are list elements that contain nested list elements. These represent product categories. When the user selects a category, I pass the product category to an action method in the controller as an integer. This will build a new model based on the selected category. The new model is then passed back to the view.
At this point, I want to display the categories that are in the category that the user selected. But, the view is not updating even though the model is now different.
I have been reading about this issue, and one forum post I read suggested that this is by design. I read somewhere that in order to achieve what I need to achieve, I have to clear the model state. But I cannot clear the model state because I am not passing the model back to the controller, and you can only pass the model back to the controller by reconstructing the model to be passed in an ajax call for example. I spent all day yesterday trying to get ajax to work and every time I executed the post, the model was populated in the JavaScript function and null or empty in the controller.
Is there another way to force the view to update upon sending a new model to the view? Does anyone have any suggestions?
<script type="text/javascript">
function AddSubCategory(elem) {
event.stopPropagation();
var e = document.querySelectorAll(".products");
e.forEach(box => {
box.remove();
});
var categoryId= $(elem).data('sub-id');
console.log(`Id: ${categoryId}`);
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
}
if (request != null) {
var url = `/Products/GetProductsByCategory?categoryId=${categoryId}`;
request.open("POST", url, false);
};
//request.onreadystatechange = function () {
// if (request.readyState == 4 && request.status == 200) {
// }
//};
request.send();
// model = JSON.stringify(model);
// console.log(model);
// $.ajax({
// type: "Post",
// url: '#Url.Action("GetProductsByCategory", "Products")',
// data: JSON.stringify({"categoryId": categoryId}),
// contentType: 'charset=utf-8;application/json',
// cache: false,
// complete: function (data) {
// }
//});
}
// Load all products
public async Task<IActionResult> Index()
{
ReadCartIDFromCookie();
string SubDomain = GetSubDomain(HttpContext);
var allProducts = await _productService.GetAllProductsWithImagesAsync(SubDomain);
var productCategoryLookup = await _productService.GetAllProductCategoryLookupAsync();
ViewBag.host = SubDomain;
ViewBag.productCategoryLookup = productCategoryLookup;
return View("Index", allProducts);
}
//Load filtered list of products
[HttpPost]
public async Task<IActionResult> GetProductsByCategory(int categoryId = -1)
{
ReadCartIDFromCookie();
string SubDomain = GetSubDomain(HttpContext);
var allProducts = await _productService.GetAllProductsWithImagesAsync(SubDomain, categoryId);
var productCategoryLookup = await _productService.GetAllProductCategoryLookupAsync();
ViewBag.host = SubDomain;
ViewBag.productCategoryLookup = productCategoryLookup;
return View("Index", allProducts);
}
I was able to resolve my issue thanks to this post: https://stackoverflow.com/a/66277911/1561777
I did have a bit of trouble trying to figure it out because it was not completely clear, but I could tell it was what I needed to do. I ended up utilizing a partial view for the display of my products. Here is my final code.
//My index.cshtml razor view
<div class="col" id="product"></div>//partial view will be loaded onto this div
//Javascript function that gets the chosen filter category Id
#section Scripts
{
<script type="text/javascript">
function AddSubCategory(elem) {
event.stopPropagation();
//get the id
var categoryId= $(elem).data('sub-id');
console.log(`Id: ${categoryId}`);
//call controller Products, controller action GetProductsByCategory and pass the categoryId
//The partial view will be returned and load onto the div id #product
$('#product').load(`/Products/GetProductsByCategory?categoryId=${categoryId}`);
}
//when the index view first loads, load all products (i.e. category -1)
$('#product').load(`/Products/GetProductsByCategory`);
</script>
}
public async Task<IActionResult> GetProductsByCategory(int categoryId = -1)
{
ReadCartIDFromCookie();
string SubDomain = GetSubDomain(HttpContext);
var allProducts = await _productService.GetAllProductsWithImagesAsync(SubDomain, categoryId);
var productCategoryLookup = await _productService.GetAllProductCategoryLookupAsync();
ViewBag.host = SubDomain;
ViewBag.productCategoryLookup = productCategoryLookup;
//notice that I am using PartialView method
//Returning View was including the full website (i.e. header and footer).
//_Products is my partial view. allProducts is the
//view model that is being passed to the partial view.
return PartialView("_Products", allProducts);
}
Now, everytime I select a new category, the partial view is reloaded. Also, when first loading the view, all products are displayed as expected.

RenderAction ViewBag Empty on the View

I am invoking a RenderAction from a View as shown below:
#{ Html.RenderAction("GetOptions", "Product", new {ProductId = Model.ProductId});
var options = ViewBag.Options;
}
Inside the GetOptions I populate the ViewBag as shown below:
public ActionResult GetOptions(..) {
// do some other stuff
ViewBag.Options = new JavaScriptSerializer().Serializer(options);
return Content(somelongstring);
}
But when I debug inside the var options is always null. What am I doing wrong?

Foreach does not work while using json in asp.net mvc

,Hi all,
I am trying to use json.İf ı return to partial view ,i can not use foreach for my customer session.My Customer Session has customers.I can not list them.
Where i miss ?
CONTROLLER:
public ActionResult ShowResult(MyModel model)
{
Session["CustomerList"] = context.Customer.Where(s => s.CustomerSituation== true).ToList(); // Customers List To Session
var stringView = RenderRazorViewToString("_ShowResultPartial", model);
return Json(stringView, JsonRequestBehavior.AllowGet);
}
.
My _ShowResultPartial View:
#foreach (var item in (List<Q502351.Models.Customer>)Session["CustomerList"])
{
Ajax.ActionLink(item.CustomerName, "ShowResult", new { CustomerId = item.CustomerId}, new AjaxOptions { HttpMethod = "POST" });
}
From what you have posted, it's not clear why you want to store the customer list in session; data for the view should generally be stored on the view model. Even if you have a compelling reason to use session, it's a better practice to retrieve the session variables in the controller and store them in the view model. Then you should be able to loop through the list on the model from the view. In this situation it doesn't look like session is necessary at all (unless you intend to reuse the stored data later and for some reason cannot pass it along via models).
Also, unless there is a good reason to return json, your ShowResult controller method should just return a PartialView.
Something like this should work...
Controller:
public ActionResult ShowResult(MyModel model)
{
model.Customers = context.Customer.Where(s => s.CustomerSituation == true).ToList();
return PartialView("_ShowResultPartial"), model);
}
Partial view:
#model MyModel
#foreach (var item in Model.Customers)
{
Ajax.ActionLink(item.CustomerName, "ShowResult", new { CustomerId = item.CustomerId}, new AjaxOptions { HttpMethod = "POST" });
}

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)

Passing viewmodel from one method to another (post)

I have a wizardtype form where i would like to keep the model from the first step to the last.
This is how im doing it now, but i cant seem to keep the model from step 3 to 4.
[HttpPost]
public ActionResult Register(MemberViewModel model)
{
var mobile = model.Mobile;
var xml = MemberclubHelper.CreateVerificationTokenXML(mobile, "47");
MemberclubHelper.SendVerificationToken(xml);
return RedirectToAction("RegisterStep1", new { mobile = mobile });
}
public ActionResult RegisterStep1(string mobile)
{
var model = new MemberViewModel();
model.Mobile = mobile;
return View("Register/Step1", model);
}
[HttpPost]
public ActionResult RegisterStep1(MemberViewModel model)
{
var interests = (from interest in model.Interests where interest.isChecked select interest.value).ToList();
var passing = (from pass in model.Passing where pass.isChecked select pass.value).ToList();
var xml = MemberclubHelper.CreateMemberProfileXML(model.Mobile, model.FirstName, model.FirstName,
model.Email1, model.Zipcode, model.SelectedKid1, model.SelectedKid2, model.SelectedKid3,
model.Gender.ToString(), interests, passing);
model.XmlToSend = xml;
if (xml.Contains("error"))
{
model.ErrorMessage = xml;
return View("Register/Step1", model);
}
return View("Register/Step2", model);
}
[HttpPost]
public ActionResult RegisterStep2(MemberViewModel model)
{
var result = MemberclubHelper.SendCreateUser(model.XmlToSend, model.Password);
if (result.Contains("error"))
{
model.ErrorMessage = result;
return View("Register/Step2", model);
}
else
{
return View("Register/Finished");
}
}
I think you may be better served by creating a separate view model for each step (i.e., MemberViewModelStep1). To me this seems like only some of your MemberViewModel properties will will be set in each step unless you carry a lot of that state between steps via hidden inputs or some other mechanism.
Alternatively, have you considered using JavaScript to build up that state between across your steps and then submitting a single post with your fully populated MemberViewModel?

Resources