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

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);
}

Related

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 Identity - Steps for custom authentication

Envrionment: Visual Studio 2013, ASP.NET MVC 5
On the new MVC5-based project I will be working on, I need to use a custom database that stores usernames, passwords, and roles in its own way. I am searching the Internet to look for an example for custom authentication. Looks like the old-style "membership provider" classes have been replaced by the new "Identity" mechanism.
However, finding a good step-by-step example has proven to be futile. There are a few links (published this year) that talk about implementing custom IPrincipal and DbContext classes. Some other links talk about implementing IUserLoginStore and IUserPasswordStore. A few others hinted on implementing IUser, IUserStore interfaces.
Maybe the last option is what is needed. Can someone please guide me with the steps or point me to any link that has a simple example? Something like:
Implement MyUser based on IUser
Implement MyUserStore based on IUserStore
Modify web.config to use MyUserStore
Remove DefaultConnection from web.config as it is not required
Regards.
First, stop. Stop thinking about "custom authentication". You don't need custom authentication, you just need custom storage of authentication data.
ASP.NET Identity has abstracted out the storage mechanism of authentication from the process of authentication. There are several interfaces that follow the pattern IxxxStore.. Such as IUserStore, IRoleStore, etc...
You can find more information about this here, along with custom implementations for various databases which you can probably convert to your own needs.
http://odetocode.com/blogs/scott/archive/2014/01/20/implementing-asp-net-identity.aspx
As an example, here is a RavenDB implementation that uses all the various interfaces in a single class.
https://github.com/tugberkugurlu/AspNet.Identity.RavenDB/blob/master/src/AspNet.Identity.RavenDB/Stores/RavenUserStore.cs
However, all this assumes you really truly a need to store data totally differently. If you just need to store the data in different columns, then it may simply be as easy as overriding OnModelCreating in your IdentityContext and changing the names of the columns in use.
ad.1.
public class ApplicationUser :IUser
{
public string Id
{
get;
set;
}
public string UserName
{
get;
set;
}
}
ad.2.
public class MyStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserSecurityStampStore<ApplicationUser>, IUserEmailStore<ApplicationUser>
{
... //implement all interfaces here
}
ad. 3.
Now you can create your applicationUserManagerService (you will need IdentityMessageService, and IDataProtectionProvider):
var applicationUserManagerService = new ApplicationUserManagerService(new MyStore(), emailService, dataProtectionProvider);
Try to use IoC and register your IUserStore (I did it this way - link below):
unityContainer.RegisterType<IUserStore<ApplicationUser>, MyStore>();
check also my answer here (i'm using int as UserId there):
AspIdentiy ApplicationUserManager is Static, how to extend so it participates in my IoC framework?

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...

Object property validation in MVC (using web service)

I have an ASP.Net MVC site, which connects to a web service.
The site's view model contains objects for each group of required service data AccountDetails (containing AccountId, AccountType, etc.), ContactDetails (containing Name, Address, etc.) and so on.
The service has a 'CreateUser()' method that accepts these objects as parameters, and it then performs all the validation itself - handing back an Object which has an array of any errors that have been found, including the name of the specific property/field.
I would like to know if there is a way of passing this returned error data into either DataAnnotations or something else.
I specifically can't write the conditions in the model itself, because the validation conditions within the web service are open to change at any moment - and we want this to dictate what fails and what succeeds.
== FURTHER INFO FOR MAKE IT A BIT CLEARER ==
Imagine I were locally (within the View Model) creating the ContactDetails class, I could very simply do this
public class ContactDetails
{
[IsRequired()]
[CustomAttributeofSomekind]
public string FirstName { get; set; }
public string LastName { get; set; }
}
However in this scenario - if we wanted to change the validation critera for whatever reason we would have to change it in both the web service AND in all the client websites that access the service.
We don't want to have to do this - instead I if (in the above) scenario ContactDetails.LastName is suddenly required and must be no more than 10 characters - this should only need updating in the web service.
I think you have two options:
Create a User class to wrap the CreateUser() method and add the DataAnnotations to that (this is what I would do, it allows you to go strongly-typed.)
Call the CreateUser() method directly from the controller Action and use server-side validation. Add each validation error in the CreateUser() result to the ModelState.Errors collection when any validation rules are violated.

Thoughts on writing a "flexible" API?

I may have the wrong "pattern" here, but I think it's a fair topic.
I have an ASP.Net MVC application in which it calls out to a WCF service to get back the ViewModels that will be rendered. (the reason it's using a WCF service is so that other small MVC apps may also call on for these ViewModels...only internally, it's not a publicly available thing so I can change anything either side of the service. The idea is to move the logic that was in the website, closer to the server/database so the roundtrips aren't so costly - and only do one roundtrip overall from the webserver to the database server).
I'm trying to work out the best thing to return these "ViewModels" in from the service. There are lots of common little bits of functionality, but each page may want to display different subsets of these things (so homepage maybe a list of tables, next page, a list of tables and users that are available).
So what's the best way of returning the information that the page wants, hopefully without the webservice knowing about the page?
Edit:
It's been suggested below that I move the logic in process. This would be a lot faster, except that's what we're moving away from because it is actually a lot slower (in this case). The reason for this is that the database is on one server, and the webapp is on another server, and the webapp is particularly chatty at points (there are pages it could end up doing 2K round trips - (I have no control over reducing this number before that's suggested)), so moving the logic closer to the db is the next best way of making it more performant.
I would look at creating a ViewModel per each MVC app/view. The service could just return the maximum amount of data for the "view" in a logical sense and each MVC app uses the information it wants when composing the ViewModel for it's view.
Your service is then only responsible for one thing, returning data specific to a view's function. The controller of each app is responsible for using/not using pieces of the returned data.
This will be more flexible as your ViewModels may require different validation rules as well. ViewModels also have MVC-specific needs(SelectList etc..) that shouldn't really be returned by a service layer. It seems like something can be shared at a glance, but there are generally lots of small differences that make sharing ViewModels a bad idea.
class MyServiceViewResult
{
public int SomethingEveryViewNeeds { get; set; }
public bool OnlyOneViewMightNeedThis { get; set; }
}
class ViewModel1
{
public int IdProperty { get; set; }
public ViewModel1(MyServiceViewResult result)
{
IdProperty = result.SomethingEveryViewNeeds;
}
}
class ViewModel2
{
public int IdProperty { get; set; }
public bool IsAllowed { get; set; }
public ViewModel2(MyServiceViewResult result)
{
IdProperty = result.SomethingEveryViewNeeds;
IsAllowed = result.OnlyOneViewMightNeedThis;
}
}
Instead of having a web service, why don't you just implement the service as a reusable library that encapsulates the desired functionality?
This will also allow you to use polymorphism to implement customizations. WCF doesn't support polymorphism in a flexible way...
Using an in-proc service will also be a lot faster.
See this related question for outlines of a polymorphic solution: Is this a typical use case for IOC?

Resources