Generic action result with Bind - asp.net-mvc-3

Is it possible to have a ActionResult with a signature of:
[HttpPost]
public ActionResult SomeAction<T>([Bind(Prefix = typeof(T).Name)] T data)
{
MapAndUpdateModel<T>(data);
return Content(Boolean.TrueString);
}
I can't seem to use typeof(T).Name ?
Regards.

Attribute arguments must be types or compile-time constants. You can't call a method (the Name property getter) to supply a value to an attribute.
Unfortunately, BindAttribute is consumed by the MVC innards in long-ish hard-coded call chain without a trivial extension hook. If you want to add a similar attribute that would allow inference of the prefix, this is possible, but you would pretty much need to replace the ControllerActionInvoker merely in order to change the parameter binding behaviour.

Related

mocking a method with parameter as LIST type

I want to mock the below mentioned method.
public class MockClass {
public boolean ToBeMocked(Cinput, Coutput, List<CIOChain<Cinput, Coutput>>)
}
What should be in place of ?? in below mentioned code ?
Easymock.expect(MockClassObject.ToBeMocked(Cinput.class, Coutput.class, ??)).andReturn(true);
At the Class level, all List interfaces are the same regardless of the generic type, due to type erasure; they are only different at compile time.
So it's just List.class in place of ??.
That is,
Easymock.expect(MockClassObject.ToBeMocked(Cinput.class, Coutput.class, List.class)).
andReturn(true);
In the scope of mocking, you should really be specifying the objects that you expect to be passed to that method, like:
Easymock.expect(MockClassObject.ToBeMocked(cInputObj, cOutputObj, listObj)).
andReturn(true);
If for some reason you can't do that, you can use isA/anyObject variants:
Easymock.expect(MockClassObject.ToBeMocked(isA(Cinput.class), isA(Coutput.class), isA(List.class))).
andReturn(true);

In Spring MVC 3, how do I bind an object to a query string when the query string parameters don't match up with the object fields?

A 3rd party is sending me part of the data to fill in my domain object via a query string. I need to partially fill in my domain object, and then have the user fill in the rest via a form. I don't have any control over the query string parameters coming in, so I can't change those, but I'd really like to be able to use Spring MVC's data binding abilities, rather than doing it by hand.
How can I do this?
To add some complication to this, some of the parameters will require extensive processing because they map to other objects (such as mapping to a user from just a name) that may not even exist yet and will need to be created. This aspect, I assume, can be handled using property editors. If I run into trouble with this, I will ask another question.
Once I have a partially filled domain object, passing it on to the edit view, etc. is no problem, but I don't know how to properly deal with the initial domain object population.
The only thing I have been able to come up with so far is to have an extra class that has it's properties named to match the inbound query parameters and a function to convert from this intermediary class to my domain class.
This seems like a lot of overhead though just to map between variable names.
Can you not just have the getter named differently from the setter, or have 2 getters and 2 setters if necessary?
private int spn;
// Standard getter/setter
public int getSpn() {
return spn;
}
public void setSpn(int spn) {
this.spn = spn;
}
// More descriptively named getter/setter
public int getShortParameterName() {
return spn;
}
public void setShortParameterName(int spn) {
this.spn = spn;
}
Maybe that is not standard bean convention, but surely would work?

MVC - Passing a Type as an action parameter

Can I pass a parameter of Type to the Action method in MVC via a HTML.ActionLink().
e.g.
public ActionResult Get(Type containerType, string name)
{
throw new NotImplementedException("vkag");
}
<%=Html.ActionLink(flow.Source.Name, "Get", new { containerType = typeof(Worksheet), name = flow.Source.Name})%>
For some reason the type is always null. I also can't pass back a base type to allow for subtypes to be passed in it's place.
I don't know whether this is a limitation of the HTML ActionLink Helper or MVC.
I can't pass an Interface, I specify a base type parameter and use sub type as an argument in the place of a base type parameter, and I can't seem to pass a Type back. I'm pretty stuck here.
Is there another HTML Helper that will help?
Can I do anything with model binding?
Can I modify the state of my model during an ActionLink invocation before control is passed to my action method?
Kind a stuck here. Any help would be gratefully appreciated.
Thanks
The types you can pass into Routes must be passable via a URL if you think about it.
You cannot pass a Type as it would have to be serialised. Why not pass the containerType as a string and convert it back to a Type in the action?

Teach ASP.NET MVC to treat key-less query values as boolean flags

If a query value in URL doesn't have a key, e.g.: http://site.com?update
and an action has bool argument named update.
I want that update argument to received value true if 'update' value is present in the URL, and false otherwise.
Example:
Action: public ActionResult MyAction(string name, bool update) {...}
URL: http://site.com/path?name=Bob&update
Expected action call: controller.MyAction("Bob", true);
if URL is http://site.com/path?name=Bob (notice no update)
then expected call is controller.MyAction("Bob", false);
It is not a big deal, I do know I can just get Request.Query and find values with key=null, but I want to have it done through the framework.
Where do I begin?
I'm using ASP.NET MVC 3
Doing this through the framework would probably require you to implement your own value provider with a corresponding value provider factory and add the factory to ValueProviderFactories. You would probably implement it similar to the existing QueryStringValueProviderFactory and QueryStringValueProvider but then add your own implementation of GetValue that includes the additional logic you wanted to return true/false based on if there is a value provided for the query string key. Here is a link on adding a value provider, and check out the QueryStringValueProvider in the framework.
http://mgolchin.net/posts/19/dive-deep-into-mvc-ivalueprovider

Need to allow an action method string parameter to have markup bound to it

I have an action method that takes in a string as its only parameter. The action method transforms it, and returns the result back to the client (this is done on an ajax call). I need to allow markup in the string value. In the past, I've done this by decorating the property on my model with [AllowHtml], but that attribute cannot be used on a parameter and the AllowHtmlAttribute class is sealed, so I cannot inherit from it. I currently have a work around where I've created a model with just one property and decorated it with the aforementioned attribute, and this is working.
I don't think I should have to jump through that hoop. Is there something I'm missing, or should I make a request to the MVC team to allow this attribute to be used on method parameters?
If you need to allow html input for a particular parameter (opposed to "model property") there's no built-in way to do that because [AllowHtml] only works with models. But you can easily achieve this using a custom model binder:
public ActionResult AddBlogPost(int id, [ModelBinder(typeof(AllowHtmlBinder))] string html)
{
//...
}
The AllowHtmlBinder code:
public class AllowHtmlBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var name = bindingContext.ModelName;
return request.Unvalidated[name]; //magic happens here
}
}
Find the complete source code and the explanation in my blog post: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/
Have you looked at ValidateInputAttribute? More info here: http://blogs.msdn.com/b/marcinon/archive/2010/11/09/mvc3-granular-request-validation-update.aspx.

Resources