2

I created an Web API 2 project that will be the service layer which connects to the database.

Now I have two different MVC 5.2 applications: a Website and its CMS ...

In the MVC 5.2 controllers I want to access the API to get posts, created posts and so on.

  1. How can I access the api from my MVC controllers?

  2. Can I call the API and send a Post with one Image to be saved?

    How can I do this? In which format should I send the image integrated in the PostModel?

  3. How can I make sure only my two MVC applications are authorized to use the API?

    All applications are on the same server.

1
  • If your MVC project is in the same solution as the API (you have control of both), instead of hitting your API, utilize the Repository pattern, and hit a common code base from both web-facing projects with your parameters and get the same data that way. Even if they're not in the same solution, you can still reference your Repository DLL in both projects. Commented Sep 9, 2014 at 13:00

1 Answer 1

6

EDIT

AUTHOR COMMENTS: I just want the service layer (Web API) to be separate from the web site since I will have 3 applications using the same service layer: Blog, CMS and Web Site. I appreciate the complete class if possible. Thank You

Yes, it is a good idea to make it separate and don't relay on adding as a reference. It is because someday you may want to deploy on a separate server. Or having a different deployment process, implementing Continuous Integration Development Process.

So from all our discussion it is clear that you are going to implement as:

enter image description here

How you are going to call WebApi from your other .Net Applications?

The simple thing you are going to use is HttpClient class added in .Net Framework 4.5 (?) I think.

using (var client = new HttpClient())
    {
        // New code:
        client.BaseAddress = new Uri("http://localhost:9000/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }
  1. How am I going to send an image along with data to an WebApi?

You can use this code from my project as a reference:

[HttpPost]
        public async Task<IHttpActionResult> UploadFileAsync()
        {
            IHttpActionResult actionResult = null;

            if (Request.Content.IsMimeMultipartContent())
            {
                // Read the file and form data.
                MultipartFormDataMemoryStreamProvider provider = new MultipartFormDataMemoryStreamProvider();
                await Request.Content.ReadAsMultipartAsync(provider);

                // get form data from  like provider.FormData["description"];
                if (!provider.FileStreams.Any())
                {
                    actionResult = BadRequest(ValidationMessages.FileNotFound);
                }
                else
                {
                    var ownerID = 0;
                    var ownerType = provider.FormData.Get("ownerType");
                    int.TryParse(provider.FormData.Get("ownerID"), out ownerID);

                    List<Document> documents = new List<Document>();

                    foreach (KeyValuePair<NameValueCollection, Stream> file in provider.FileStreams)
                    {
                        NameValueCollection fileHeader = file.Key;
                        string fileName = fileHeader.Get("FileName");
                        string contentType = fileHeader.Get("ContentType");
                        Stream stream = file.Value;


                        using (var reader = new BinaryReader(stream))
                        {
                            var fileBytes = reader.ReadBytes((int)stream.Length);

                            var document = new Document()
                            {
                                FileName = fileName,
                                Extension = Path.GetExtension(fileName),
                                Binary = fileBytes,
                                ContentType = contentType,
                                Size = fileBytes.LongLength
                            };

                            if (ownerID > 0)
                            {
                                document.RequestID = ownerID;
                            }

                            documents.Add(document);
                        }
                    }

                    if (documents.Count() > 0)
                    {
                        string exceptionMessages = string.Empty;
                        if (this.DomainService.InsertRange(documents, out exceptionMessages))
                        {
                            actionResult = Created(string.Empty, documents);
                        }
                        else
                        {
                            actionResult = BadRequest(exceptionMessages);
                        }
                    }
                    else
                    {
                        actionResult = BadRequest(ValidationMessages.FileNotFound);
                    }
                }
            }
            else
            {
                // The response to upload did not came with Multiple content;
                actionResult = BadRequest(ValidationMessages.MimeNotFound);
            }

            return actionResult;
        }


using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;

namespace Webapi.Helper
{
    public class MultipartFormDataMemoryStreamProvider : MultipartMemoryStreamProvider
    {
        private readonly Collection<bool> _isFormData = new Collection<bool>();
        private readonly NameValueCollection _formData = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
        private readonly Dictionary<NameValueCollection, Stream> _fileStreams = new Dictionary<NameValueCollection, Stream>();

        public NameValueCollection FormData
        {
            get { return _formData; }
        }

        public Dictionary<NameValueCollection, Stream> FileStreams
        {
            get { return _fileStreams; }
        }

        public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }


            var contentDisposition = headers.ContentDisposition;
            if (contentDisposition == null)
            {
                throw new InvalidOperationException("Did not find required 'Content-Disposition' header field in MIME multipart body part.");
            }

            _isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));
            return base.GetStream(parent, headers);
        }

        public override async Task ExecutePostProcessingAsync()
        {
            for (var index = 0; index < Contents.Count; index++)
            {
                HttpContent formContent = Contents[index];
                if (_isFormData[index])
                {
                    // Field
                    string formFieldName = UnquoteToken(formContent.Headers.ContentDisposition.Name) ?? string.Empty;
                    string formFieldValue = await formContent.ReadAsStringAsync();
                    FormData.Add(formFieldName, formFieldValue);
                }
                else
                {
                    Stream stream = await formContent.ReadAsStreamAsync(); // File
                    /// we are not going to accept any stream that has no value!!
                    if (stream.Length > 0)
                    {
                        string fileName = UnquoteToken(formContent.Headers.ContentDisposition.FileName);

                        NameValueCollection fileHeader = new NameValueCollection();
                        fileHeader.Add("FileName", fileName);
                        fileHeader.Add("ContentType", UnquoteToken(formContent.Headers.ContentType.MediaType));
                        FileStreams.Add(fileHeader, stream);
                    }
                }
            }
        }

        private static string UnquoteToken(string token)
        {
            if (string.IsNullOrWhiteSpace(token))
            {
                return token;
            }

            if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
            {
                return token.Substring(1, token.Length - 2);
            }

            return token;
        }
    }
}

How I am going to secure so that only my applications can connect with WebApi?

Well the short answer is that you can use Private key shared between applications by following this architecture.

enter image description here There are many code available on the net that can help you with this.

Sign up to request clarification or add additional context in comments.

6 Comments

But when creating a post two calls are necessary? One to send the post data and other to send the image?
In terms of security if I use a token I would have in the database a table with Applications list and a token for each one to compare to ... Is that what you mean? Do you know any docs where I can read about it? I have been goggling for it but I am not sure how to search for.
It comes down to how u want to architect. If you just want to host separately ie saparate website then my way is good otherwise you can just refer. You can awns multiple.data however you will.have to write few line of code I can send you tomorrow a complete class . Time to sleep
I just want the service layer (Web API) to be separate from the web site since I will have 3 applications using the same service layer: Blog, CMS and Web Site. I appreciate the complete class if possible. Thank You
answered you above mate.With the above approach you can pass data and image in one go - you can even pass multiple images. See ownertype and ownerid how I am reading.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.