I am developing a project in asp.net mvc structure.I want to create the detail page of the books I bought from a web service, but I encountered a problem and could not solve it. I need help.
Web Api: https://gutendex.com/
These are the codes for my homepage.
#model BookListModel
<div class="col-md-12">
<div class="row">
#foreach (var books in Model.results)
{
<div class="col-md-3 text-truncate">
<img src="#books.formats.imagejpeg" alt="...">
<div class="card-body">
<h5 class="card-title">#books.title</h5>
</div>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<a class="btn btn-primary stretched-link" asp-controller="Book" asp-action="Details" asp-route-id="#books.id">Details</a>
<button type="button" class="btn btn-sm btn-outline-secondary">Add</button>
</div>
</div>
<br />
</div>
}
</div>
</div>
public class BookRepository
{
private static List<Result> results;
public static Result GetBooksById(int id)
{
return results.FirstOrDefault(b => b.id == id); // PROBLEM HERE
}
}
public IActionResult Details(int id)
{
return View(BookRepository.GetBooksById(id));
}
#model Result
<div class="card mb-3">
<div class="card-body">
<div class="row no-gutters">
<div class="col-md-3">
<img src="#Model.formats.imagejpeg" class="card-img">
</div>
<div class="col-md-9">
<h5 class="card-title">#Model.title</h5>
<p class="card-text">#Model.subjects</p>
<p class="card-text">
<small class="text-muted">3 days ago</small>
</p>
</div>
</div>
</div>
</div>
I wrote a book repository class to help me, the id of the book comes from there with the help of a button, but my method returns a null value.
It gives an error here, it returns null.
Your private static List<Result> results; is null. You should initialized that at some point/somewhere. Or load data into it, whatever is your intent. At least that is what the errors indicates, FirstOrDefault is an extensions method called on the collection, but that fails if said collection is null. And your code does not show if it is initialized somewhere.
i.e.
results = new List<Result> { new Result(...) }
Related
I have added stripe payment as an Identity folder in my project and I have two tables named OrderHeader and Orderdetails entities in my data base.I created a SD class which has some status and the default status is "Pending_Payment".this status should be updated to Submitted_PaymentApproved in database after placing order,but all of my orders save as Pending_Payment in database .As a result,when I definite to show the list of orderHeaders which are in Inprocess or Submitted status ,it doesnt show me any data but when I change it to pending status it shows.I want to know what should I do to update the status from pending?
public class ManageOrderModel : PageModel
{
private readonly IUnitOfWork _uniOfWork;
public List<OrderDetailVM> OrderDetailVM { get; set; }
public ManageOrderModel(IUnitOfWork unitOfWork)
{
_uniOfWork = unitOfWork;
}
public void OnGet()
{
OrderDetailVM = new();
List<OrderHeader> orderHeaders = _uniOfWork.OrderHeader.GetAll(u => u.Status ==SD.StatusSubmitted || u.Status == SD.StatusInProcess).ToList();
foreach(OrderHeader item in orderHeaders)
{
OrderDetailVM individual = new OrderDetailVM()
{
OrderHeader = item,
OrderDetails = _uniOfWork.OrderDetails.GetAll(u => u.OrderId == item.Id).ToList()
};
OrderDetailVM.Add(individual);
}
}
}
}
this is my view of my razor page block:
#page
#model PracticeWithVideo.Pages.Admin.Order.ManageOrderModel
<h1 class="text-primary py-3">Manage Order's</h1>
<form method="post">
<div class="container row bg-white p-2 mb-3 rounded">
#foreach(var item in Model.OrderDetailVM)
{
<div class="col-12 pb-3 pt-3 mt-4 border rounded">
<div class="row">
<div class="col-4">
Order Number: #item.OrderHeader.Id
<ul class="text-info">
#foreach(var details in item.OrderDetails)
{
<li>#details.Name x #details.Count</li>
}
</ul>
</div>
<div class="col-4 pb-2">
<div class="input-group pb-2">
<div class="input-group-prepend">
<span class="input-group-text bg-secondary border">Time</span>
</div>
<input type="text" value="#item.OrderHeader.PickUpTime" class="form-control" readonly />
</div>
<textarea readonly asp-for="#item.OrderHeader.Comments" class="rounded border form-control" rows="3"></textarea>
</div>
<div class="col-3 offset-1 d-flex align-content-center">
<div class="col-12">
<button type="submit" class="btn btn-primary form-control mb-3">
<i class="bi bi-check-square"></i> Start Cooking
</button>
<button type="submit" class="btn btn-success form-control mb-3">
<i class="bi bi-emoji-laughing"></i> Order Ready
</button>
<button type="submit" class="btn btn-warning form-control mb-3">
<i class="bi bi-x-square-fill"></i> Cancel Order
</button>
</div>
</div>
</div>
</div>
}
</div>
</form>
I change the
List<OrderHeader> orderHeaders = _uniOfWork.OrderHeader.GetAll(u => u.Status ==SD.StatusSubmitted || u.Status == SD.StatusInProcess).ToList();
to
List<OrderHeader> orderHeaders = _uniOfWork.OrderHeader.GetAll(u => u.Status ==SD.StatusPending ).ToList();
and it shows the data because all of my orders saved as Pending_payment in my database.I need to show change the status from pending to submitted after placing order and display the data when I run my project
Even though the model is not null the required html is not rendered. This is my razor view:
#model List<Product>
#{
ViewBag.Title = "Cart";
}
#for(int i=0;i<=Model.Count()-1;i++)
{
<p>foreach triggered</p>
var image = "~/images/" + Model[i].product_image_path;
<div class="row">
<div class="col">
<div class="row">
<div class="col-md-2">
<img src="#image" alt="No image" class="img-fluid" width="60" asp-append-version="true" />
</div>
<div class="col-md-4">
<div class="row">
<div class="col">
<p class="justify-content-md-start">#Model[i].ProductName</p>
</div>
</div>
<div class="row">
<div class="col">
<p>₹#Model[i].Price</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row">
<div class="col-md-8">
#*change quantity button*#
<div class="input-group">
<button type="submit" class="btn btn-light"> - </button>
<input type="text" class="form-control" value="#Model[i].Quantity" readonly />
<button type="submit" class="btn btn-light"> + </button>
</div>
</div>
</div>
<br />
</div>
<div class="col-md-2">
<div class="row">
<div class="col">
<button class="btn btn-danger" type="button" id="button-minus">Remove</button>
</div>
</div>
</div>
</div>
</div>
</div>
}
Here is my get action method. This is basically retrieving the product from the models. I am returning an object of List<Product>. Trying to loop over it using for loop on razor view does not seem to work.
[HttpGet]
public IActionResult Cart()
{
var model = new CartProductViewModel();
var sessionId = HttpContext.Session.Id;
var allCartItems = context.cartItems;
var allProducts = context.products;
var currentCartItem = allCartItems.Where(p => p.Product.ProductId.Equals(sessionId)).Select(p=>p).ToList();
List<Product> products = new List<Product>();
foreach (var item in currentCartItem)
{
var id = item.Product.ProductId;
if (id is null) { return View("NotFound"); }
Product prod = allProducts.Where(p => p.ProductId.Equals(id)).Select(p=>p).Single();
products.Add(prod);
}
return View(products);
}
I have a problem with implement saving value with input type number to the database. I have created website with ASP .NET MVC with UnitOfWork and Repositories. I have a Commodity model, where I have field Amount, and I have HomeViewModel in which I have a field Amount also. I would like to overwrite the amount field from the commodity model. Should I use onchange or onclick in input or a tags in html code, or all with my basic ideas are nonsens ?
Below is the code snippet with view created in RazorPages with extension .cshtml.
<div class="col-12">
<div class="row my-3">
#foreach(var Commodity in Model.CommodityList.Where(c=>c.CategoryId==category.Id))
{
<div class="col-lg-4 col-xl-3 col-md-6 pb-4">
<div class="card" style="border:2px solid #43ac6a;border-radius:5px;
backgroundcolor: #fffeee">
<div class="pl-3 pt-1 text-center">
<h3 class="card-title text-primary"><b>#Commodity.Name</b></h3>
</div>
<div class="d-flex justify-content-between">
<div class="pl-1 text-muted">#localizer.Get("Price")</div>
<div class="pr-1 text-danger h5">$#Commodity.Price</div>
</div>
<img src="#Commodity.ImageUrl" class="card-img-top p-2 rounded" />
<div class="col-9">
<input onchange="save()" asp-for="#Commodity.Amount" type="number"
id="quantity" name="quantity" min="0" max="100" />
</div>
<a onclick="save()" asp-action="Details" class="btn btn-success"
style="border-
radius:2px;" asp-route-id="#Commodity.Id"
onclick="save()">#localizer.Get("Details")</a>
</div>
</div>
}
</div>
</div>
My problem is that I can't write the value from after pressing the button below as the tag.
Below is the method written by me in controller regarding to the view
public IActionResult Index()
{
HomeVM = new HomeViewModel()
{
CategoryList = _unitOfWork.Category.GetAll(),
CommodityList = _unitOfWork.Commodity.GetAll(includeProperties: "Category"),
ServiceList = _unitOfWork.Service.GetAll(includeProperties: "Category,Payment"),
EmployeeList = _unitOfWork.Employee.GetAll(includeProperties: "Service"),
Amount = _unitOfWork.Commodity.GetFirstOrDefault(includeProperties:
"Category").Amount
};
foreach (var commodity in (_unitOfWork.Commodity.GetAll(includeProperties:
"Category")))
{
var CommodityFromDb = commodity;
CommodityFromDb.Amount = HomeVM.Amount;
_unitOfWork.Save();
}
_unitOfWork.Save();
return View(HomeVM);
}
I have a guess that you probably need to do it somehow with jquery, in a file with the extension js, but I have no idea how. I would be grateful for any help.
I have a Razor Index page with a button, that when clicked should run an action on the Home Controller, but when I debug the home controller, the action is not firing and the break point not being hit.
The Razor code is:
#{
ViewBag.Title = "csi media web test";
}
<div class="jumbotron">
<h1>csi media web test</h1>
<p class="lead">Liane Stevenson</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading"><i class="glyphicon glyphicon-arrow-right"></i> Enter Your Four Numbers</div>
<div class="panel-body">
<form class="form-inline">
<div class="col-md-9">
<div class="form-group">
<label class="sr-only" for="number1">1st Number</label>
<input type="number" class="form-control" id="number1" name="Number1" placeholder="#1">
</div>
<div class="form-group">
<label class="sr-only" for="number2">2nd Number</label>
<input type="number" class="form-control" id="number2" name="Number2" placeholder="#2">
</div>
<div class="form-group">
<label class="sr-only" for="number3">3rd Number</label>
<input type="number" class="form-control" id="number3" name="Number3" placeholder="#3">
</div>
<div class="form-group">
<label class="sr-only" for="number4">4th Number</label>
<input type="number" class="form-control" id="number4" name="Number4" placeholder="#4">
</div>
</div>
<div class="col-md-3 text-right">
<button class="btn btn-default" onclick="location.href='#Url.Action("SortDesc", "Home")'"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</button>
<button class="btn btn-default" onclick="location.href='#Url.Action("SortAsc", "Home")'"><i class="glyphicon glyphicon-arrow-up"></i> Sort Asc</button>
</div>
</form>
<p>
#if (Model != null)
{
foreach (int number in Model.Numbers)
{
<span class="label label-info">#number</span>
}
}
</p>
</div>
</div>
</div>
</div>
And the Action is:
public ActionResult SortDesc (string number1, string number2, string number3, string number4)
{
NumberSetList list = new NumberSetList();
List<int> numbers = new List<int>();
numbers.Add(Convert.ToInt32(number1));
numbers.Add(Convert.ToInt32(number2));
numbers.Add(Convert.ToInt32(number3));
numbers.Add(Convert.ToInt32(number4));
numbers.OrderByDescending(i => i);
list.SortOrder = "Desc";
return View(list);
}
When it runs it does however change the URL of the page to:
http://localhost/Home/Index?number1=5&number2=4&number3=3&number4=9
So it's almost as if it knows the action is there and what it takes but it just doesn't run it?
What you need is a anchor tag and not a button. Having a link on a tag will actually change the browser URL to the value given in its href. Where as a button will do nothing. To change the URL you will have to add additional Javascript to handle it.
So change this
<button class="btn btn-default" onclick="location.href='#Url.Action("SortDesc", "Home")'">
<i class="glyphicon glyphicon-arrow-down"></i> Sort Desc
</button>
to
<a class="btn btn-default" href="#Url.Action("SortDesc", "Home")">
<i class="glyphicon glyphicon-arrow-down"></i> Sort Desc
</a>
Do the same changes to your other button syntax too.
This code is pseudo code and is untested but this should give you an idea
put this in your models folder
public class myViewModel
{
public int Number1 {get; set;}
public int Number2 {get; set;}
public int Number3 {get; set;}
public int Number4 {get; set;}
}
change your controller to something like this
[HttpPost]
public ActionResult SortDesc (myViewModel model)
{
if(!ModelState.IsValid)
{
return View(list)
}
else
{
NumberSetList list = new NumberSetList();
List<int> numbers = new List<int>();
numbers.Add(model.Number1);
numbers.Add(model.Number2));
numbers.Add(model.Number3));
numbers.Add(model.Number4));
numbers.OrderByDescending(i => i);
list.SortOrder = "Desc";
return View(list);
}
}
this will tell you if your model is valid or not, but I suspect your data is being passed and read as an integer rather than a string, so you could try changing the object type first and then try model binding
but on a review of my code just then, you might be missing the [HttpPost] attribute at the start of the code block which would mean this is always a HttpGet
In my asp.net mvc form I have 2 buttons, one to save which will save data from the from in a list in sharepoint and the second button does the same and additionally it applies some css colors.
I doubt however how to use 2 actions on the same form (same controller)
this is my view
#{
Layout = "~/Views/Shared/_LayoutPage2.cshtml";
}
#using (Html.BeginForm("Index", "Movies", FormMethod.Post))
{
<div class="row">
<div class="col-md-8">
<div class="col-xs-6 col-sm-3" id="stylesheet">Hojas de estilos</div>
<div class="col-xs-6 col-sm-3">
#Html.DropDownList("cssFiles", (IEnumerable<SelectListItem>)ViewBag.cssFiles, "Crear Nuevo", new { #class = "form-control", #id = "selCssFile" })
<span>
<input type="text" class="form-control" id="txtFileName" style="display:none;" placeholder="Nombre del archivo">
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8">
Color base, links, botones, borde encabezado y pie
</div>
<div class="col-md-4">
<div id="colorSelector" class="colorSelector"><div style="background-color: #0000ff"></div></div>
</div>
</div>
<div class="row">
<div class="col-md-8">
Fondo de la pagina, fondo de los cuadros
</div>
<div class="col-md-4">
<div id="colorSelector2" class="colorSelector"><div style="background-color: #0000ff"></div></div>
</div>
</div>
<div class="row">
<div class="col-md-8">
Navegación
</div>
<div class="col-md-4">
<div id="colorSelector3" class="colorSelector"><div style="background-color: #0000ff"></div></div>
</div>
</div>
<div class="row">
<div class="col-md-8">
Navegación (Item seleccionado)
</div>
<div class="col-md-4">
<div id="colorSelector4" class="colorSelector"><div style="background-color: #0000ff"></div></div>
</div>
</div>
<div class="row">
<div class="col-md-8">
Pie de página
</div>
<div class="col-md-4">
<div id="colorSelector5" class="colorSelector"><div style="background-color: #0000ff"></div></div>
</div>
</div>
<div class="row" id="buttons">
<div class="col-md-8">
</div>
<div class="col-md-4">
<button type="button" class="btn btn-success">Guardar</button>
<button type="button" class="btn btn-primary">Guardar y aplicar</button>
</div>
</div>
}
My index action on the customize controller so far
public class CustomizeController : Controller
{
// GET: Customize
public ActionResult Index()
{
User spUser = null;
var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
using (var cc = spContext.CreateUserClientContextForSPHost())
{
int aprovisionado = (int)cc.Web.GetPropertyBagValueInt("Vinculosc.PlantillasIntranet.Aprovisionado", 0);
if (aprovisionado == 0)
{
string libraryName = "ConfiguraciónColores";
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("Color1", "Text");
fields.Add("Color2", "Text");
fields.Add("Color3", "Text");
fields.Add("Color4", "Text");
fields.Add("Color5", "Text");
//ProvisionTemplate(cc);
CreateLibrary(cc, libraryName);
AddFields(cc, libraryName, fields);
}
}
#region comments
/*Uri hostWeb = new Uri(Request.QueryString["SPHostURL"]);
using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity))
{
var web = clientContext.Web;
clientContext.Load(web, w => w.Lists.Include(l => l.Title).Where(l => !l.hidden));
clientContext.ExecuteQuery();
return View(web.Lists);
}*/
#endregion
return View();
}
You can put the same name in the view with different value
<button type="submit" name="Guardar" value="guardar" class="btn btn-success">Guardar</button>
<button type="submit" name="Guardar" value="aplicar" class="btn btn-primary">Guardar y aplicar</button>
And in the Controller you can check the value of the button
if (Request["Guardar"].ToString() == "guardar")
{
//Your code for the first button
}
else
{
//Your code for the second button
}
Your button type should be "submit", and you can give them a name... Same name, that can be reused in a model, or by Request.Form["GiveAName"]
Your controller should have a
[HttpPost]
public ActionResult Index()
{
... Your code to retrieve form values
}
Anyway that's bad coding... You should work with models to inject on the view, that same model could be retrieved back and so you don't have to worry about retrieving form values. :=)