Custom Binding Required for SpringMVC Form Field - spring-mvc

I ran into the following SpringMVC issue: there is a domain object which uses a certain Address sub-object, but the getters/setters have to be tweaked to use a different Address object via conversion. This is an architectural requirement.
public class DomainObj {
protected DomainObj.Address address;
public anotherpackage.new.Address getAddress()
{
return convertFrom(address);
}
public void setAddress (anotherpackage.new.Address value)
{
this.address = convertTo(value);
}
}
// Internal Address object, old, #1
public static class Address {
protected String street1;
protected String street2;
// etc., getters/setters
}
Now, in the JSP, I bind an Input Text Field to the new Address object (the result of conversions) that's what we have to deal with. In this new 2nd Address object (anotherpackage.new.Address), there is a field e.g. "addressLine1", which is different from the old object's "Street1":
<form:input path="topObject.address.addressLine1" />
My problem is that the setter, setAddress(), never gets called in this case for binding (verified in the Debugger). Any solutions to this?

Your options are:
a) do not bind directly to the business object
b) configure a binder to do the conversion to your domain object
Discussion:
Usually in enterprise class software we don't want to bind directly to the business objects -- which are usually entities (in the context of jpa). This is because session handling is a bee-otch. Usually we code against DTOs, and when one is received from the front-end we read the appropriate object from the repository (ORM) layer, update it, and save it back again (I've only described updates because they're the hardest, but a similar model works for everything).
However, spring mvc binders offer a way of binding anything to anything. They're a bit complicated and it'll take too long to explain here, but the docs are in the spring documentation and you want to be looing at converters and a conversion service. There are SO Q/A's on this topic, for example...

Related

How can I access the request HttpSession from Scout client side code?

For example, from Scout Form execStore() method, right before executing any server services, i like to get the HttpSession and eventually get custom data from its attributes store.
As mentioned in the comments, Eclipse Scout separates the UI Layer (the HTML rendering - or the Swing client in older versions) from the client model. And while the UI Layer knows about the HttpSession, the client model, in which your form lives, does not.
You can however put the relevant attributes on the ServerSession (backend) and synchronize them to the ClientSession (model) or vice versa - depending on where your attributes come from.
This sketch should get you started:
In your Client/ServerSession class (extends AbstractServerSession) add a getter and setter.
If - and only if - you need to synchronize the values to the client implement the getter / setter like this (example for an Integer property):
public Integer getMyProperty() {
return getSharedContextVariable("myProperty", Integer.class);
}
public void setMyProperty(Integer newValue) {
setSharedContextVariable("myProperty", Integer.class, newValue);
}
You'll need to teach the application to transfer the data to your Client or ServerSession.
If your data comes from the backend side (e.g. from database): Your best guess is to override the default implementation of org.eclipse.scout.rt.server.context.HttpServerRunContextProducer.
Create a subclass of this class in your .server-part, and add the #Replace annotation. Your best place to implement it is likely in the method public IServerSession getOrCreateScoutSession(HttpServletRequest req, ServerRunContext serverRunContextForSessionStart, String scoutSessionId)
If your data comes from the UI side (e.g. passed by SAML):
This is more complicated and I have only hints where to start looking: org.eclipse.scout.rt.ui.html.UiSession.createAndStartClientSession(Locale, UserAgent, Map<String, String>) on how the ClientSession is created and if you can access your data at this location.

Where should Stored Proc business logic be placed in MVC?

I'm looking for a bit of experience and explanation here, given that different sources give different recommendations. I am totally new to MVC. I know this question has been asked before, but I am not (currently) using EF or Linq.
I have a SQL database with many stored procedures. Previously when used with webforms, there was a business layer that contained helper methods for calling the procedures and returning DataSets to the pages. The important part is that the procedures often interrogated about 20 tables; the pages do not simply reflect the database structure exactly (as I see in the majority of MVC tutorials):
SQL database <--> stored procedures <--> business layer <--> web forms
I want to take the best approach here to start on the right footing and learn properly but appreciate there may not be a correct answer. Therefore if you post, could you please offer some explanation as to "why"?
Should stored procedure logic (SQLCommand/business methods etc) go within Model or
Controller?
One post advises neither, but retain the business layer. Another expert advises that
[Models/Entities] should not have any addon methods outside of what's
coming back from the database
If the business layer is retained, where are the methods called from (e.g. Model or Controller)?
If the above answer is "Neither", does that mean the Model part will go unused?
That almost feels that things aren't being done properly, however in this tutorial that appears to be what happens.
Should I plug in the Entity Framework into the Model layer to call the business layer?
That feels like overkill, adding all that additional logic.
Your controllers should gather the information required to build the page the user is currently viewing. That's it.
Controllers should reference classes in your business logic layer.
For example here's your controller. All it does is translate the http request and call the business logic.
public class MyController : Controller
{
private IMyBusinessLogic _businessLogic;
public MyController(IMyBusinessLogic businessLogic)
{
_businessLogic = businessLogic;
}
[HttpPost]
public ActionResult UpdateAllRecords()
{
_businessLogic.UpdateAllRecords();
return Json(new Success());
}
}
And your business logic class
public class MyBusinessLogic : IMyBusinessLogic
{
public void UpdateAllRecords()
{
// call SP here
using(SqlConnection conn = new...
}
}
There are a number of advantages to this:
Your business logic is completely separated from your UI, there's no database code in your presentation layer. This means your controller can focus on it's job and code doesn't get polluted.
You can test your controller and see what happens when your business logic succeeds, throws exceptions etc.
For extra bonus points you should look into creating a data access layer.
public void DataAccess : IDataAccess
{
public void RunStoredProcedure(string spName)
{
}
}
Now you can test that your BLL is calling and processing your SP results correctly!
Expanded following the comment questioning the models:
Ideally your model should have no logic in it at all. It should simply represent the data required to build the page. Your object which you're loading represents the entity in the system, the model represents the data which is displayed on the page. This is often substantially lighter and may contain extra information (such as their address) which aren't present on the main entity but are displayed on the page.
For example
public class Person
{
public int PersonID {get;set;}
public string Firstname {get;set;}
public string Lastname {get;set;}
public Address Address {get;set;}
}
The model only contains the information you want to display:
public class PersonSummaryModel
{
public int PersonID {get;set;}
public string FullName {get;set;}
}
You then pass your model to your view to display it (perhaps in a list of FullNames in this case). Lots of people us a mapper class to convert between these two, some do it in the controller.
For example
public class PersonMapper
{
public PersonSummaryModel Map(Person person)
{
return new PersonSummaryModel
{
PersonID = person.PersonID,
FullName = string.Concat(person.Firstname, " ", person.Lastname)
};
}
}
You can also use some automatic solutions such at AutoMapper to do this step for you.
Your controller should really only be involved with orchestrating view construction. Create a separate class library, called "Data Access Layer" or something less generic, and create a class that handles calling your stored procs, creating objects from the results, etc. There are many opinions on how this should be handled, but perhaps the most
View
|
Controller
|
Business Logic
|
Data Access Layer
|--- SQL (Stored procs)
-Tables
-Views
-etc.
|--- Alternate data sources
-Web services
-Text/XML files
-and son on.
if you feel like learning tiers and best way
MSDN have great article on this link
MSDN

asp.net MVC 4 with Data Access Layer using Entity Framework 5?

In my project, i have first created my Data Access Layer using Entity Framework with the following projects in a single solution,
1.Domain Model - Entity Model (.edmx)
2.Services - Business Services, Dtos, Infrastructure(Configurator), Interfaces and Models(Repository)
Now the problem is, i want to connect this data access layer to my MVC project, i do not know how to make the data access layer projects to behave as the models for my mvc project. So can anyone tell me how to connect my data access layer into my controllers and views.. any references is appreciated. Thanks in Advance !
I think what you're asking is what's the best way for controllers to interact with your services and data layer?
One option is to use the mediator pattern, and decouple the services from the controllers.
There's a great implementation for ASP.NET MVC apps: ShortBus, also available on nuget that I've used in a number of projects, and so far it's worked great.
One of the nice things about ShortBus is it's support for dependency injection. In the example below, all the services are created with Ninject, and require the appropriate registration.
The basic idea is you define queries and commands that the controllers will use, and then add handlers to perform the actual work.
public class AddUser : ICommand<User>
{
public string Email { get; set; }
}
and then a handler:
public class AddUserHandler : ICommandHandler<AddUser, User>
{
private IDatabaseService _database;
private IEmailService _email;
public AddUserHandler(IDatabaseService database, IEmailService email)
{
_database = database;
_email = email;
}
public User Handle(AddUser command)
{
bool created = _database.CreateUser(command.Email);
if (created)
{
_email.SendWelcome(command.Email);
}
}
}
Then inside your controller, all you'd do is issue the command:
public class UsersController : Controller
{
private IMediator _mediator;
public UsersController(IMediator mediator)
{
_mediator = mediator;
}
public ActionResult Create(string email)
{
User user = _mediator.Send(new AddUser("foo#bar.com"));
}
}
The things I like about this pattern are:
Controllers don't need to know how to create a user. It issues a command, and the appropriate business logic handles it.
Each handler can require the services it needs. There's no need to pollute the controllers with services only used by a single action.
It's really easy to unit test. I use a mock, and only need to verify that _mediator.Send() was called with the correct parameters. Then to test the handler, I mock IDatabaseService and IEmailService and verify they are called correctly in the 2 cases.
Commands and queries can be reused, and again, the caller never needs to know what's required to handle the request.
As for the Views, I'd recommend ViewModels.
Each View gets it's own ViewModel, which holds whatever is required for showing that particular page. You'd then map your domain objects to their own individual ViewModels, possibly with AutoMapper.
What's nice about ViewModels is you can format the data appropriately (formatting a DateTime maybe), and then your Views don't need any special logic. If later you decide to update the DateTime format, you only need to change it in one place.
Create a (shared) interface to pass to the layer that's between the DAL and MVC, especially if you're unit testing. Use a repository pattern. Check it out here:
http://csharppulse.blogspot.com/2013/09/learning-mvc-part-5repository-pattern.html
This should get you going...

Best Way to Write an Asp.Net Web Service To Play Well In the Wild

I am writing an API for my ASP.NET application that other developers will use. The API will basically return a list of people with their first name, last name, and id. There are lots of ways to write web services in ASP.NET, the easiest probably being create a web service function (asmx) that returns a DataTable. This is simple enough for other .NET developers to deal with, but I am not convinced that this is the best way to write a web service for general platform and language independence.
What is the currently accepted standard to write a web service like this that plays well in the wild today?
Some ideas that come to mind from experience:
Use WCF, not .asmx. WCF does all the same things that ASMX files do, and is generally the replacement for ASMX services (see here and here).
Write methods using simple POCO data types, like List<Person> rather than DataTable. Basic types serialize more easily and will make more sense in other programming environments since you want your service to be language independent.
Provide generic CRUD methods for managing data. Depending on how your service will be consumed, if the user needs to modify data, a simple method is to provide getBlah(), updateBlah(obj newObj), deleteBlah(obj objToDelete), etc. that use the same data types.
Hide the details that the service consumer doesn't need to know, rather than just blindly exposing all of your data types, structures, and field names as-is. This will make your service more robust for handling internal changes, and you can simplify and control what the end-users see. For instance, if you have a Person class with 30 properties, and only 5 are relevant to the end-user, provide a class that interfaces between Person and a PersonSimple class which is exposed. Without this layer, your end-users will have to modify your code every time you change your data structure, and you will be locked down by this tight coupling.
If security is important
Execute your service over SSL. This protects data transfered over the wire from being sniffed.
Use authentication, either with a Login method and session, or SOAP headers. Services by default are anonymous unless there is some sort of authentication scheme. Even if you think nobody will find your service because you only provide the URL to your users, it will get out somehow, somewhere, and people will try to misuse the service when it does. Plus, you can control who can do what by different logins and authorization schemes.
I am currently working on a similar issue: A web api service in .NET that receives data tables as input parameters, apply some operations on them (using Table Valued Functions), and return some output data tables.
In your case, you don't need to use a complex class like DataTable; you could use an array (List<>) of a simple class with fields like first name, last name and id. Using Web Api of ASP.NET you could do something like the following:
1) Create a new WebApi project in Visual Studio: For example (in VS 2012) C# > Web > ASP.NET MVC 4 Web Application > select "Wep Api" as project template
You will see a VS project with lots of folders, including one named Models
For help see: http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
2) Create a new model code file Person.cs with a class like the following:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string[] Friends { get; set; }
}
3) Create e new controller code file PersonController.cs with methods for getting, inserting and updating records of the database. All the necessary serialization/deserialization (JSON and XML) and data binding is done automatically by the Web Api environment set by the project template.
// Get all the records of persons
public IList<Person> Get()
{
// read database into a list of persons (List<Person>)
// return List<Person>
}
Return record of a selected person:
public Person Get(int id)
{
// read database for a selected person
}
Parameter binding (reading a JSON/XML content sent by http POST into an object, or into a list objects) is also done automatically, as easy as the following:
// parameter binding: Create a Person object with content from XML/JSON
public void ReadPerson(Person p)
{
Trace.WriteLine(Person.Id);
}
public void ReadPersonList(List<Person> plist)
{
Trace.WriteLine(plist.Count);
}

ASP.net MVC v2 - Debugging Model Binding Issues - BUG?

I am having more than a little difficulty trying to debug why MVC is not binding correctly in a given case I have...
Basically, I have my action which receives a complex object which in turn has a complex child object - Activity.Location.State (Where Activity is the complex object that the action expects, Location is a complex child object and State is just a string).
Now I set up a test project which as far as I can tell exactly mimics the actually scenario I have, in this test case the binding works... But in my actually project, the binding to Activity works but not to Location... By putting break points within the Locaiton property I can tell that MVC is retrieving the complex Location object from the Activity, but its not setting any of the properties...
I am trying to debug the issue but I need access to the MVC v2 preview 2 symbols which I can't seem to track down... I would like to see what it is actually doing once it pulls out the location object (for some reason I think it might be failing internally but swallowing the exception).
Any ideas on what I could do here...
Cheers
Anthony
UPDATE:
Ok I did what J.W. suggested and directly reference the MVC project...
I found the problem and there was one very small difference that I overlooked... As I result I found out that MVC does not currently support multiple levels of INTERFACE inheritance when it comes to model binding... See the following...
//MODEL
public class Location : ILocation
{
...
}
public interface ILocation : ILocationCore
{
...
}
public interface ILocationCore //In my sample I didn't have this second level interface
{
...
//MVC doesn't find any of these properties
...
}
public class Activity : IActivity
{
...
}
public interface IActivity : IActivityCore
{
ILocation Location { get; set; } //MVC finds this and reads its meta type as an ILocation
//Also the implementation of this Location within Activity will always return a instance - our IoC takes care of that, so MVC should never have to create the instance
}
public interface IActivityCore
{
...
}
//CONTROLLER
public ActionResult Create(Activity activity)
{
}
Hence what I have found is that MVC finds the Location and reads its meta type as an ILocation, but when GetModelProperties is run within the DefaultModelBinder the following occurs -
protected virtual PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
return GetTypeDescriptor(controllerContext, bindingContext).GetProperties();
//This return no properties
}
protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) {
return new AssociatedMetadataTypeTypeDescriptionProvider(bindingContext.ModelType).GetTypeDescriptor(bindingContext.ModelType);
//bindingContext.ModelType - is ILocation
}
Hence I am assuming at this point that TypeDescriptionProvider doesn't support this style of inheritance, which i am quite surprised by. Also looking at the v1 source it looks like this was introduced with v2 - but v1 mightn't have been able to support what I am trying to do anyway.
I wouldn't say that this is really a bug, but I tried replacing my the interfaces with concrete classes and it worked fine. Hence the behavior isn't really what I would expect and is a little inconsistent.
Any thoughts??? I would have thought that this inheritance was not fairly standard but would occur often enough to be catered for. Thanks for the reply.
Cheers
Turns out this behavior is by design due to how interface inheritance works. Interfaces do not define implementations, thus ILocation doesn't "inherit" the properties of ILocationSource. Rather, ILocation only defines what a concrete implementation must implement.
For the full details including the section of the CLI (Common Language Infrastructure) spec which defines this behavior, check out: http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx
I would simply reference to the asp.net mvc2 source code published in codeplex. I did that, it's very straightforward.
It will give you much better understanding when you debugging through the source code.

Resources