I want to write an asynchronous Controller that is displaying in output an IEnumerable<IEnumerable<Video>>
I don't know I can manage to write correctly my function Task<IEnumerable<IEnumerable<Video>>> GetVideosAsync(xxxxx) especially the Task.ContinueWhenAll function (in order not to have blocking code ).
Is it better to use a lambda for this piece of code ...?
Can someone help me ?
Nb: *I can only use C#4 and visual Studio 2010
public class HomeController : AsyncController
{
string[] sources = {
"http://xxxx/membervideos/1",
"http://xxxx/membervideos/2"
};
public Task<ActionResult> Async()
{
var sw = Stopwatch.StartNew();
var data = GetVideosAsync();
sw.Stop();
ViewBag.Elapsed = sw.ElapsedMilliseconds;
return View("~/views/home/index.cshtml", data);
}
Task<IEnumerable<IEnumerable<Video>>> GetVideosAsync()
{
var allVideosTasks = new List<Task<IEnumerable<Video>>>();
foreach (var url in sources)
{
allVideosTasks.Add(DownloadDataAsync(url));
}
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.ContinueWhenAll<IEnumerable<Video>,IEnumerable<IEnumerable<Video>>(
/// CODE TO ComplETE HERE
);
Task<IEnumerable<Video>> DownloadDataAsync(string url)
{
var httpClient = new HttpClient();
var httpResponseMessage = httpClient.GetAsync(url);
var result = httpResponseMessage.ContinueWith
(t =>
{
t.Result.EnsureSuccessStatusCode();
return t.Result.Content.ReadAsAsync<IEnumerable<Video>>();
}
).Unwrap();
return result;
}
/**** VIEW ******/
#{
ViewBag.Title = "Home Page";
}
#model IEnumerable<IEnumerable<MvcApplication1.Models.Video>>
<table>
#foreach (var memberVideos in Model)
{
<tr>
#foreach(var video in memberVideos){
<td>
<div>#video.Title</div>
<div><img src="http://xxxxxx/membervideos/#video.ImageUrl" style="width: 185px;"/> </div>
</td>
}
</tr>
}
</table>
<h1>#ViewBag.Elapsed</h1>
Related
I want to be able to upload a file then to download it or delete it. But when I try to delete it, I get this error:
The view 'Delete' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/FileUpload/Delete.aspx ,~/Views/FileUpload/Delete.ascx, ~/Views/Shared/Delete.aspx,~/Views/Shared/Delete.ascx, ~/Views/FileUpload/Delete.cshtml, ~/Views/FileUpload/Delete.vbhtml, ~/Views/Shared/Delete.cshtml ,~/Views/Shared/Delete.vbhtml .
[HttpGet]
public ActionResult Delete( string deletedfile)
{
string current_usr = User.Identity.GetUserId();
string fullPath = Request.MapPath("~/Files/" + current_usr + "/" + deletedfile);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
ViewBag.Message="Deleted";
}
var items = GetFiles();
return View(items);
}
// GET: FileUpload
public ActionResult Index()
{
var items = GetFiles();
return View(items);
}
// POST: FileUpload
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
try
{
string current_usr = User.Identity.GetUserId();
//string path = Path.Combine(Server.MapPath("~/Files/"),
// Path.GetFileName(file.FileName));
var folder = Server.MapPath("~/Files/" + current_usr + "/");
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
string path = Path.Combine(String.Format(folder),
Path.GetFileName(file.FileName));
file.SaveAs(path);
ViewBag.Message = "File uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
else
{
ViewBag.Message = "You have not specified a file.";
}
var items = GetFiles();
return View(items);
}
public FileResult Download(string downloadedfile)
{
string current_usr = User.Identity.GetUserId();
var FileVirtualPath = "~/Files/" + current_usr + "/" + downloadedfile;
return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
}
private List<string> GetFiles()
{
string current_usr = User.Identity.GetUserId();
var dir = new System.IO.DirectoryInfo(Server.MapPath("~/Files/" + current_usr + "/"));
System.IO.FileInfo[] fileNames = dir.GetFiles("*.*");
List<string> items = new List<string>();
foreach (var file in fileNames)
{
items.Add(file.Name);
}
return items;
}
The View :
<h2> File Upload </h2>
#model List<string>
#using (Html.BeginForm("Index", "FileUpload", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file"> Upload </label>
<input type="file" name="file" id="file" />
<br /><br />
<input type="submit" value="Upload" />
<br /><br />
#ViewBag.Message
<br />
<h2>Documents list</h2>
<table style="width:100%">
<tr>
<th> File Name </th>
<th> Link </th>
</tr>
#for (var i = 0; i <= (Model.Count) - 1; i++)
{
<tr>
<td>#Model[i].ToString() </td>
<td>#Html.ActionLink("Download", "Download", new { downloadedfile = Model[i].ToString() }) </td>
<td>
#Html.ActionLink("Delete", "Delete", new { deletedfile = Model[i].ToString() })
</td>
</tr>
}
</table>
}
The issue is that your Delete Controller method is calling View() at the end. That method will attempt to find a view file with the name of the controller method. If you want to show the list of files after the delete you can redirect to your index action like this:
[HttpGet]
public ActionResult Delete(string deletedfile)
{
string current_usr = User.Identity.GetUserId();
string fullPath = Request.MapPath("~/Files/" + current_usr + "/" + deletedfile);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
ViewBag.Message = "Deleted";
}
return RedirectToAction("Index");
}
See this link from the microsoft Docs for more detail on redirecting
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs
I have a code for image upload and that working as expected, in my way image is DP display picture of user.
Create.cshtml
<div class="form-group">
<label asp-for="DP" class="control-label">Profile Image</label>
<input type="file" name="DP" asp-for="DP" class="form-control" />
<span asp-validation-for="DP" class="text-danger"></span>
</div>
Controller Action
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Profile profile, IFormFile DP)
{
if (ModelState.IsValid)
{
var id = _userManager.GetUserName(HttpContext.User);
var fileName = Path.Combine(_environment.WebRootPath +"/Upload/DP/", Path.GetFileName(id+".png"));
DP.CopyTo(new FileStream(fileName,FileMode.Create));
//profile.DP = fileName;
ViewBag.fileName = fileName;
var create = new Profile {
userName = profile.userName,
uId = profile.uId,
rId = profile.rId,
Mobile = profile.Mobile,
Job = profile.Job,
City = profile.City,
Address = profile.Address,
dof = profile.dof,
DP = profile.DP = Path.GetFileName(id+".png"),
CreatedOn = profile.CreatedOn,
Status = profile.Status
};
_context.Add(profile);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["rId"] = new SelectList(_context.Set<CharityRole>(), "rId", "Name", profile.rId);
return View(profile);
}
Question: How I can delete existing image and add a new one with same name bcz its display on user profile like:
<img src="#Url.Content("~/Upload/DP/"+ _userManager.GetUserName(User)+".png")">
There are two issues in your post.
You need to use Using for FileStream, otherwise, the filestream will be not disposed.
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await DP.CopyToAsync(fileStream);
}
You need to pass create instead of profile to _context.Add.
Here is the complete demo code:
public async Task<IActionResult> Create(Profile profile, IFormFile DP)
{
if (ModelState.IsValid)
{
var id = _userManager.GetUserName(HttpContext.User);
var fileName = Path.Combine(_environment.WebRootPath + "/Upload/DP/", Path.GetFileName(id + ".png"));
using (var fileStream = new FileStream(fileName, FileMode.Create))
{
await DP.CopyToAsync(fileStream);
}
var create = new Profile
{
UserName = profile.UserName,
DP = Path.GetFileName(id + ".png")
};
_context.Add(create);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(profile);
}
My cart is working fine in localhost but when i have hosted in cloud hosting it is not working well problem is that when i click add to cart button it will add one product with one quantity but when i add another product in the cart again it will override the previous one and show only one product in cart when i have added on last.. i don't know whats wrong with the sessions it will override the session again i guess. And another problem is that my my update cart button's functionalities and delete button functionalities in cart is not working it throw exception
Object reference not set to an instance of an object.
I have a controller name shoppingCartController here is the code
namespace Medi.Areas.User.Controllers
{
public class ShoppingCartController : Controller
{
ArrayList arr = new ArrayList();
int id;
BLL.IRepository<tbl_Product> de = new BLL.IRepository<tbl_Product>();
public ActionResult Index()
{
return View();
}
private int isExisting(int id)
{
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
if (cart[i].Pr.ProductID == id)
return i;
return -1;
}
public ActionResult Delete(int id)
{
int index = isExisting(id);
List<Items> cart = (List<Items>)Session["cart"];
cart.RemoveAt(index);
Session["cart"] = cart;
return PartialView("_pvCart");
}
public ActionResult OrderNow(string q)
{
if (Session["cart"] == null)
{
List<Items> cart = new List<Items>();
cart.Add(new Items(de.GetById(Convert.ToInt32(q)), 1));
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart,"Quantity","Quantity");
// cart[1]
}
else
{
id = Convert.ToInt32(q);
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity++;
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart, "Quantity", "Quantity");
}
return View("Cart");
}
[HttpPost]
public ActionResult UpdateCart(int[] ProductID,int [] quantity )
{
int[] x = new int[4];
int[] y = new int[4];
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
{
x[i] = ProductID[i];
y[i] = quantity[i];
updcart(x[i],y[i]);
}
Session["cart"] = cart;
return PartialView("_pvCart");
}
public void updcart(int id,int quantity) {
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity = quantity;
Session["cart"] = cart;
}
}
}
and here is the view name Cart.cshtml
#{
ViewBag.Title = "Cart";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("UpdateCart", "ShoppingCart", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }))
{
#Html.AntiForgeryToken()
<br />
<br />
<div id="MyData">
#{Html.RenderPartial("_pvCart");}
</div>
<br /><br />
<input id="updatecart" type="submit" value="update Cart" />
}
and here is the partial view code
#using Medi.Models;
<script src="~/Scripts/metro.min.js"></script>
<table class="table hovered" cellpadding=" 2" cellspacing="2" border="1px">
<tr class="info">
<th></th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Sub Total</th>
</tr>
#{
decimal s = 0;
}
#foreach (Items item in (List<Items>)Session["cart"])
{
<input id="ProductID" name="ProductID" type="hidden" value="#item.Pr.ProductID" />
s = s + (Convert.ToInt32(item.Pr.Price) * item.Quantity);
<tr>
<th>#Ajax.ActionLink("Delete", "Delete", new { id = item.Pr.ProductID }, new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }, new { #class = "mif-cross" })</th>
<td>#item.Pr.ProductName</td>
<td>#item.Pr.Price</td>
<td>
<input name="quantity" id="quantity" type="text" style="width:25px;" value="#item.Quantity" />
</td>
<td>#(item.Pr.Price * item.Quantity)</td>
</tr>
}
</table><br />
<hr />
<table cellpadding="1px" cellspacing="1px" style="float:right;">
<tr align="center" colspan="5" style="background-color:gray;">
<td><h3 style="padding:1px;">Total</h3></td>
<td> <h3 style="padding:1px;">Rs #s</h3></td>
</tr>
</table>
here is the model class
using BOL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Medi.Models
{
public class Items
{
tbl_Product pr = new tbl_Product();
public tbl_Product Pr
{
get { return pr; }
set { pr = value; }
}
int quantity;
public int Quantity { get; set; }
public Items()
{
}
public Items(tbl_Product product, int quantity)
{
this.Pr = product;
this.Quantity = quantity;
}
}
}
i have also write this code in web.config
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
<sessionState mode="InProc"/>
My cart is working fine in localhost but when i have hosted in cloud hosting it is not working well problem is that when i click add to cart button it will add one product with one quantity but when i add another product in the cart again it will override the previous one and show only one product in cart when i have added on last.. i don't know whats wrong with the sessions it will override the session again i guess. And another problem is that my my update cart button's functionalities and delete button functionalities in cart is not working it throw exception
Object reference not set to an instance of an object.
I have a controller name shoppingCartController here is the code
namespace Medi.Areas.User.Controllers
{
public class ShoppingCartController : Controller
{
ArrayList arr = new ArrayList();
int id;
BLL.IRepository<tbl_Product> de = new BLL.IRepository<tbl_Product>();
public ActionResult Index()
{
return View();
}
private int isExisting(int id)
{
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
if (cart[i].Pr.ProductID == id)
return i;
return -1;
}
public ActionResult Delete(int id)
{
int index = isExisting(id);
List<Items> cart = (List<Items>)Session["cart"];
cart.RemoveAt(index);
Session["cart"] = cart;
return PartialView("_pvCart");
}
public ActionResult OrderNow(string q)
{
if (Session["cart"] == null)
{
List<Items> cart = new List<Items>();
cart.Add(new Items(de.GetById(Convert.ToInt32(q)), 1));
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart,"Quantity","Quantity");
// cart[1]
}
else
{
id = Convert.ToInt32(q);
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity++;
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart, "Quantity", "Quantity");
}
return View("Cart");
}
[HttpPost]
public ActionResult UpdateCart(int[] ProductID,int [] quantity )
{
int[] x = new int[4];
int[] y = new int[4];
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
{
x[i] = ProductID[i];
y[i] = quantity[i];
updcart(x[i],y[i]);
}
Session["cart"] = cart;
return PartialView("_pvCart");
}
public void updcart(int id,int quantity) {
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity = quantity;
Session["cart"] = cart;
}
}
}
and here is the view name Cart.cshtml
#{
ViewBag.Title = "Cart";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("UpdateCart", "ShoppingCart", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }))
{
#Html.AntiForgeryToken()
<br />
<br />
<div id="MyData">
#{Html.RenderPartial("_pvCart");}
and here is the partial view code
#using Medi.Models;
<script src="~/Scripts/metro.min.js"></script>
<table class="table hovered" cellpadding=" 2" cellspacing="2" border="1px">
<tr class="info">
<th></th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Sub Total</th>
</tr>
#{
decimal s = 0;
}
#foreach (Items item in (List<Items>)Session["cart"])
{
<input id="ProductID" name="ProductID" type="hidden" value="#item.Pr.ProductID" />
s = s + (Convert.ToInt32(item.Pr.Price) * item.Quantity);
<tr>
<th>#Ajax.ActionLink("Delete", "Delete", new { id = item.Pr.ProductID }, new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }, new { #class = "mif-cross" })</th>
<td>#item.Pr.ProductName</td>
<td>#item.Pr.Price</td>
<td>
<input name="quantity" id="quantity" type="text" style="width:25px;" value="#item.Quantity" />
</td>
<td>#(item.Pr.Price * item.Quantity)</td>
</tr>
}
</table><br />
<hr />
<table cellpadding="1px" cellspacing="1px" style="float:right;">
<tr align="center" colspan="5" style="background-color:gray;">
<td><h3 style="padding:1px;">Total</h3></td>
<td> <h3 style="padding:1px;">Rs #s</h3></td>
</tr>
</table>
here is the model class
using BOL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Medi.Models
{
public class Items
{
tbl_Product pr = new tbl_Product();
public tbl_Product Pr
{
get { return pr; }
set { pr = value; }
}
int quantity;
public int Quantity { get; set; }
public Items()
{
}
public Items(tbl_Product product, int quantity)
{
this.Pr = product;
this.Quantity = quantity;
}
}
}
i have also write this code in web.config
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
<sessionState mode="InProc"/>
Wannt to give the user the possibility to select people via checkboxes in a list.
This sample works, but I would like to know, if you would do it the same way.
The main problem is, that javascript arbitrary objects cannot be compared against easily. So there must be a mapping.
Is this ok so? I don't want to create a custom-binding for this, where I could defined an Id field in the binding.
function Person(id, name, age) {
this.id = id;
this.name = name;
this.age = age;
}
function Party(id, name, persons) {
var self = this;
this.id = id;
this.name = name;
this.persons = ko.observableArray(persons);
this.persons_checked = ko.observableArray(); //<--- for the checkboxes
this.persons_checked.subscribe(function(newValue) {
var mapped = [];
mapped = $.map(newValue, function(id) {
return $.grep(listOfPeople, function(n) { return n.id == id; }); });
self.persons(mapped);
});
}
Complete Sample here: http://jsbin.com/ukipek/6/edit
Thank you
The simplest solution is to use knockoutjs 3.x and not 2.x, and it is magically done !
I've taken your example and modified it:
The HTML part:
<h1 data-bind="text: party.name"></h1>
<ul data-bind="foreach: people">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.party.persons_checked, attr: {value: id}">
<span data-bind="text:name"></span>
</li>
</ul>
And the JS part:
function Person(id, name, age) {
var self = this;
self.id = id;
self.name = name;
self.age = age;
}
function Party(id, name, persons) {
var self = this;
self.id = id;
self.name = name;
self.persons = ko.observableArray(persons);
self.persons_checked = ko.observableArray();
}
var listOfPeople = [
new Person(1, 'Fred', 25),
new Person(2, 'Joe', 60),
new Person(3, 'Sally', 43)];
var viewModel = function() {
var self = this;
this.party = new Party(1, "Weihnachtsfeier1", []);
this.people = ko.observableArray(listOfPeople);
};
ko.applyBindings(new viewModel());
No more mappings, knockoutjs handles everything alone :-)
You can have a look at this jsbin if you want : http://jsbin.com/sasuvuwabu/1/edit
Hope that helps !