Server error in application '/'. HTTP 404. MVC ASP.NET - c#

I am trying to show a view through the POST action method, but when calling this action it shows me the message "Server error in application '/'".
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) may have been removed, renamed, or temporarily unavailable. Please review the URL below and make sure it is spelled correctly.
I have already created my respective view for this method using the routes.MapMvcAttributeRoutes().
[Route("Home/AddPiloto")]
[Route("AddPiloto")]
public ActionResult AddPiloto()
{
return View();
}
Here is the POST action that I am calling from my html form, the method works and gets the data, only the view fails.
[HttpPost]
public ActionResult AddPiloto(PilotoClass pclass)
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("http://localhost:8080/AeronauticaDGAC/");
var request = httpClient.PostAsync("webresources/conndatabase.piloto/supCreatePost", pclass,
new JsonMediaTypeFormatter()).Result;
if (request.IsSuccessStatusCode)
{
var resultString = request.Content.ReadAsStringAsync().Result;
var succes = JsonConvert.DeserializeObject<bool>(resultString);
ViewBag.Mg = succes;
return RedirectToAction("AddPiloto");
}
ViewBag.Mg = request.StatusCode;
return RedirectToAction("Index",ViewBag);
}
Finally here I have a typical form that calls this method POST.
<form action="AddPiloto" method="post">
<div class="form-group">
<input class="form-control" type="number" name="id" value="" placeholder="Id" />
<input id="inp1" class="form-control" type="text" name="nombre" value="" placeholder="Nombre" />
<input id="inp1" class="form-control" type="text" name="apellido" value="" placeholder="Apellido" />
<input id="inp1" class="form-control" type="number" name="edad" value="" placeholder="Edad" />
<hr />
<input class="btn btn-primary" type="submit" name="button" value="Enviar" />
<input onclick="limpiarFormulario1()" class="btn btn-danger" type="button" name="button" value="Limpiar" />
</div>
</form>
I already have the view created, compile and recompile the solution, clear the browser cache, check if the file exists and restart the IIS server, but nothing works for me, if someone knows any possible solution I would greatly appreciate the answer.
Thanks in advance.
All code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net.Http;
using Newtonsoft.Json;
using AeronauticaClient.Models;
using System.Net.Http.Formatting;
namespace AeronauticaClient.Controllers
{
[RoutePrefix("Home")]
[Route("{action}")]
public class HomeController : Controller
{
[Route("~/")]
[Route("")]
[Route("Index")]
[HttpGet]
public ActionResult Index()
{
System.Net.Http.HttpClient CHttp = new HttpClient();
CHttp.BaseAddress = new Uri("http://localhost:8080/AeronauticaDGAC/");
var request = CHttp.GetAsync("webresources/conndatabase.piloto/supFindAllGet").Result;
if (request.IsSuccessStatusCode)
{
var resultString = request.Content.ReadAsStringAsync().Result;
var listado = JsonConvert.DeserializeObject<List<PilotoClass>>(resultString);
ViewBag.Message = request;
return View(listado);
}
else
{
ViewBag.Message = request;
}
return View();
}
[Route("Home/AddPiloto")]
[Route("AddPiloto")]
public ActionResult AddPiloto()
{
return View();
}
[HttpPost]
public ActionResult AddPiloto(PilotoClass pclass)
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("http://localhost:8080/AeronauticaDGAC/");
var request = httpClient.PostAsync("webresources/conndatabase.piloto/supCreatePost", pclass,
new JsonMediaTypeFormatter()).Result;
if (request.IsSuccessStatusCode)
{
var resultString = request.Content.ReadAsStringAsync().Result;
var succes = JsonConvert.DeserializeObject<bool>(resultString);
ViewBag.Mg = succes;
return RedirectToAction("AddPiloto");
}
ViewBag.Mg = request.StatusCode;
return RedirectToAction("Index",ViewBag);
}
}
}
Routing code.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

When you redirect to index, you're passing ViewBag as an argument.
return RedirectToAction("Index",ViewBag);
But the server cannot find an index method receiving that parameter, so it raises an exception.
Remove ViewBag as an argument when you redirect.
return RedirectToAction("Index");
Before redirecting, replace ViewBag for TempData
if (request.IsSuccessStatusCode)
{
var resultString = request.Content.ReadAsStringAsync().Result;
var succes = JsonConvert.DeserializeObject<bool>(resultString);
TempData["Mg"] = succes;
return RedirectToAction("AddPiloto");
}
TempData["Mg"] = request.StatusCode;
return RedirectToAction("Index");
To retrieve the value you stored in previous step, use TempData["Mg"] further on.
You need TempData instead because after RedirectToAction you'll be in a new request. Since ViewBag is only available for same request, the values would be lost after redirecting.

Related

I don't understand why I have null MVC AJAX

I have Get and Post partial Action. Get take me a list of image which I have in ma app.
[HttpGet]
public PartialViewResult ViewImageFileList()
{
IEnumerable<string> allImages = Directory.EnumerateFiles(Server.MapPath("~/Images/NBAlogoImg/"));
return PartialView(allImages);
}
Post delete image which I extra.
[HttpPost]
public PartialViewResult ViewImageFileList(string imageNameType)
{
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), imageNameType);
if (System.IO.File.Exists(fileToDeletePath))
{
fileOperations.Delete(fileToDeletePath);
}
return PartialView();
}
My .chhtml of my partial view
#model IEnumerable<string>
<div class="name-block-style">
Логотипы которые имеются
</div>
<div id=team-logo-wrapper-images>
<ul>
#foreach (var fullPath in Model)
{
var fileName = Path.GetFileName(fullPath);
<li>
<div class="box-name-image">
<p class="image-name-type">#fileName</p>
<img src="#Url.Content(string.Format("~/Images/NBAlogoImg/{0}", fileName))"
class="logo-images" alt="Логотип команды"
title="Логотип команды" />
</div>
</li>
}
</ul>
<div id="delete-image-form" class="form-group">
#using (Ajax.BeginForm(
"ViewImageFileList",
"Team",
new AjaxOptions() { HttpMethod = "POST", OnComplete = "reloadPage()" }))
{
<label>Введите имя с указание типа изображения</label>
<input type="text" class="form-group" name="imageNameType" id="imageNameType" />
<input type="submit" value="Удалить" class="btn btn-primary" />
}
</div>
<script>
function reloadPage() {
location.reload();
}
</script>
My problem is Null references when I write the deleting image and submit it(i do it by ajax). I have this error Null reference but when I click to continue, the image deleted and my script to reload page work.
I want to understand why I take the null and how I can fix it, because it stops my app always when I delete an image.
The problem is that when you POST after you delete the image you don't populate the model of the partial view, as you do correctly in ViewImageFileList. This has a result when the View Engine try to build the view that you would send after the POST to the client, to get a null reference exception when try to perform the foreach on a null reference.
That being said, the thing you need is to pass to the PartialView all the images. So just add before the return statement in the action method you POST this:
var allImages = Directory.EnumerateFiles(Server.MapPath("~/Images/NBAlogoImg/"));
return PatialView(allImages);
When you browsing images you return view with model passed
return PartialView(allImages); //allImages is a model
But when you deleting images you return view without any model
return PartialView(); //need to pass a model
So after deleting you would like to redirect to ViewImageFileList to browse
all images
[HttpPost]
public RedirectToRouteResult ViewImageFileList(string imageNameType)
{
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), imageNameType);
if (System.IO.File.Exists(fileToDeletePath))
{
fileOperations.Delete(fileToDeletePath);
}
return RedirectToAction("ViewImageFileList");
}
or retrieve images in delete action once again and pass the list to view
[HttpPost]
public PartialViewResult ViewImageFileList(string imageNameType)
{
var fileToDeletePath = Path.Combine(Server.MapPath("~/Images/NBAlogoImg/"), imageNameType);
if (System.IO.File.Exists(fileToDeletePath))
{
fileOperations.Delete(fileToDeletePath);
}
IEnumerable<string> allImages = Directory.EnumerateFiles(Server.MapPath("~/Images/NBAlogoImg/"));
return PartialView(allImages);
}

Search function with a foreign API in MVC architechture

I am trying to mess around with a foreign API, but i cant seem to get the last bit working. I have succesfully retrieved data from the API but i cannot get the search functionality to cooperate with the API. The search function needs an id, and from that an object is returned. Here is what i have so far:
Controller
[HttpGet]
public ActionResult GetCardsByID(string idNumber)
{
//idNumber = "c353618d9f76c03a0c7d549f2d877f9533112d0c";
ViewBag.Message = "Your GetCardsByID page.";
var client = new RestClient("https://api.magicthegathering.io");
var request = new RestRequest("v1/cards/{id}", Method.GET);
request.AddUrlSegment("id", idNumber);
IRestResponse response = client.Execute(request);
var content = response.Content;
CardContainer cards = JsonConvert.DeserializeObject<CardContainer>(content);
return View();
}
View
#{
ViewBag.Title = "GetCardsByID";
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<p>
In this tab we can retrieve a card by searching with an id
</p>
<form method="get" action="#Url.Action("GetCardsByID", "CardsController")">
<label for="idNumber">Search</label>
<input type="text" name="idNumber" id="idNumber" />
<button type="submit">Perform search</button>
</form>
Routing
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id =
UrlParameter.Optional }
);
}
}
The error i get is as follows: (Translated)
Server error in program'/'.
Resource not found.
Description: HTTP 404, the resource you are looking for, or one of its dependencies, has possible been removed and is not accesable at this moment. Check if the following URL-addresses are spelled correctly
Wanted URL address: /CardsController/GetCardsByID
Home page GetCardsByID page Search error
When you call a controller, don't put controller on the end of it.
Try this:
<form method="get" action="#Url.Action("GetCardsByID", "Cards")">
<label for="idNumber">Search</label>
<input type="text" name="idNumber" id="idNumber" />
<button type="submit">Perform search</button>
</form>
Note the Url.Action is Cards, not CardsController
Even though your controller is called CardsController.cs
You know you could probably do this easier entirely in javascript

How to return a file path to the controller to parse a JSON file

I have a very simple view that will prompt a user to select a JSON file and then parse it.
Here is the relevant code from the view...
#using (Html.BeginForm("AddSampleDataJSON", "Event"))
{
<input type="file" name="GetJSONFile" /><br>
<input type="submit" />
}
Here is the method from the controller:
[HttpPost]
public ActionResult AddSampleDataJSON(FormCollection form)
{
string path = ??
using (StreamReader r = new StreamReader(path))
{
string json = r.ReadToEnd();
List<Event> events =
JsonConvert.DeserializeObject<List<Event>>(json);
}
return View();
}
The question then is how do I access the full path so I can send it to the StreamReader to eventually parse the JSON. I don't see it in the FormCollection object.
You won't be able to access the client path to the file. You'll only see the file name.
You should set the encoding to multipart/form-data in your view:
#using (Html.BeginForm("AddSampleDataJSON", "Event", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="uploadedFile" /><br>
<input type="submit" />
}
And in your controller change your input parameter to HttpPostedFileBase, with the parameter name being the same as the name parameter in the form:
[HttpPost]
public ActionResult AddSampleDataJSON(HttpPostedFileBase uploadedFile)
{
using (StreamReader r = new StreamReader(uploadedFile.InputStream))
{
string json = r.ReadToEnd();
List<Event> events = JsonConvert.DeserializeObject<List<Event>>(json);
}
return View();
}

MVC route URL not containing parameter

I'm attempting to wrap my head around .NET MVC5 routing.
I've got a form:
#using (Html.BeginForm("ProductsCheaperThan", "Home", FormMethod.Post))
{
<input type="text" name="comparisonPrice" />
<button type="submit">Search!</button>
}
And I've got a controller Home and an action ProductsCheaperThan which takes a parameter comparisonPrice
public ActionResult ProductsCheaperThan(decimal comparisonPrice)
{
ViewBag.FilterPrice = comparisonPrice;
var resultSet = new ProductService().GetProductsCheaperThan(comparisonPrice);
return View(resultSet);
}
This posts the value in the input (let's suppose that the value I'm posting is 20) back to my action, and correctly routes me to ~/Home/ProductsCheaperThan. The problem is, I'd like to be routed to ~/Home/ProductsCheaperThan/20
I'd like to do this so that if somebody bookmarks the page they don't end up getting an error when they revisit the page.
I thought that adding something like:
routes.MapRoute(
name: "ProductsCheaperThan",
url: "Home/ProductsCheaperThan/{comparisonPrice}",
defaults: new { controller = "Home", action = "ProductsCheaperThan", comparisonPrice = 20 }
);
might work, and I have one solution to my problem which changes the form to a GET
#using (Html.BeginForm("ProductsCheaperThan", "Home", FormMethod.Get))
and produces a URL of ~/Home/ProductsCheaperThan?comparisonPrice=20, but that uses a query string instead, and isn't exactly what I was aiming for.
Can anybody help me get my URL right?
You should add [HttpPost] attribute to your action
[HttpPost]
public ActionResult ProductsCheaperThan(decimal comparisonPrice)
{
ViewBag.FilterPrice = comparisonPrice;
var resultSet = new ProductService().GetProductsCheaperThan(comparisonPrice);
return View(resultSet);
}
One option is to use JQuery -
<div>
<input type="text" name="comparisonPrice" id="comparisonPrice" />
<button type="button" id="Search">Search!</button>
</div>
#section scripts{
<script>
$(function () {
$("#Search").click(function () {
window.location = "#Url.Action("PriceToCompare", "Home")" + "/" + $("#comparisonPrice").val();
});
});
</script>
}
Above script will result in - http://localhost:1655/PriceToCompare/Home/123
I think you can specify your route values using an overload:
#using (Html.BeginForm("Login", "Account", new { comparisonPrice= "20" }))
{
...
}

Routing Issue on asp.net mvc 5 GET

I am trying to get my product search URL to look like "Products/Search/{search term here}".
I am using attribute based routing and my controller action looks like this:
[HttpGet]
[Route("Products/Search/{searchTerm?}", Name="ProductSearch")]
public ActionResult Search(string searchTerm = "")
{
return View();
}
I have tried using the HTML Helper for BeginForm and BeginRouteForm (shown below) but have not had luck with either. The right action is being called, but my URL looks like "Products/Search?searchTerm"
BeginRouteForm
#using (Html.BeginRouteForm("ProductSearch", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
BeginForm
#using (Html.BeginForm("Search", "Products", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
I have gone through debugging and the right route is selected, the URL is just not displaying how I wanted it to. What am I missing?
Here is the solution I suggest -
You have the following controller Action -
[HttpGet]
public ActionResult Search(string searchTerm = "")
{
return View();
}
Let the view be -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click').click(function (e) {
var name = $("#search").val();
var url = '#Url.Action("Search", "Action")' + '/' + name;
window.location.href = url;
});
});
</script>
<input type="text" name="searchText" id="search"/>
<input type="button" value="click" id="click"/>
And when you click the button -
Do not forget to have proper route to be added on to the route configuration -
routes.MapRoute(
name: "searchaction",
url: "{controller}/{action}/{searchTerm}",
defaults: new { controller = "Action", action = "Search" }
);
The problem you think you are experiencing isn't because of anything about ASP.Net MVC. All Html Forms that use the method GET will translate all input elements into QueryString parameters. This is just a W3C standard.
If you want this to work, you'll have to write jQuery to throw an event before the form is submitted, take the text value from the input store it temporarily, empty the input box, and then update the action by appending the temporary value.
I don't think that BeginRouteForm works the way that you're expecting it to. According to the documentation, all that the method does is insert a <form> using the arguments provided. If you had provided something other than an empty string for the route value such as , new { searchTerm = "somesearchterm" }, you would see that show up in the Url as "/product/search/somesearchterm". As it is now, however, the form will be processed as normal, putting the search term on the Url as a normal query parameter.

Categories

Resources