简体   繁体   English

如何从MVC Controller访问Web Api?

[英]How to access Web Api from MVC Controller?

I created an Web API 2 project that will be the service layer which connects to the database. 我创建了一个Web API 2项目,该项目将成为连接数据库的服务层。

Now I have two different MVC 5.2 applications: a Website and its CMS ... 现在,我有两个不同的MVC 5.2应用程序:一个网站及其CMS ...

In the MVC 5.2 controllers I want to access the API to get posts, created posts and so on. 在MVC 5.2控制器中,我想访问API以获取帖子,创建的帖子等。

  1. How can I access the api from my MVC controllers? 如何从我的MVC控制器访问api?

  2. Can I call the API and send a Post with one Image to be saved? 我可以调用API并发送带有一张要保存的图片的帖子吗?

    How can I do this? 我怎样才能做到这一点? In which format should I send the image integrated in the PostModel? 我应该以哪种格式发送集成在PostModel中的图像?

  3. How can I make sure only my two MVC applications are authorized to use the API? 如何确保只有两个MVC应用程序被授权使用API​​?

    All applications are on the same server. 所有应用程序都在同一服务器上。

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. 作者评论:我只希望将服务层(Web API)与网站分开,因为我将有3个使用相同服务层的应用程序:博客,CMS和网站。 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: 因此,从我们所有的讨论中可以很明显地看出,您将实现为:

在此处输入图片说明

How you are going to call WebApi from your other .Net Applications? 您将如何从其他.Net应用程序调用WebApi?

The simple thing you are going to use is HttpClient class added in .Net Framework 4.5 (?) I think. 我要使用的最简单的方法是在.Net Framework 4.5(?)中添加的HttpClient类。

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? 如何将图像和数据一起发送到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? 我该如何确保只有我的应用程序可以与WebApi连接?

Well the short answer is that you can use Private key shared between applications by following this architecture. 简短的答案是,您可以通过遵循此体系结构来使用在应用程序之间共享的私钥。

在此处输入图片说明 There are many code available on the net that can help you with this. 网上有很多代码可以帮助您解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM