I am trying to pass dynamic parameters from jquery to mvc controller. This is my jquery function
function OpenBrowserUrl(type, params)
{
window.open("{0}?linkType={1}&{2}".format(URL.openBrowserLinkURL, type, $.param(params)), '_blank');
}
params would be different things based on who passes it in. For example, it's an object like this: var param = { P1: "Test1", P2: "Test2" }
I am trying to bind those in MVC Controller. This is what it looks like right now:
public virtual RedirectResult OpenBrowserLink(object urlParameters)
{
IDictionary<string, object> paramsPair = new RouteValueDictionary(urlParameters);
foreach (var item in paramsPair)
{
System.Diagnostics.Debug.WriteLine(item.Key);
}
}
However, it's not binding properly. the values are empty. On fiddler, this is how it's sending data: http://www.url.com?param1=1¶m2=2¶m3=3
Any idea what's going on? or Is there a better way to handle this? Basically I am trying to mimic the way Html Helpers send parameters and bind it from the controller side using JQuery. HtmlHelper example: Html.TextboxFor(m => m.Text, new { Param1=1, Param2=2, Param3=3 });
Thanks a lot for the help
Model binder won't work because your object urlParameters has no properties. You should either create strongly typed model:
public class UrlParamerters
{
public string Param1 {get; set;}
public string Param2 {get; set;}
public string Param3 {get; set;}
}
or change your action signature:
public virtual RedirectResult OpenBrowserLink(string[] params)
and just pass an array or parameters.
Related
I want to do this:
public ActionResult SaveStuff(dynamic vm) {
StoreTheValue(vm.myvalue);
return Content("Saved :)");
}
This doesn't work, MVC doesn't seem to want to create a dynamic object with properties that correspond to the post data of the request.
Now I know that the whole point of properly defined view models is to create strongly typed data structures and have MVC bind data into them, but given that I'm posting data from javascript using ajax it's not strongly typed data anyway, so I don't see that I'm loosing any maintainability by doing this, and it will save me time and effort creating view model classes.
Can anyone help suggest how I can bind post data to a dynamic object, posssibly using a custom model binder?
One possible way to achieve this would be to use a custom model binder, assuming that you are posting Json to the action
public class DynamicBinder : IModelBinder
{
public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext )
{
using( var streamReader = new StreamReader( controllerContext.HttpContext.Request.InputStream ) )
{
return JsonConvert.DeserializeObject< dynamic >( streamReader.ReadToEnd() );
}
}
}
then in your action you can tell it, to use the custom binder
public ActionResult SaveStuff([ModelBinder(typeof(DynamicBinder))]dynamic vm) {
StoreTheValue(vm.myvalue);
return Content("Saved :)");
}
then post your json as such :
{
"myvalue":{...}
}
dynamic type and ajax request that you do with javascript is not corresponding.
You always can create your strongly typed object properties on javascript side.
Anyway you can use FormCollection like this:
[HttpPost]
public ActionResult yourAction(FormCollection collection)
{
StoreTheValue(Convert.ToString(collection["myvalue"]));
return Content("Saved :)");
}
But I think it's better to think of a strongly typed way.
I'm trying pass a html code trough Ajax like this:
Using plugin 'summernote' (WYSIWYG Editor)
var description = $('#ticketDescription').code();
This give me for example:
<span style="font-weight: bold;">asdasdasd<span>sadasd
and when Ajax process this give an 500 internal error
$.ajax({
url: '/Ticket/NewTicket',
type: 'POST',
data: {
companyId: companyId,
subject: subject,
ticketDescription: description
},
success: function(result) {
....
},
error: function(result) {
}
});
The problem is solved by removing the '<' character from string.
Any solution to this?
Thanks
Edit: The only way I found so far is:
In javascript:
description = escape(description);
and in the controller:
ticketDescription = HttpUtility.UrlDecode(ticketDescription);
Is it correct?
ValidateInput and AllowHtml attribute is what you need to set in the property
By default Asp.Net MVC doesn't allow a user to submit html for avoiding Cross Site Scripting attack to your application.
ValidateInput Attribute
This is the simple way to allow the submission of HTML. This attribute can enable or disable input validation at the controller level or at any action method.
ValidateInput at Controller Level
[ValidateInput(false)]
public class HomeController : Controller
{
public ActionResult AddArticle()
{
return View();
}
[HttpPost]
public ActionResult AddArticle(BlogModel blog)
{
if (ModelState.IsValid)
{
}
return View();
}
}
Now, the user can submit Html for this Controller successfully.
ValidateInput at Action Method Level
public class HomeController : Controller
{
public ActionResult AddArticle()
{
return View();
}
[ValidateInput(false)]
[HttpPost]
public ActionResult AddArticle(BlogModel blog)
{
if (ModelState.IsValid)
{
}
return View();
}
}
Now, the user can submit Html for this action method successfully.
Limitation of ValidateInput attribute
This attribute also has the issue since this allow the Html input for all the properties and that is unsafe. Since you have enable Html input for only one-two properties then how to do this. To allow Html input for a single property, you should use AllowHtml attribute.
AllowHtml Attribute
This is the best way to allow the submission of HTML for a particular property. This attribute will be added to the property of a model to bypass input validation for that property only. This explicit declaration is more secure than the ValidateInput attribute.
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public class BlogModel
{
[Required]
[Display(Name = "Title")]
public string Title { get; set; }
[AllowHtml]
[Required]
[Display(Name = "Description")]
public string Description{ get; set; }
}
Make sure, you have removed the ValidateInput attribute from Conroller or Action method. Now, the user can submit Html only for the Description property successfully.
So I do this post:
$http.post(Common.blog.save, { blog: blog })
.then(saveBlogComplete)
.catch(function(message) {
});
And I get this in fiddler output:
{"blog":{"title":"Chicken Is Good","content":"#Chicken Is Good\n##Contents\n* Introduction\n* Factfile\n* Analysis\n* Evaluation\n* Conclusion\n###Introduction\n\n###Factfile","dateAuthored":"","userId":""}}
In my action:
[HttpPost]
public JsonResult Save(string blog)
{
var desBlog = JsonConvert.DeserializeObject<BlogDto>(blog);
return this.ExecuteService(() => this.blogService.Save(desBlog));
}
string blog is coming back null.... I'm not sure why this is happening?
I have done the following
Put breakpoint in JavaScript - data is getting populated
Reviewed Fiddler output - the data is the same as JavaScript obj
Put breakpoint in the Action - it's getting called, the HttpContext doesn't have any data about the POST data in it
Your code will work without stringify function, if you change your mvc action parameter from String to Blog:
public class Blog
{
public string Title {get; set;}
public string Content {get; set;}
public DateTime DateAuthored {get; set;}
public long UserId {get; set;}
}
[HttpPost]
public JsonResult Save(Blog blog)
{
This happening because your blog model on server-side doesn't match to the structure of passing parameter from angular.
I just needed to stringify the data!
$http.post(Common.blog.save, { blog: JSON.stringify(blog) })
.then(saveBlogComplete)
.catch(function(message) {
});
I am using a userControl in MVC 4 that has a telerik radeditor.
I want to submit the content of the radeditor the the action method but if I user editor.get_html() the code doesn't execute.
the javascript call to the action method is the following:
function Save() {
var editor = $find("<%=radEdit.ClientID%>");
var editorHtmlContent = editor.get_html();
var entityId = document.getElementById('hdEntityId').value;
var url = '<%=Url.Action("SaveNote", "staticController")%>';
$.post(url, { EntityId: entityId, Desc: editorHtmlContent }, function (result) { });
}
any clue?
Posting HTML tags is being considered a security threat (HTML Injection and Cross-site Scripting (XSS)), so it is blocked by default. You have three ways out of this:
Encode your HTML on client side before sending to the server. You can find a lot of reading about that on SO, for example here: Fastest method to escape HTML tags as HTML entities?
If you have strongly typed model class and want to get the actual HTML, you can use AllowHtmlAttribute:
public class XMLModel
{
public int EntityId { get; set; }
[AllowHtml]
public string Desc { get; set; }
}
Last option is to disable input validation for entire action, which can be done with ValidateInputAttribute:
[ValidateInput(false)]
[HttpPost]
public ActionResult SaveNote(...)
{
...
}
You should choose the option most suitable for you.
In my spring mvc project i have a properties.property file whose structure is as such
TestOrderURL=blah
LiveOrderURL=blah1
These values are used in my controller and are read using the #Value annotation.
The view [.jsp] has a javascript function which has variables that need to have their default value set from the above properties file. Is there a way to set this?
My HomeController.java
#RequestMapping(value = "/Home.html", method = RequestMethod.GET)
public String home(Locale locale, Model model)
{
logger.info("Welcome home! the client locale is "+ locale.toString());
return "Home";
}
Set your variables from controller to some specific scope i.e HttpSession so that you could access them in your javascript via Expression Language or Scriptlet.
UPDATE:
In your controller call:
request.getSession(false).setAttribute("YourProperty",propertyvalue);
then in javascript access them like:
var property=<%=session.getAttribute("YourProperty")%>;
UPDATE:
Change your controller method to this:
#RequestMapping(value = "/Home.html", method = RequestMethod.GET)
public String home(Locale locale, Model model,HttpServletRequest request)
{
request.getSession(false).setAttribute("YourProperty",propertyvalue);
logger.info("Welcome home! the client locale is "+ locale.toString());
return "Home";
}
or you could set in Your model also.