I am trying to create simple page where I am sending some data to the server using $http.put.
Script code
<script>
var myApp = angular.module("myApp", []);
myApp.controller("HttpPostController", function ($scope, $http) {
$scope.SendHttpPostData = function () {
var data = $.param({
firstName: $scope.firstName,
lastName: $scope.lastName,
age : $scope.age
});
$http.put('/ServerRequest/PutDataResponse', data)
.success(function (data, status, headers, config) {
$scope.ServerResponse = data;
})
.error(function (data, status, header, config) {
$scope.ServerResponse = htmlDecode("Data: " + data +
"\n\n\n\nstatus: " + status +
"\n\n\n\nheaders: " + header +
"\n\n\n\nconfig: " + config);
});
};
});</script>
My HTML code
<div ng-app="myApp" ng-controller="HttpPostController">
<form ng-submit="SendHttpPostData()">
<p>First Name: <input type="text" name="firstName" ng-model="firstName" required /></p>
<p>Last Name: <input type="text" name="lastName" ng-model="lastName" required /></p>
<p>Age : <input type="number" name="age" ng-model="age" required /></p>
<input type="submit" value="Submit" />
<hr />
{{ ServerResponse }}
</form></div>
ASP.NET MVC controller action method
[HttpPut]
public ContentResult PutDataResponse(string firstName, string lastName, int age)
{
return Content("First name: " + firstName +
" | Last name: " + lastName +
" | Age: " + age +
" | Request Type: " + Request.RequestType.ToString());
}
The error message I get is following
TTP Error 404.0 - Not Found The resource you are looking for has been removed, had its name changed, or is temporarily unavailable. Most likely causes: The directory or file specified does not exist on the Web server. The URL contains a typographical error. A custom filter or module, such as URLScan, restricts access to the file. Things you can try: Create the content on the Web server. Review the browser URL. Check the failed request tracing log and see which module is calling SetStatus.
So in ASP.NET MVC it doesn't work. (POST and GET works). I tried the above with ASP.NET MVC Web API and it works fine. I am able to send and receive response using PUT method of mvc web api.
The question is why it doesn't work in ASP.NET MVC even if the method verb is [HttpPut].
Thanks
Okay, after much effort I found the solution. Actually, the problem was that by default ASP.NET MVC doesn't allow "PUT" or "DELETE" request type so we need to enable them in the web.config file like below.
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="FormsAuthenticationModule" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Notice the ExtensionlessUrlHandler-Integrated-4.0 handler. This makes the difference. This is allowing all types of verb acceptable and so even PUT request now works with ASP.NET MVC.
I suspect the model binding works differently. You are passing in :
var data = $.param({
firstName: $scope.firstName,
lastName: $scope.lastName,
age : $scope.age
});
An object with 3 properties. Yet your MVC controller method is looking for 3 parameters only: string firstName, string lastName, int age
You could change your MSC controller method to expect an object with 3 properties i.e:
public class myViewModel
{
string firstName;
string lastName;
int age;
}
public ContentResult PutDataResponse(myViewModel formData)
or
Change the request to pass the parameters in the URL:
$http.get('/ServerRequest/PutDataResponse?firstname=bob&lastname=smith&age=12')
Also, check your route : '/ServerRequest/PutDataResponse' . If you are using default routing, This will map to Your /ServerRequestController and the first HttpPut method. From your example I don't know if you have more than one HttpPut method on your controller. If you do, you could add an attribute route [Route("ServerRequest/PutDataResponse")] to the top of your MVC method.
Related
I am trying to upload an mp4 video file that is 5.25 MB in size in an ASP.NET MVC 5 application.
I have tried adding this to the Web.config file which has been the accepted answer in most cases to this problem.
<system.web>
<!-- This will handle requests up to 1024MB (1GB) -->
<httpRuntime maxRequestLength="1048576" />
</system.web>
I've also tried setting the timeout as well in the Web.config
<httpRuntime maxRequestLength="1048576" executionTimeout="3600" />
However, when I go to upload the file I am getting System.Web.HttpException (0x80004005): Maximum request length exceeded.
Maybe there is something that needs to be set in the controller or view?
Controller:
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
if (fileName != null)
{
var path = Path.Combine(Server.MapPath("~/Content/Videos"), fileName);
file.SaveAs(path);
}
}
return RedirectToAction("Index");
}
View:
#using (Html.BeginForm("Edit", "Posts", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
How do you upload video files in ASP.NET MVC 5?
Try add this in web.config (in bytes !):
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
I’m stuck in a reference book by Steven Sanderson/Adum Freeman Pro ASP .Net MVC 3. I’ve made it up to page 185 where a HTML helper is to be used to return the numberer of pages in links. I found help on this site addressing my issue with this reference book, and walked through every step still having the same issues (link) MVC extension method error
When I run the code in a browser I get this error:
Compiler Error Message: CS1973: 'System.Web.Mvc.HtmlHelper'
has no applicable method named 'PageLinks' but appears to have an
extension method by that name. Extension methods cannot be dynamically
dispatched. Consider casting the dynamic arguments or calling the
extension method without the extension method syntax
The code builds fine but if I open any other class to edit this line of code to my helper method gets the same error as above.
#Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
Helper Class:
namespace SportsStore.WebUI.HtmlHelpers
{
public static class PagingHelpers
{
public static MvcHtmlString PageLinks(this HtmlHelper html,
PagingInfo pagingInfo,
Func<int, string> pageURL)
{
StringBuilder results = new StringBuilder();
for (int i = 1; i <= pagingInfo.TotalPages; i++)
{
TagBuilder tag = new TagBuilder("a");
tag.MergeAttribute("href", pageURL(i));
tag.InnerHtml = i.ToString();
if (i == pagingInfo.CurrentPage)
tag.AddCssClass("selected");
results.Append(tag.ToString());
}
return MvcHtmlString.Create(results.ToString());
}
}
}
My View:
#{
ViewBag.Title = "Products";
}
#foreach (var p in Model.Products) {
<div class="item">
<h3>#p.Name</h3>
#p.Description
<h4>#p.Price.ToString("c")</h4>
</div>
}
<div class="pager">
#Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
</div>
Web.config
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="SportsStore.WebUI.HtmlHelpers"/>
</namespaces>
</pages>
</system.web.webPages.razor>
You are passing a dynamic value to an extension method. (Hover over Model.PagingInfo and intellisense should tell you that the type is dynamic. This means it does not know what the type is until runtime) So, try changing your code so that it casts the dynamic type like this:
#Html.PageLinks((PagingInfo)Model.PagingInfo, x => Url.Action("List", new {page = x}))
You could fix this in two other ways:
As the error suggests, do not call it using the extension method:
PageLinks(Html, Model.PagingInfo, x => Url.Action("List", new {page = x}))
OR you could make the view know what the model is going to be so that it does not use a dynamic, by setting this at the top of your view
#model PagingInfo
Add #using project_name.HtmlHelpers
e.g.
#using ChristianSchool.HtmlHelpers
#Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))
you must add this lines in web.cofig under Views Folder not main one
<add namespace="YourProjectName.HtmlHelpers"/>
I tried to create this HtmlHelper method:
namespace Power.WebUx.Helpers
{
public static class HtmlHelperExtensions
{
public static MvcHtmlString SelectedIfMatch(this HtmlHelper helper, string actual, string expected)
{
if (expected == actual)
{
return new MvcHtmlString("<option selected=\"selected\" value=\"" + actual + "\"" + actual + "</option>");
}
else
{
return new MvcHtmlString("<option value=\"" + actual + "\"" + actual + "</option>");
}
}
I added the Power.WebUx.Helpers line to my web.config:
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
<add namespace="Power.WebUx.Helpers" />
</namespaces>
</pages>
However when I try to use the extension I get an error message saying that System.Web.Mvc.HtmlHelper does not contain a definition for SelectedIfMatch
Does the code I am trying to run look right or am I missing something?
Hope someone can see something obvious.
thanks
Jon Wylie
Import the namespace into your view to use any extension methods in that namespace
<%# Import Namespace =
"Power.WebUx.Helpers" %>
Make sure you're modifying the top level web.config file(instead of the one in the views folder), then close and open the files where you're trying to use the helper
I have these routes defined:
routes.MapRoute("CategoryList_CountryLanguage", "Categories/{id}/{urlCategoryName}/{country}/{language}",
new {
controller = "Categories",
action = "Details",
});
routes.MapRoute("CategoryList", "Categories/{id}/{urlCategoryName}",
new {
controller = "Categories",
action = "Details",
country = "US",
language = "EN"
});
and I'm generating links using:
#Html.ActionLink("desc", "Details", "Categories", new { id = item.Id, urlCategoryName = item.UrlFriendlyName}, null)
and the generated urls are in the form:
/Categories/id/friendly-name
I want to generate:
/Categories/id/friendly-name/US/EN
without having to specify the country and language in the ActionLink call, can't I use defaults like that?
The easy workaround is to specify those parameters in the ActionLink calls, but I would like to avoid that if possible. My hope is that the first route expects the values specified in the url, while the second has the defaults when not included in the url and would use that to create new urls, no luck so far, is this possible?
You can create a helper class called UrlHelpers.cs that looks like this:
public static class URLHelpers {
public static string CategoryList(this UrlHelper helper, int id, string urlFirendlyName) {
return CategoryList(helper, id, urlFirendlyName, "US", "EN");
}
public static string CategoryList(this UrlHelper helper, int id, string urlFirendlyName, string country, string language)
{
return helper.Action("Details", "Categories", new { id, urlCategoryName = urlFriendlyName, country, language });
}
}
Then in your view you would call it like this:
Some Text
Just a note: You will want to add the namespace of your helper to your web.config in the pages > namespaces section. So if you add a Helpers folder to the root of your MVC app and place the UrlHelper.cs class in it you would add:
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
<add namespace="MyProject.Helpers"/>
</namespaces>
</pages>
I am trying to get remote validation working in ASP.NET MVC 3 but for some reason the validation never gets fired. I am returning json from the controller and in FireFox it ask me to download the files. Not sure what is going on here. Here is my code:
#using(Html.BeginForm(new {Action = "ValidateUserName"})) {
<text> Enter UserName: </text> #Html.TextBoxFor(x => x.UserName)
<input type="submit" value="Login" />
}
Here is the RegistrationViewModel:
public class RegistrationViewModel
{
[Required(ErrorMessage = "UserName is required!")]
[Remote("ValidateUserName","Home",ErrorMessage ="UserName already taken!")]
public string UserName { get; set; }
}
And here is the HomeController:
public ActionResult ValidateUserName(RegistrationViewModel registrationViewModel)
{
return Json(!registrationViewModel.UserName.Equals("test"),JsonRequestBehavior.AllowGet);
}
A couple of things to consider:
1) In your view, you should be referencing the jquery validation and unobtrusive javascript libraries:
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
2) Also in your view, you should have an Html.ValidationMessageFor(m => m.Attribute):
#Html.ValidationMessageFor(x => x.UserName)
3) Lastly, make sure you have the two AppSettings in your web.config file that enable the client-side validation.
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>