asp.net mvc My Form action is empty - asp.net-mvc-4

I have define my routeconfig as :
routes.MapRoute(
"addcomments",
"addcomments/{urlLanguage}",
new { controller = "Home", action = "addcomments", urlLanguage = "h" }
);
and in Homecontroller :
public ActionResult addcomments(string urlLanguage)
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public string addcommentssave(int id, string yourName, string youremail, string website, string yourComment)
{
string message = " Thanks for sharing your comment! If your comment doesn't appear right away, please be patient as it may take a few minutes to publish or may require moderation.";
DateTime WishDateTime = DateTime.UtcNow;
string szRemoteAddr = System.Web.HttpContext.Current.Request.UserHostAddress;
Comments commit = new Comments();
commit.comdate = WishDateTime;
commit.comments = yourComment;
commit.email = youremail;
commit.Name = yourName;
commit.Website = website;
commit.IpAddress = szRemoteAddr;
commit.PostId = id;
commit.IsVisible = 0;
_session.Comment.Add(commit);
_session.SaveChanges();
//ViewBag.result= "<div class='message success'>" + message + "</div>";
// return View();
return "<div class='message success'>" + message + "</div>";
}
in addcomments view
#using (Ajax.BeginForm("addcommentssave", "home", null,
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "commentmessage",
OnBegin = "wait()",
OnSuccess = "success()",
LoadingElementId = "updating" },
new { id = "_commitForm" }))
{
}
but when i run it my form action become empty like
form action="" ....`
how to i solve it, help me

I created a simple test site to try and see if I could replicate your issue.
Here is my route config:
namespace Comments
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// Use LocalDB for Entity Framework by default
Database.DefaultConnectionFactory = new SqlConnectionFactory(#"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
}
Here is my HomeController.cs:
namespace Comments.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return RedirectToAction("AddComment");
}
[HttpGet]
public ActionResult AddComment()
{
return View();
}
[HttpPost]
public ActionResult AddComment(int id, string yourName, string youremail, string website, string yourComment)
{
return Content(String.Format("Got a comment, id = {0}, yourName = {1}, youremail = {2}, website = {3}, yourComment = {4}",
id,
yourName,
youremail,
website,
yourComment));
}
}
}
Here is my AddComment.cshtml:
#{
ViewBag.Title = "Add Comment";
}
<h2>Add Comment</h2>
#using (Ajax.BeginForm("AddComment", "Home", null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "commentmessage", OnBegin = "wait()", OnSuccess = "success()", LoadingElementId = "updating" }, new { id = "_commitForm" }))
{
<b>Form Here</b>
}
Here is the view source:
<DOCTYPE html>
<html>
<head>
<title>Add Comment</title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
</head>
<body>
<h2>Add Comment</h2>
<form action="/Home/AddComment" data-ajax="true" data-ajax-begin="wait()" data-ajax-loading="#updating" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-success="success()" data-ajax-update="#commentmessage" id="_commitForm" method="post"> <b>Form Here</b>
</form>
</body>
</html>
So you can see the form path rendering. Try simplifying your route config (I didn't do anything special).

Related

Where i must get Ajax Helper or how to create it to use #AjaxExtensions.ActionLink

I want to use #AjaxExtensions.ActionLink(AjaxHelper, String, String, String, RouteValueDictionary, AjaxOptions) in cshtml file (ASP.Net 6 MVC).
#model List<Shift>
#using System.Web.Mvc.Ajax;
#{
AjaxOptions deleteOptions = new AjaxOptions()
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "table"
};
}
#foreach (Shift shift in Model)
{<td>
#AjaxExtensions.ActionLink( ???,"Delete", "DeleteShift", "MainDoctor", new{id=shift.Id}, deleteOptions)
</td>
}
As this document said, AjaxExtensions.ActionLink is only applies to ASP.NET MVC 5.2, and the correct usage should be:
#Ajax.ActionLink("Delete", "DeleteShift", "MainDoctor", new { id = shift.Id }, deleteOptions)
In ASP.NET 6, you need use an alternative way like below:
<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#table" data-ajax-url="#Url.Action("DeleteShift", "MainDoctor", new { id = shift.Id})">Delete</a>
A simple working demo you could follow:
Model:
public class Test
{
public string Id{ get; set; }
}
View(Views/Home/Index.cshtml):
#model Test
<div id="table">
#Model.Id
<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#table" data-ajax-url="#Url.Action("DeleteShift", "MainDoctor", new { id = 1 })">Delete</a>
</div>
#section Scripts
{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ajax-unobtrusive/3.2.6/jquery.unobtrusive-ajax.js" integrity="sha256-v2nySZafnswY87um3ymbg7p9f766IQspC5oqaqZVX2c=" crossorigin="anonymous"></script>
}
Controller:
public class MainDoctorController:Controller
{
public IActionResult DeleteShift(int id)
{
var model = new Test()
{
Id = "bb"
};
return PartialView("/Views/Home/Index.cshtml", model);
}
}
public class HomeController : Controller
{
public async Task<IActionResult> Index()
{
var model = new Test()
{
Id = "aaa"
};
return View(model);
}
}
Result:

AppSetting Data is visiblae in Controller but does not pass to View

Fairly new to ASP.NET CORE so this could be a rookie mistake but it has be baffled!
I have been working on integrating a plugin for Square with some existing code, and when I write the data to console it's there but as soon as it's passed to the view I get a nullable error.
Controller
public IActionResult AccountPayments()
{
var appId = _config.GetValue<string>("AppSettings:ApplicationId");
var locId = _config.GetValue<string>("AppSettings:LocationId");
var env = _config.GetValue<string>("AppSettings:Environment");
ModelState.Clear();
var acc = new AccountPayment();
acc.ApplicationId = appId;
acc.LocationId = locId;
acc.PaymentFormUrl = env;
Console.WriteLine(acc.LocationId + " " + locId + " " + env);
return View(acc);
}
View
#page
#model AccountPayment
#section Scripts {
<!-- link to the SqPaymentForm library -->
<script type="text/javascript" src="#Model.PaymentFormUrl"></script>
<script type="text/javascript">
window.applicationId = "#Model.ApplicationId";
window.locationId = "#Model.LocationId";
</script>
<!-- link to the local SqPaymentForm initialization -->
<script type="text/javascript" src="~/js/sq-payment-form.js"></script>
}
Model
namespace WebInvoice.Pages
{
public class AccountPayment : PageModel
{
public string PaymentFormUrl { get; set; }
public string ApplicationId { get; set; }
public string LocationId { get; set; }
}
}
When I remove the #model from the view it works OK.
When I check the console it displays the information.
When I run the application the view above returns the below error.
"System.NullReferenceException: 'Object reference not set to an instance of an object.'"
Eternally grateful to anyone who can shed some light on the issue.
If you want to return View,don't add #page in your view,#page means it's a razor page rather than razor view.And also PageModel is used in razor page.You can refer to the official doc about razor page.Here is a demo about mvc:
Model:
public class AccountPayment
{
public string PaymentFormUrl { get; set; }
public string ApplicationId { get; set; }
public string LocationId { get; set; }
}
View(AccountPayment.cshtml):
#model AccountPayment
#section Scripts {
<!-- link to the SqPaymentForm library -->
<script type="text/javascript" src="#Model.PaymentFormUrl"></script>
<script type="text/javascript">
window.applicationId = "#Model.ApplicationId";
window.locationId = "#Model.LocationId";
</script>
<!-- link to the local SqPaymentForm initialization -->
<script type="text/javascript" src="~/js/sq-payment-form.js"></script>
}
Controller:
public IActionResult AccountPayments()
{
var appId = _config.GetValue<string>("AppSettings:ApplicationId");
var locId = _config.GetValue<string>("AppSettings:LocationId");
var env = _config.GetValue<string>("AppSettings:Environment");
ModelState.Clear();
var acc = new AccountPayment();
acc.ApplicationId = appId;
acc.LocationId = locId;
acc.PaymentFormUrl = env;
Console.WriteLine(acc.LocationId + " " + locId + " " + env);
return View(acc);
}
appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"AppSettings": {
"ApplicationId": "123",
"LocationId": "456",
"Environment": "Development"
}
}
result:

Serving dynamic XML file from .NET Core Web Application

In my .NET Core 2.2 website, I have a controller method within my BlogController that generates a sitemap.xml file:
public ActionResult SiteMap()
{
// logic here
return Content("<sitemap>...</sitemap>", "text/xml");
}
I have this route set up so that the sitemap will be output at https://mysite/sitemap
routes.MapRoute(
name: "sitemap",
template: "sitemap",
defaults: new { controller = "Blog", action = "SiteMap" });
That works, in that accessing /sitemap results in the XML content being served up.
However, when I access https://mysite/sitemap.xml, I get a 404 error.
I'm pretty sure this is something to do with static file handling, but I'm not sure how to set it up so that /sitemap.xml works.
You could try to dynamtically build xml like this
[Route("/sitemap.xml")]
public void SitemapXml()
{
string host = Request.Scheme + "://" + Request.Host;
Response.ContentType = "application/xml";
using (var xml = XmlWriter.Create(Response.Body, new XmlWriterSettings { Indent = true }))
{
xml.WriteStartDocument();
xml.WriteStartElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
xml.WriteStartElement("url");
xml.WriteElementString("loc", host);
xml.WriteElementString("changefreq", "daily");
xml.WriteElementString("lastmod", DateTime.Now.ToString("yyyy-MM-dd"));
xml.WriteEndElement();
var categories = _categoryService.GetAllCategories(inclTopMenu: true);
foreach (var c in categories)
BuildXml(xml, c.GetSeName(), host);
xml.WriteEndElement();
}
}
private void BuildXml(XmlWriter xml, string url, string host)
{
xml.WriteStartElement("url");
xml.WriteElementString("loc", host + "/" + url);
xml.WriteElementString("changefreq", "weekly");
xml.WriteElementString("lastmod", DateTime.Now.ToString("yyyy-MM-dd"));
xml.WriteEndElement();
}
or create a page like https://forums.asp.net/t/2160949.aspx?Create+Robots+txt+and+sitemap+xml+dynamically+in+asp+net+core
Here is a simple demo about how to generate xml file to server and show xml file by using url like https://mysite/sitemap.xml:
1.View:
<form asp-action="Create" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="file" id="file" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
2.Controller:
public class UsersController : Controller
{
private IHostingEnvironment _env;
public UsersController(IHostingEnvironment env)
{
_env = env;
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create(IFormFile file)
{
var fileName = System.IO.Path.GetFileName(file.FileName);
var filePath = System.IO.Path.Combine(_env.WebRootPath, fileName);
if (file.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
}
return View("Index");
}
}
3.Be sure to add app.UseStaticFiles(); like below,then you could access https://mysite/sitemap.xml:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
app.UseStaticFiles();
//...
}
4.Result:

Action is called twice

All, I encountered a problem which MVC action is called twice. Please help to review it.
The view code is simple.
<div class="divContainer">
<ul>
#foreach (var blobName in ViewBag.BlobList)
{
<li>#Html.ActionLink("Delete", "Delete", "LogBlob", new { blobUrl = blobName }, null)</li>
}
</ul>
</div>
public class LogBlobController : Controller
{
public ActionResult Delete(string blobUrl)
{
//...
//The action is call twice.
}
}
Since the LogBlobController belong to an MVC Area named Log. So the route config in the AreaRegistration looks like below.
public class LogAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Log";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Log_default",
"Log/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
And the default implement of RouteConfig of MVC is below.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Login", id = UrlParameter.Optional }
);
}
And the Html in the page looks like below.
Delete
I doubted the reason of twice is they(LogAreaRegistration and RouteConfig) both worked at the same time. thanks.

ASP.Net MVC 4 WebAPI POST returns 404

I've looked at the many similar issues posted but couldn't find a solution that worked for me. So the call to Get is working fine but call to POST returns 404. I created a simple WebAPI project (MVC 4).
public class CasesController : ApiController
{
[Inject]
public ICaseManager CaseManager { get; set; }
// GET api/cases
public IEnumerable<Case> Get()
{
return CaseManager.ListCases();
}
// POST api/cases
[HttpPost]
public void Post([FromBody]Case objCase)
{
}
}
So when I navigate to http://localhost:34645/api/cases I get the following:
[{"CaseID":1,"CaseCode":"one","CaseDescription":"case one"},{"CaseID":2,"CaseCode":"two","CaseDescription":"case two"}]
I created another project (ASP.Net) and have an html file within it with the following code:
<script src="Scripts/jquery-2.0.3.js"></script>
<script src="Scripts/jquery-2.0.3.intellisense.js"></script>
<script type="text/javascript">
function postData() {
$.post('http://localhost:34645/api/cases', { "CaseID": 3, "CaseCode": "three", "CaseDescription": "case three" }).done(function (data) { alert("Success " + data); }).fail(function (xhr, textStatus, errorThrown) { alert("Error " + xhr.status); });
}
</script>
Every time I click the button that invokes postData, I get an alert "Error 404".
Here are my routes:
Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
WebAPIConfig.Register:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//RA: to get JSON
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
}
RouteConfig:
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 }
);
}
}
Please advise.
Be careful about the order of the WebApi registration line. I found when I specifically had the Global.asax.cs code in this order it worked:
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Otherwise, it failed with 404 error.
If these are two separate solutions, check they're both running - it's possible that they're trying to share a server instance, so the WebAPI you're trying to hit isn't running when the other app is. If they're projects within the same solution, check that they're both set to run on startup, or again, the WebAPI won't be running when the ASP.NET project tries to access it.
Try below. It works for me. I have removed some properties for brevity.
public class CasesController : ApiController {
// GET api/cases
public IEnumerable<Case> Get() {
var caseManager = new CaseManager();
return caseManager.ListCases();
}
// POST api/cases
[HttpPost]
public string Post([FromBody]Case objCase) {
return objCase.CaseName;
}
}
public interface ICaseManager {
IEnumerable<Case> ListCases();
}
public class CaseManager {
public IEnumerable<Case> ListCases()
{
return new List<Case>() { new Case() { CaseID = 1, CaseName = "one" } };
}
}
public class Case {
public int CaseID { get; set; }
public string CaseName { get; set; }
}
View
<script type="text/javascript">
//function postData() {
// $.post('http://localhost:58820/api/cases', { "CaseID": 3, "CaseCode": "three", "CaseDescription": "case three" })
// .done(function (data) { alert("Success " + data); }).fail(function (xhr, textStatus, errorThrown)
// { alert("Error " + xhr.status); });
//}
$(document).ready(function () {
$('#save-source').click(function (e) {
e.preventDefault();
var source = {
'ID': 0,
'CaseID': 3,
'CaseName': "three",
};
$.ajax({
type: "POST",
dataType: "json",
url: "/api/cases",
data: source,
success: function (data) {
alert(data);
},
error: function (error) {
jsonValue = jQuery.parseJSON(error.responseText);
}
});
});
});
</script>
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm"}))
{
<input type="submit" id="save-source" name="save-source" value="Add" />
}
After different attempts, this article helped me the most:
WebAPI and CORS enabled REST services
I also installed the Ninject WebApi DependencyResolver package through NuGet.
You write that you post to $.post('http://localhost:34645/api/cases'...
Either you change the url to include the action method name explicitly, like: $.post('http://localhost:34645/api/cases/post'..
or you add in your config.Routes.MapHttpRoute a default action which will be used when none action specified in the url
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { action="Post", id = RouteParameter.Optional }
);
OR you can change your route to
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
);
(without {action} and then web api will reach the Post method when you use a post http verb (it knows to do it automatically, but if you set a default action it'll override it)