欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

ASP.NETWebAPI單元測(cè)試-WebAPI簡(jiǎn)單介紹-創(chuàng)新互聯(lián)

如果你對(duì)Web API已比較了解則可以跳過本篇直接看單元測(cè)試部分。

創(chuàng)新互聯(lián)公司主要業(yè)務(wù)有網(wǎng)站營(yíng)銷策劃、成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開發(fā)、成都小程序開發(fā)、H5頁面制作、程序開發(fā)等業(yè)務(wù)。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當(dāng)客戶,還把客戶視為我們的合作伙伴,在開展業(yè)務(wù)的過程中,公司還積累了豐富的行業(yè)經(jīng)驗(yàn)、全網(wǎng)營(yíng)銷推廣資源和合作伙伴關(guān)系資源,并逐漸建立起規(guī)范的客戶服務(wù)和保障體系。 

創(chuàng)建一個(gè)叫 UnitTesingWebAPI的空白的解決方案,并包含下列項(xiàng)目:

  1. UnitTestingWebAPI.Domain:類庫(kù)(包含 Entity Models)

  2. UnitTestingWebAPI.Data:類庫(kù)(包含 Repositories)

  3. UnitTestingWebAPI.Services:類庫(kù)(包含 Services)

  4. UnitTestingWebAPI.API.Core:類庫(kù)(包含WebAPI組件,例如:Controllers, Filters, Massage Handlers)

  5. UnitTestingWebAPI.API:空的ASP.NET Web Application(Web程序去管控(host) WebAPI

  6. UnitTestingWebAPI.Tests:類庫(kù)(包含單元測(cè)試)

Domain 層

Articles.cs

public class Article
{
    public int ID { get; set; }
    public string Title { get; set; }
    public string Contents { get; set; }
    public string Author { get; set; }
    public string URL { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateEdited { get; set; }

    public int BlogID { get; set; }
    public virtual Blog Blog { get; set; }

    public Article()
    {
    }
}

Blog.cs

public class Blog
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string URL { get; set; }
    public string Owner { get; set; }
    public DateTime DateCreated { get; set; }
    public virtual ICollection<Article> Articles { get; set; }

    public Blog()
    {
        Articles = new HashSet<Article>();
    }
}

Respository 層
為UnitTestingWebAPI.Data安裝Entity Framework,有兩種方式:

1:在UnitTestingWebAPI.Data上右鍵,點(diǎn)擊管理Nuget包,選擇對(duì)話窗口的左邊選擇在線包,找到EF進(jìn)行安裝

ASP.NET Web API 單元測(cè)試 - Web API 簡(jiǎn)單介紹

2:命令行:

install-package EntityFramework

ASP.NET Web API 單元測(cè)試 - Web API 簡(jiǎn)單介紹

注:一定要注意我用紅色圈住的地方。

添加下面的類:

Configurations/ArticleConfiguration.cs

public class ArticleConfiguration : EntityTypeConfiguration<Article>
{
    public ArticleConfiguration()
    {
        ToTable("Article");
        Property(a => a.Title).IsRequired().HasMaxLength(100);
        Property(a => a.Contents).IsRequired();
        Property(a => a.Author).IsRequired().HasMaxLength(50);
        Property(a => a.URL).IsRequired().HasMaxLength(200);
        Property(a => a.DateCreated).HasColumnType("datetime2");
        Property(a => a.DateEdited).HasColumnType("datetime2");
    }
}

Configurations/BlogConfiguration.cs

public class BlogConfiguration : EntityTypeConfiguration<Blog>
{
    public BlogConfiguration()
    {
        ToTable("Blog");
        Property(b => b.Name).IsRequired().HasMaxLength(100);
        Property(b => b.URL).IsRequired().HasMaxLength(200);
        Property(b => b.Owner).IsRequired().HasMaxLength(50);
        Property(b => b.DateCreated).HasColumnType("datetime2");
    }
}

Configurations/BloggerEntities

    public class BloggerEntities : DbContext
    {
        public BloggerEntities()
            : base("BloggerEntities")
        {
            Configuration.ProxyCreationEnabled = false;
        }

        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Article> Articles { get; set; }

        public virtual void Commit()
        {
            base.SaveChanges();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new ArticleConfiguration());
            modelBuilder.Configurations.Add(new BlogConfiguration());
        }
    }

Configurations/BloggerInitializer

public class BloggerInitializer : DropCreateDatabaseIfModelChanges<BloggerEntities>
{
    protected override void Seed(BloggerEntities context)
    {
        GetBlogs().ForEach(b => context.Blogs.Add(b));

        context.Commit();
    }

    public static List<Blog> GetBlogs()
    {
        List<Blog> _blogs = new List<Blog>();

        // Add two Blogs
        Blog _chsakellsBlog = new Blog()
        {
            Name = "chsakell's Blog",
            URL = "https://chsakell.com/",
            Owner = "Chris Sakellarios",
            Articles = GetChsakellsArticles()
        };

        Blog _dotNetCodeGeeks = new Blog()
        {
            Name = "DotNETCodeGeeks",
            URL = "dotnetcodegeeks",
            Owner = ".NET Code Geeks",
            Articles = GetDotNETGeeksArticles()
        };

        _blogs.Add(_chsakellsBlog);
        _blogs.Add(_dotNetCodeGeeks);

        return _blogs;
    }

    public static List<Article> GetChsakellsArticles()
    {
        List<Article> _articles = new List<Article>();

        Article _oData = new Article()
        {
            Author = "Chris S.",
            Title = "ASP.NET Web API feat. OData",
            URL = "https://chsakell.com/2015/04/04/asp-net-web-api-feat-odata/",
            Contents = @"OData is an open standard protocol allowing the creation and consumption of queryable 
                        and interoperable RESTful APIs. It was initiated by Microsoft and it’s mostly known to
                        .NET Developers from WCF Data Services. There are many other server platforms supporting
                        OData services such as Node.js, PHP, Java and SQL Server Reporting Services. More over, 
                        Web API also supports OData and this post will show you how to integrate those two.."
        };

        Article _wcfCustomSecurity = new Article()
        {
            Author = "Chris S.",
            Title = "Secure WCF Services with custom encrypted tokens",
            URL = "https://chsakell.com/2014/12/13/secure-wcf-services-with-custom-encrypted-tokens/",
            Contents = @"Windows Communication Foundation framework comes with a lot of options out of the box, 
                        concerning the security logic you will apply to your services. Different bindings can be
                        used for certain kind and levels of security. Even the BasicHttpBinding binding supports
                        some types of security. There are some times though where you cannot or don’t want to use
                        WCF security available options and hence, you need to develop your own authentication logic
                        accoarding to your business needs."
        };

        _articles.Add(_oData);
        _articles.Add(_wcfCustomSecurity);

        return _articles;
    }

    public static List<Article> GetDotNETGeeksArticles()
    {
        List<Article> _articles = new List<Article>();

        Article _angularFeatWebAPI = new Article()
        {
            Author = "Gordon Beeming",
            Title = "AngularJS feat. Web API",
            URL = "http://www.dotnetcodegeeks.com/2015/05/angularjs-feat-web-api.html",
            Contents = @"Developing Web applications using AngularJS and Web API can be quite amuzing. You can pick 
                        this architecture in case you have in mind a web application with limitted page refreshes or
                        post backs to the server while each application’s View is based on partial data retrieved from it."
        };

        _articles.Add(_angularFeatWebAPI);

        return _articles;
    }

    public static List<Article> GetAllArticles()
    {
        List<Article> _articles = new List<Article>();
        _articles.AddRange(GetChsakellsArticles());
        _articles.AddRange(GetDotNETGeeksArticles());

        return _articles;
    }
}

Infrastructure/Disposable.cs

public class Disposable : IDisposable
{
    private bool isDisposed;

    ~Disposable()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    private void Dispose(bool disposing)
    {
        if (!isDisposed && disposing)
        {
            DisposeCore();
        }

        isDisposed = true;
    }

    // Ovveride this to dispose custom objects
    protected virtual void DisposeCore()
    {
    }
}

Infrastructure/IDbFactory.cs

public interface IDbFactory : IDisposable
{
    BloggerEntities Init();
}

Infrastructure/DbFactory.cs

public class DbFactory : Disposable, IDbFactory
{
    BloggerEntities dbContext;

    public BloggerEntities Init()
    {
        return dbContext ?? (dbContext = new BloggerEntities());
    }

    protected override void DisposeCore()
    {
        if (dbContext != null)
            dbContext.Dispose();
    }
}

Infrastrure/IRepository.cs

public interface IRepository<T> where T : class
{
    // Marks an entity as new
    void Add(T entity);
    // Marks an entity as modified
    void Update(T entity);
    // Marks an entity to be removed
    void Delete(T entity);
    void Delete(Expression<Func<T, bool>> where);
    // Get an entity by int id
    T GetById(int id);
    // Get an entity using delegate
    T Get(Expression<Func<T, bool>> where);
    // Gets all entities of type T
    IEnumerable<T> GetAll();
    // Gets entities using delegate
    IEnumerable<T> GetMany(Expression<Func<T, bool>> where);
}

Infrastructure/RepositoryBase.cs

public abstract class RepositoryBase<T> where T : class
{
    #region Properties
    private BloggerEntities dataContext;
    private readonly IDbSet<T> dbSet;

    protected IDbFactory DbFactory
    {
        get;
        private set;
    }

    protected BloggerEntities DbContext
    {
        get { return dataContext ?? (dataContext = DbFactory.Init()); }
    }
    #endregion

    protected RepositoryBase(IDbFactory dbFactory)
    {
        DbFactory = dbFactory;
        dbSet = DbContext.Set<T>();
    }

    #region Implementation
    public virtual void Add(T entity)
    {
        dbSet.Add(entity);
    }

    public virtual void Update(T entity)
    {
        dbSet.Attach(entity);
        dataContext.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Delete(T entity)
    {
        dbSet.Remove(entity);
    }

    public virtual void Delete(Expression<Func<T, bool>> where)
    {
        IEnumerable<T> objects = dbSet.Where<T>(where).AsEnumerable();
        foreach (T obj in objects)
            dbSet.Remove(obj);
    }

    public virtual T GetById(int id)
    {
        return dbSet.Find(id);
    }

    public virtual IEnumerable<T> GetAll()
    {
        return dbSet.ToList();
    }

    public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
    {
        return dbSet.Where(where).ToList();
    }

    public T Get(Expression<Func<T, bool>> where)
    {
        return dbSet.Where(where).FirstOrDefault<T>();
    }

    #endregion

}

Infrastrure/IUnitOfWork.cs

public interface IUnitOfWork
{
    void Commit();
}

Infrastrure/UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
{
    private readonly IDbFactory dbFactory;
    private BloggerEntities dbContext;

    public UnitOfWork(IDbFactory dbFactory)
    {
        this.dbFactory = dbFactory;
    }

    public BloggerEntities DbContext
    {
        get { return dbContext ?? (dbContext = dbFactory.Init()); }
    }

    public void Commit()
    {
        DbContext.Commit();
    }
}

Infrastructure/BlogRepository.cs

public class BlogRepository : RepositoryBase<Blog>, IBlogRepository
{
    public BlogRepository(IDbFactory dbFactory)
        : base(dbFactory) { }

    public Blog GetBlogByName(string blogName)
    {
        var _blog = this.DbContext.Blogs.Where(b => b.Name == blogName).FirstOrDefault();

        return _blog;
    }
}

public interface IBlogRepository : IRepository<Blog>
{
    Blog GetBlogByName(string blogName);
}

Repositories/ArticleRepository.cs

public class ArticleRepository : RepositoryBase<Article>, IArticleRepository
{
    public ArticleRepository(IDbFactory dbFactory)
        : base(dbFactory) { }

    public Article GetArticleByTitle(string articleTitle)
    {
        var _article = this.DbContext.Articles.Where(b => b.Title == articleTitle).FirstOrDefault();

        return _article;
    }
}

public interface IArticleRepository : IRepository<Article>
{
    Article GetArticleByTitle(string articleTitle);
}

Service 層

到UnitTestingWebAPI.Service項(xiàng)目上,添加對(duì)UnitTestingWebAPI.Domain, UnitTestingWebAPI.Data的引用,并添加下列文件:

ArticleService.cs

// operations you want to expose
public interface IArticleService
{
    IEnumerable<Article> GetArticles(string name = null);
    Article GetArticle(int id);
    Article GetArticle(string name);
    void CreateArticle(Article article);
    void UpdateArticle(Article article);
    void DeleteArticle(Article article);
    void SaveArticle();
}

public class ArticleService : IArticleService
{
    private readonly IArticleRepository articlesRepository;
    private readonly IUnitOfWork unitOfWork;

    public ArticleService(IArticleRepository articlesRepository, IUnitOfWork unitOfWork)
    {
        this.articlesRepository = articlesRepository;
        this.unitOfWork = unitOfWork;
    }

    #region IArticleService Members

    public IEnumerable<Article> GetArticles(string title = null)
    {
        if (string.IsNullOrEmpty(title))
            return articlesRepository.GetAll();
        else
            return articlesRepository.GetAll().Where(c => c.Title.ToLower().Contains(title.ToLower()));
    }

    public Article GetArticle(int id)
    {
        var article = articlesRepository.GetById(id);
        return article;
    }

    public Article GetArticle(string title)
    {
        var article = articlesRepository.GetArticleByTitle(title);
        return article;
    }

    public void CreateArticle(Article article)
    {
        articlesRepository.Add(article);
    }

    public void UpdateArticle(Article article)
    {
        articlesRepository.Update(article);
    }

    public void DeleteArticle(Article article)
    {
        articlesRepository.Delete(article);
    }

    public void SaveArticle()
    {
        unitOfWork.Commit();
    }

    #endregion
}

BlogService.cs

// operations you want to expose
public interface IBlogService
{
    IEnumerable<Blog> GetBlogs(string name = null);
    Blog GetBlog(int id);
    Blog GetBlog(string name);
    void CreateBlog(Blog blog);
    void UpdateBlog(Blog blog);
    void SaveBlog();
    void DeleteBlog(Blog blog);
}

public class BlogService : IBlogService
{
    private readonly IBlogRepository blogsRepository;
    private readonly IUnitOfWork unitOfWork;

    public BlogService(IBlogRepository blogsRepository, IUnitOfWork unitOfWork)
    {
        this.blogsRepository = blogsRepository;
        this.unitOfWork = unitOfWork;
    }

    #region IBlogService Members

    public IEnumerable<Blog> GetBlogs(string name = null)
    {
        if (string.IsNullOrEmpty(name))
            return blogsRepository.GetAll();
        else
            return blogsRepository.GetAll().Where(c => c.Name == name);
    }

    public Blog GetBlog(int id)
    {
        var blog = blogsRepository.GetById(id);
        return blog;
    }

    public Blog GetBlog(string name)
    {
        var blog = blogsRepository.GetBlogByName(name);
        return blog;
    }

    public void CreateBlog(Blog blog)
    {
        blogsRepository.Add(blog);
    }

    public void UpdateBlog(Blog blog)
    {
        blogsRepository.Update(blog);
    }

    public void DeleteBlog(Blog blog)
    {
        blogsRepository.Delete(blog);
    }

    public void SaveBlog()
    {
        unitOfWork.Commit();
    }

    #endregion
}

Web API Core 組件

在UnitTestingWebAPI.API.Core 上添加 UnitTestingWebAPI.API.Domain 和UnitTestingWebAPI.Service 項(xiàng)目,并安裝下面的包(方法和前面Resporities層一樣):

  1. Entity Framework

  2. Microsoft.AspNet.WebApi.Core

  3. Microsoft.AspNet.WebApi.Client

添加下面的Web API Controller到 Controller 文件夾中:

Controllers/ArticlesController.cs

public class ArticlesController : ApiController
{
    private IArticleService _articleService;

    public ArticlesController(IArticleService articleService)
    {
        _articleService = articleService;
    }

    // GET: api/Articles
    public IEnumerable<Article> GetArticles()
    {
        return _articleService.GetArticles();
    }

    // GET: api/Articles/5
    [ResponseType(typeof(Article))]
    public IHttpActionResult GetArticle(int id)
    {
        Article article = _articleService.GetArticle(id);
        if (article == null)
        {
            return NotFound();
        }

        return Ok(article);
    }

    // PUT: api/Articles/5
    [ResponseType(typeof(void))]
    public IHttpActionResult PutArticle(int id, Article article)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != article.ID)
        {
            return BadRequest();
        }

        _articleService.UpdateArticle(article);

        try
        {
            _articleService.SaveArticle();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ArticleExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/Articles
    [ResponseType(typeof(Article))]
    public IHttpActionResult PostArticle(Article article)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _articleService.CreateArticle(article);

        return CreatedAtRoute("DefaultApi", new { id = article.ID }, article);
    }

    // DELETE: api/Articles/5
    [ResponseType(typeof(Article))]
    public IHttpActionResult DeleteArticle(int id)
    {
        Article article = _articleService.GetArticle(id);
        if (article == null)
        {
            return NotFound();
        }

        _articleService.DeleteArticle(article);

        return Ok(article);
    }

    private bool ArticleExists(int id)
    {
        return _articleService.GetArticle(id) != null;
    }
}

Controllers/BlogsController.cs

public class BlogsController : ApiController
{
    private IBlogService _blogService;

    public BlogsController(IBlogService blogService)
    {
        _blogService = blogService;
    }

    // GET: api/Blogs
    public IEnumerable<Blog> GetBlogs()
    {
        return _blogService.GetBlogs();
    }

    // GET: api/Blogs/5
    [ResponseType(typeof(Blog))]
    public IHttpActionResult GetBlog(int id)
    {
        Blog blog = _blogService.GetBlog(id);
        if (blog == null)
        {
            return NotFound();
        }

        return Ok(blog);
    }

    // PUT: api/Blogs/5
    [ResponseType(typeof(void))]
    public IHttpActionResult PutBlog(int id, Blog blog)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != blog.ID)
        {
            return BadRequest();
        }

        _blogService.UpdateBlog(blog);

        try
        {
            _blogService.SaveBlog();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!BlogExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/Blogs
    [ResponseType(typeof(Blog))]
    public IHttpActionResult PostBlog(Blog blog)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _blogService.CreateBlog(blog);

        return CreatedAtRoute("DefaultApi", new { id = blog.ID }, blog);
    }

    // DELETE: api/Blogs/5
    [ResponseType(typeof(Blog))]
    public IHttpActionResult DeleteBlog(int id)
    {
        Blog blog = _blogService.GetBlog(id);
        if (blog == null)
        {
            return NotFound();
        }

        _blogService.DeleteBlog(blog);

        return Ok(blog);
    }

    private bool BlogExists(int id)
    {
        return _blogService.GetBlog(id) != null;
    }
}

在有需要時(shí)添加下面的過濾器,它會(huì)反轉(zhuǎn)Articles list的順序:

Filters/ArticlesReversedFilter.cs

public class ArticlesReversedFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        var objectContent = actionExecutedContext.Response.Content as ObjectContent;
        if (objectContent != null)
        {
            List<Article> _articles = objectContent.Value as List<Article>;
            if (_articles != null && _articles.Count > 0)
            {
                _articles.Reverse();
            }
        }
    }
}

當(dāng)添加下面的媒體類型格式化器,可以返回一個(gè)用逗號(hào)分割來展示的文章列表:

MediaTypeFormatters/ArticleFormatter.cs

public class ArticleFormatter : BufferedMediaTypeFormatter
{
    public ArticleFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/article"));
    }

    public override bool CanReadType(Type type)
    {
        return false;
    }

    public override bool CanWriteType(Type type)
    {
        //for single article object
        if (type == typeof(Article))
            return true;
        else
        {
            // for multiple article objects
            Type _type = typeof(IEnumerable<Article>);
            return _type.IsAssignableFrom(type);
        }
    }

    public override void WriteToStream(Type type,
                                        object value,
                                        Stream writeStream,
                                        HttpContent content)
    {
        using (StreamWriter writer = new StreamWriter(writeStream))
        {
            var articles = value as IEnumerable<Article>;
            if (articles != null)
            {
                foreach (var article in articles)
                {
                    writer.Write(String.Format("[{0},\"{1}\",\"{2}\",\"{3}\",\"{4}\"]",
                                                article.ID,
                                                article.Title,
                                                article.Author,
                                                article.URL,
                                                article.Contents));
                }
            }
            else
            {
                var _article = value as Article;
                if (_article == null)
                {
                    throw new InvalidOperationException("Cannot serialize type");
                }
                writer.Write(String.Format("[{0},\"{1}\",\"{2}\",\"{3}\",\"{4}\"]",
                                                _article.ID,
                                                _article.Title,
                                                _article.Author,
                                                _article.URL,
                                                _article.Contents));
            }
        }
    }
}

添加下面兩個(gè) 消息 處理器,第一個(gè)負(fù)責(zé)Response中添加定制 header,第二個(gè)可以決定這個(gè)請(qǐng)求是否被接受:

MessageHandler/HeaderAppenderHandler.cs

public class HeaderAppenderHandler : DelegatingHandler
{
    async protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

        response.Headers.Add("X-WebAPI-Header", "Web API Unit testing in chsakell's blog.");
        return response;
    }
}

HeaderAppenderHandler/EndRequestHandler.cs

public class EndRequestHandler : DelegatingHandler
{
    async protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.RequestUri.AbsoluteUri.Contains("test"))
        {
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("Unit testing message handlers!")
            };

            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return await tsc.Task;
        }
        else
        {
            return await base.SendAsync(request, cancellationToken);
        }
    }
}

添加下面被用于從Web 應(yīng)用程序中注冊(cè)Controller 的 DefaultAssembliesResolver

CustomAssembliesResolver.cs

public class CustomAssembliesResolver : DefaultAssembliesResolver
{
    public override ICollection<Assembly> GetAssemblies()
    {
        var baseAssemblies = base.GetAssemblies().ToList();
        var assemblies = new List<Assembly>(baseAssemblies) { typeof(BlogsController).Assembly };
        baseAssemblies.AddRange(assemblies);

        return baseAssemblies.Distinct().ToList();
    }
}

Asp.NET Web Application

添加 UnitTestingWebAPI.API Web應(yīng)用項(xiàng)目,并且添加引用 UnitTestingWebAPI.Core, UnitTestingWebAPI.Data 和 UnitTestingWebAPI.Service,同樣需要安裝下列組件包:

  1. Entity Framework

  2. Microsoft.AspNet.WebApi.WebHost

  3. Microsoft.AspNet.WebApi.Core

  4. Microsoft.AspNet.WebApi.Client

  5. Microsoft.AspNet.WebApi.Owin

  6. Microsoft.Owin.Host.SystemWeb

  7. Microsoft.Owin

  8. Autofac.WebApi2

在Global配置文件(如果沒有就新增一個(gè))中配置初始化數(shù)據(jù)庫(kù)配置

Global.asax

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);

    // Init database
    System.Data.Entity.Database.SetInitializer(new BloggerInitializer());
}

同樣要記得添加一個(gè)相關(guān)的Connection String在Web.config文件中.

<connectionStrings>
  <add name="BloggerDbConnStr" connectionString="Data Source=(localdb)\v11.0;Initial Catalog=BloggerDB;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>

注冊(cè)外部Controller

在Web Application的根目錄創(chuàng)建一個(gè) Owin Startup.cs 文件并且粘貼下面的代碼,在(autofac configration)需要的時(shí)候,這部分代碼會(huì)確保 UnitTestingWebAPI.API.Core(CustomAssembliesResolver) 項(xiàng)目正確使用WebApi Controller和注入合適的倉(cāng)庫(kù)以及服務(wù).

Startup.cs

public class Startup
{
    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
        config.Services.Replace(typeof(IAssembliesResolver), new CustomAssembliesResolver());
        config.Formatters.Add(new ArticleFormatter());

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );


        // Autofac configuration
        var builder = new ContainerBuilder();
        builder.RegisterApiControllers(typeof(BlogsController).Assembly);
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
        builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerRequest();

        //Repositories
        builder.RegisterAssemblyTypes(typeof(BlogRepository).Assembly)
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces().InstancePerRequest();
        // Services
        builder.RegisterAssemblyTypes(typeof(ArticleService).Assembly)
            .Where(t => t.Name.EndsWith("Service"))
            .AsImplementedInterfaces().InstancePerRequest();

        IContainer container = builder.Build();
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

        appBuilder.UseWebApi(config);
    }
}

在這個(gè)時(shí)候,你應(yīng)該可以啟動(dòng)Web應(yīng)用程序并且使用下面的請(qǐng)求來獲取article或blogs(這里的端口可能不一致):

http://localhost:57414/api/Articles

http://localhost:57414/api/Blogs

同樣附上原文:chsakell's Blog

文章中的源碼: http://down.51cto.com/data/2243634

到此為止,WebAPI部分介紹的差不多了,有問題請(qǐng)留言.

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。

當(dāng)前題目:ASP.NETWebAPI單元測(cè)試-WebAPI簡(jiǎn)單介紹-創(chuàng)新互聯(lián)
本文來源:http://aaarwkj.com/article30/gceso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷手機(jī)網(wǎng)站建設(shè)、域名注冊(cè)、Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)
精品日韩av一区二区三区| 国产亚洲一线二线三线| 日韩欧美一区二区不卡在线| 18禁在线免费观看网站| 国产精品免费观看在线国产 | 欧美看黄网站在线观看| 亚洲天堂,男人的天堂| 日本成人午夜福利电影| 就去吻色综合一二三四| 亚洲精品熟女一区二区三区| 久久av免费一区二区观看| 成人又黄又爽大片在线观看 | 天堂av五月在线观看| 午夜视频在线观看黄片| 未满十八禁止下载软件| 日韩精品人妻一区二区三区蜜桃臀| 欧美亚洲综合激情在线 | 欧美三级欧美一级视频看| 国产精品毛片av在线| 日韩一区二区高清视频在线观看| 91久久精品国产一区| 国产国语激情对白在线| 91精彩啦在线看国产| 高清偷自拍亚洲精品三区| 91精品国产综合久久麻豆| 蜜桃午夜精品一区二区三区| 91青青草原在线视频| 激情偷拍一区二区三区视频| 日韩亚洲中文一区三级黄片| 久久国产国内精品国语对白| 亚洲国产精品日韩专区av有中文| 久久国产精品av在线观看| 亚洲午夜精品久久久天堂| av亚洲天堂免费观看| 国产一区999精品在线| 国产三级伦理在线播放| 国产中文字幕乱码中文| 尤物视频在线观看一下| 免费国产三级在线观看| 97视频免费观看在线| 国产精品传媒免费在线观看|