클라이언트

주의할점은

서버와 클라이언트 방식을 똑같이 맞추어 줘야한다

일단 기본적으로 20MB 이상 안올라감

아래값은 최대값이다(2GB) 이렇게 하면 성능 저하 및 디도스 공격에 취약해짐. 적절하게 값을 지정 해야하고

인증받은 계정만 쓸 수 있게 해야함

 

   transferMode="Streamed" messageEncoding="Mtom"

 

        private static IFileService CreateIFileService()
        {
            BasicHttpBindingService<IFileService> service
                                = new BasicHttpBindingService<IFileService>(Framework.Module.WCFCommon.FileServiceURL);
            service.BasicHttpBindingProperty.MessageEncoding = WSMessageEncoding.Mtom;
            service.BasicHttpBindingProperty.TransferMode = TransferMode.Streamed;
            service.BasicHttpBindingProperty.MaxBufferPoolSize = 2147483647;
            service.BasicHttpBindingProperty.MaxBufferSize = 2147483647;
            service.BasicHttpBindingProperty.MaxReceivedMessageSize = 2147483647;
      
            service.BasicHttpBindingProperty.ReaderQuotas.MaxDepth = 2147483647;
            service.BasicHttpBindingProperty.ReaderQuotas.MaxArrayLength = 2147483647;
            service.BasicHttpBindingProperty.ReaderQuotas.MaxBytesPerRead = 2147483647;
            service.BasicHttpBindingProperty.ReaderQuotas.MaxStringContentLength = 2147483647;
            service.BasicHttpBindingProperty.ReaderQuotas.MaxNameTableCharCount = 2147483647;

            return service.CreateProxy();
        }

서버 web.config

    <bindings>
      <basicHttpBinding>
        <binding name="baseBasicHttpBinding" closeTimeout="00:10:00"
          openTimeout="00:50:00" receiveTimeout="01:50:00" sendTimeout="00:50:00"
          maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
          transferMode="Streamed" messageEncoding="Mtom">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
      </basicHttpBinding>
    </bindings>
 <services>
      <service name="KAI.CIM.WebService.FileService">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="baseBasicHttpBinding"
          contract="KAI.CIM.Framework.Contract.IFileService" />
        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
      </service>
    </services>

 

http://msdn.microsoft.com/ko-kr/library/aa395209(v=vs.110).aspx

* MTOM은 SOAP 메시지와 함께 큰 이진 첨부 파일을 원시 바이트로 전송함으로써 더 작은 크기의 메시지를 허용하는 메커니즘입니다.

 

http://msdn.microsoft.com/ko-kr/library/76dt1k3h.aspx

WCF 디버깅 방법

http://blogs.msdn.com/b/carlosfigueira/archive/2011/08/02/wcf-extensibility-system-diagnostic-tracing.aspx

 

 

 

위에 설명된 내용을  WCF 서비스 구성 편집기에 들어가면 간단하게 설정 할 수 있습니다.

image

 

 

image

 

image

지연된 콘텐츠 로드(WCF Data Services)

http://msdn.microsoft.com/ko-kr/library/ee358709.aspx

실버라이트에서의 사용법 : http://msdn.microsoft.com/ko-kr/blogvisualizer/ee681614

 

여기서는 WCF가 기본적으로 한번에 받을 수 있는 양을 제한 하기 때문에 페이징을 이용해서 데이터를 가져옵니다.
(예를 들어 한번에 1만건의 데이터를 가지고 올수없으니 100개씩 쪼개서 로컬에서 합칩니다)

프로젝트 구성

edmx 는 NorthwindEntities를 구성하였습니다.

Model1.edmx

 

WcfDataService1.svc

SetEntitySetPageSize : http://msdn.microsoft.com/ko-kr/library/system.data.services.dataserviceconfiguration.setentitysetpagesize.aspx

 

namespace WcfService1
{
    public class WcfDataService1 : DataService<NorthwindEntities>
    {
        // 이 메서드는 서비스 전반적인 정책을 초기화하는 데 한 번만 호출됩니다.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: 규칙을 설정하여 어떤 엔터티 집합과 서비스 작업을 표시할 수 있고 업데이트할 수 있는지 등을 표시합니다.
            // 예제:
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            config.SetEntitySetPageSize("Customers", 8); //Customers 데이터를 8개씩 끊어서 가져옵니다.
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

페이징으로 불러오기

MainWindow.xaml.cs


namespace WebServicePager
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {


        public MainWindow()
        {
            InitializeComponent();
            ServiceReference1.NorthwindEntities context = new ServiceReference1.NorthwindEntities(new Uri("http://localhost:50764/WcfDataService1.svc"));


            //일반적으로 가져오는 방식
            //var query = from c in ne.Customers
            //            select c;
            //this.dataGrid1.ItemsSource = query.ToList();


            //여기서부터는 페이징을 통해서 가져오는방법
            List<ServiceReference1.Customers> pagerCustomer = new List<ServiceReference1.Customers>();
            DataServiceQueryContinuation<ServiceReference1.Customers> token = null;
            int pageCount = 0;
            try
            {
 
                QueryOperationResponse<ServiceReference1.Customers> response =
                    context.Customers.Execute() as QueryOperationResponse<ServiceReference1.Customers>;

                do
                {
                    Console.WriteLine("Page {0}:", pageCount++);
                    if (token != null)
                    {
         
                        response = context.Execute<ServiceReference1.Customers>(token)
                            as QueryOperationResponse<ServiceReference1.Customers>;
                    }
                    pagerCustomer.AddRange(response.ToList());
                }
                while ((token = response.GetContinuation()) != null);

                this.dataGrid1.ItemsSource = pagerCustomer;
            }
            catch (DataServiceQueryException ex)
            {
                throw new ApplicationException(
                    "An error occurred during query execution.", ex);
            }

        }
    }
}
좀더 쉽게 사용하기
제가 만든거기때문에 최적화 안됨( 발빼기 ㅋ)
 
            //여기서부터는 페이징을 통해서 가져오는방법
            PagerService.NorthwindEntities __ContextPager 
                = new PagerService.NorthwindEntities(new Uri("http://localhost:56323/PagerWcfDataService.svc"));
            DataServicePager<PagerService.Categories> pager 
                = new DataServicePager<PagerService.Categories>(this.__ContextPager);
 
            List<PagerService.Categories> list = pager.List();
            this.dataGrid1.ItemsSource = list;
            this.label1.Content = list.Count.ToString();

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;

namespace 테스트용
{
    /// 
    /// WCF 서비스에서 config.SetEntitySetPageSize("Customers", 10); 
    /// 설정되있을때 페이징으로 가지고 오는 메소드 입니다.
    /// 
    /// WCF DataSerive애 속해있는 테이블 명
    public class DataServicePager where T : class
    {
        private string __Table { set; get; }
        private Type __Type;
        
        DataServiceQueryContinuation token = null;
        int pageCount = 0;
        private DataServiceContext __DataServiceContext;

        public DataServicePager(DataServiceContext dataServiceContext)
        {
            this.__Type = typeof(T);
            this.__DataServiceContext = dataServiceContext;
        }

        public List List()
        {
            List __PagerObjectList = new List();
            try
            {
                Uri uri = new Uri(string.Format("{0}/{1}", __DataServiceContext.BaseUri.ToString(), this.__Type.Name));
                QueryOperationResponse response = __DataServiceContext.Execute(uri) as QueryOperationResponse;
                do
                {
                    Console.WriteLine("Page {0}:", pageCount++);
                    if (token != null)
                    {
                        response = __DataServiceContext.Execute(token)
                            as QueryOperationResponse;
                    }

                    __PagerObjectList.AddRange(response.ToList());
                }
                while ((token = response.GetContinuation()) != null);
            }
            catch (Exception ex)
            {
                throw new Exception("Ge tData ServiceList Error :" + ex.Message);
            }
            return   __PagerObjectList.ToList();
        }
    }
}


 

image

위와같이 나온다.

 

클래스위에다가 속성추가하면 오류 해결

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

image

추가중….

var urlString = "http://localhost:19000/InsaDataService.svc/UploadFile";

var webClient = new WebClient();

Debug.WriteLine("업로드 시작");
webClient.UploadFileAsync(new Uri(urlString), "POST", @"C:\temp\img.JPG");
webClient.UploadProgressChanged += new UploadProgressChangedEventHandler(webClient_UploadProgressChanged);
webClient.UploadFileCompleted += new UploadFileCompletedEventHandler(webClient_UploadFileCompleted);

 

void webClient_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

void webClient_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
    if (e.Error != null)
    {
        MessageBox.Show(e.Error.Message);

        return;
    }
    string reply = System.Text.Encoding.UTF8.GetString(e.Result);
    XElement config = XElement.Parse(reply);
    string result = config.Value;


  
}

 

void webClient_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)의 e.Result 결과값은 바이트로 넘어온다.

image

 

string reply = System.Text.Encoding.UTF8.GetString(e.Result); //문자열로 변환하면

아래와 같이 나온다. 나는 aefb3d66-b35d-4c99-b566-17e4f47f923a 이 값만 필요한데…..

image

 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<UploadFile xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">파일업로드 완료</UploadFile>

 

값 읽어오기

string reply = System.Text.Encoding.UTF8.GetString(e.Result);
XElement config = XElement.Parse(reply);
string result = config.Value;
result 의 결과 값 : aefb3d66-b35d-4c99-b566-17e4f47f923a

 

익명 인증확인

image

 

IIS 폴더 자체에 권한이 주어져 있는지 확인해보자

image

 

WCF Data Services 퀵 스타트

http://msdn.microsoft.com/ko-kr/library/cc668796.aspx

 

필수 구성 요소


이 퀵 스타트를 수행하려면 다음 구성 요소를 설치해야 합니다.

  • Visual Studio 2010

  • Microsoft SQL Server의 인스턴스. 여기에는 Visual Studio의 기본 설치에 들어 있는 SQL Server Express가 포함됩니다.

  • Northwind 샘플 데이터베이스. 이 샘플 데이터베이스를 다운로드하려면 Sample Databases for SQL Server 다운로드 페이지를 참조하십시오.

WCF Data Services 퀵 스타트 작업


데이터 서비스 만들기

ASP.NET 응용 프로그램과 데이터 모델을 정의하고, 데이터 서비스를 만들고, 리소스에 액세스할 수 있도록 합니다.

웹 브라우저에서 서비스 액세스(WCF Data Services 퀵 스타트)

Visual Studio에서 서비스를 시작하고 웹 브라우저를 통해 HTTP GET 요청을 노출된 피드로 전송하여 서비스에 액세스합니다.

.NET Framework 클라이언트 응용 프로그램 만들기(WCF Data Services 퀵 스타트)

WPF 클라이언트 응용 프로그램을 만들어 OData 피드를 사용하고, 데이터를 Windows 컨트롤에 바인딩하고, 바인딩된 컨트롤의 데이터를 변경한 후 변경 내용을 데이터 서비스로 다시 보냅니다.

IIS에서 실행되는 WCF Data Services 개발

http://msdn.microsoft.com/ko-kr/library/dd728288.aspx

 

이 항목에서는 WCF 데이터 서비스를 사용하여 IIS(인터넷 정보 서비스)에서 실행되는 ASP.NET 웹 응용 프로그램이 호스팅하는 Northwind 샘플 데이터베이스를 기반으로 데이터 서비스를 만드는 방법을 보여 줍니다.ASP.NET Development Server에서 실행되는 ASP.NET 웹 응용 프로그램으로 동일한 Northwind 데이터 서비스를 만드는 방법의 예제는 WCF Data Services 퀵 스타트를 참조하십시오.

 

  1. Visual Studio의 파일 메뉴에서 새로 만들기를 선택한 다음 프로젝트를 선택합니다.

  2. 새 프로젝트 대화 상자에서 Visual Basic 또는 Visual C#을 프로그래밍 언어로 선택합니다.

  3. 템플릿 창에서 ASP.NET 웹 응용 프로그램을 선택합니다.참고: Visual Studio Web Developer를 사용하는 경우 새 웹 응용 프로그램 대신 새 웹 사이트를 만들어야 합니다.

  4. 프로젝트 이름으로 NorthwindService를 입력합니다.

  5. 확인을 클릭합니다.

  6. 프로젝트 메뉴에서 NorthwindService 속성을 선택합니다.

  7. 웹 탭을 선택한 다음 로컬 IIS 웹 서버 사용을 선택합니다.

  8. 가상 디렉터리 만들기를 클릭한 다음 확인을 클릭합니다.

  9. 명령 프롬프트에서 다음 명령을 실행합니다.

    복사

    "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -i

    이렇게 하면 WCF(Windows Communication Foundation)가 컴퓨터에서 등록됩니다.

  10. SQL Server Management Studio 또는 sqlcmd.exe 유틸리티를 사용하여 Northwind 데이터베이스가 연결된 SQL Server 인스턴스에 대해 다음 Transact-SQL 명령을 실행합니다.

    복사

    CREATE LOGIN [NT AUTHORITY\NETWORK SERVICE] FROM WINDOWS;
    GO 

    이렇게 하면 IIS를 실행하는 데 사용되는 Windows 계정에 대한 로그인이 SQL Server 인스턴스에서 만들어집니다.이에 따라 IIS에서 SQL Server 인스턴스에 연결할 수 있습니다.

  11. Northwind 데이터베이스가 연결된 상태에서 다음 Transact-SQL 명령을 실행합니다.

    복사

    USE Northwind
    GO
    CREATE USER [NT AUTHORITY\NETWORK SERVICE] 
    FOR LOGIN [NT AUTHORITY\NETWORK SERVICE] WITH DEFAULT_SCHEMA=[dbo];
    GO
    ALTER LOGIN [NT AUTHORITY\NETWORK SERVICE] 
    WITH DEFAULT_DATABASE=[Northwind]; 
    GO
    EXEC sp_addrolemember 'db_datareader', 'NT AUTHORITY\NETWORK SERVICE'
    GO
    EXEC sp_addrolemember 'db_datawriter', 'NT AUTHORITY\NETWORK SERVICE'
    GO 

    이렇게 하면 새 로그인에 권한이 부여되어 IIS에서 Northwind 데이터베이스에 있는 데이터를 읽고 Northwind 데이터베이스에 데이터를 쓸 수 있습니다.

http://msdn.microsoft.com/en-us/library/dd756368.aspx

 

With the WCF Data Services  client libraries, you can create, update, and delete entity data in a data service by performing equivalent actions on objects in the DataServiceContext. For more information, see Updating the Data Service (WCF Data Services).

The example in this topic uses the Northwind sample data service and autogenerated client data service classes. This service and the client data classes are created when you complete the WCF Data Services quickstart.

Example

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri);

// Create the new product.
Product newProduct =
    Product.CreateProduct(0, "White Tea - loose", false);

// Set property values.
newProduct.QuantityPerUnit = "120gm bags";
newProduct.ReorderLevel = 5;
newProduct.UnitPrice = 5.2M;

try
{
    // Add the new product to the Products entity set.
    context.AddToProducts(newProduct);

    // Send the insert to the data service.
    context.SaveChanges();

    Console.WriteLine("New product added with ID {0}.", newProduct.ProductID);
}
catch (DataServiceRequestException ex)
{
    throw new ApplicationException(
        "An error occurred when saving changes.", ex);
}

 

The following example retrieves and modifies an existing object and then calls the UpdateObject method on the DataServiceContext to mark the item in the context as updated. An HTTP MERGE message is sent to the data service when the SaveChanges method is called.

 

string customerId = "ALFKI";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri);

// Get a customer to modify using the supplied ID.
var customerToChange = (from customer in context.Customers
                        where customer.CustomerID == customerId
                        select customer).Single();
 
// Change some property values.
customerToChange.CompanyName = "Alfreds Futterkiste";
customerToChange.ContactName = "Maria Anders";
customerToChange.ContactTitle = "Sales Representative";

try
{
    // Mark the customer as updated.
    context.UpdateObject(customerToChange);

    // Send the update to the data service.
    context.SaveChanges();
}
catch (DataServiceRequestException  ex)
{
    throw new ApplicationException(
        "An error occurred when saving changes.", ex);
}

 

 

The following example calls the DeleteObject method on the DataServiceContext to mark the item in the context as deleted. An HTTP DELETE message is sent to the data service when the SaveChanges method is called.

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri);

try
{
    // Get the product to delete, by product ID.
    var deletedProduct = (from product in context.Products
                          where product.ProductID == productID
                          select product).Single();

    // Mark the product for deletion.    
    context.DeleteObject(deletedProduct);

    // Send the delete to the data service.
    context.SaveChanges();
}
// Handle the error that occurs when the delete operation fails,
// which can happen when there are entities with existing 
// relationships to the product being deleted.
catch (DataServiceRequestException ex)
{
    throw new ApplicationException(
        "An error occurred when saving changes.", ex);
}

 

The following example creates a new object instance and then calls the AddRelatedObject method on the DataServiceContext to create the item in the context along with the link to the related order. An HTTP POST message is sent to the data service when the SaveChanges method is called.

int productId = 25;
string customerId = "ALFKI";

Order_Detail newItem = null;

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri);

try
{
    // Get the specific product.
    var selectedProduct = (from product in context.Products
                           where product.ProductID == productId
                           select product).Single();

    // Get the specific customer.
    var cust = (from customer in context.Customers.Expand("Orders")
                where customer.CustomerID == customerId
                select customer).Single();

    // Get the first order. 
    Order order = cust.Orders.FirstOrDefault();

    // Create a new order detail for the specific product.
    newItem = Order_Detail.CreateOrder_Detail(
        order.OrderID, selectedProduct.ProductID, 10, 5, 0);

    // Add the new item with a link to the related order.
    context.AddRelatedObject(order, "Order_Details", newItem);
    context.SetLink(newItem, "Order", order);

    // Since the item is now tracked by the context,
    // set just the link to the related product.
    context.AddLink(selectedProduct, "Order_Details", newItem);
    context.SetLink(newItem, "Product", selectedProduct);

    // Add the new order detail to the collection, and
    // set the reference to the product.
    order.Order_Details.Add(newItem);
    newItem.Order = order;
    newItem.Product = selectedProduct;
   
    // Send the inserts to the data service.
    context.SaveChanges();
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException(
        "An error occurred when saving changes.", ex);
}

// Handle any errors that may occur during insert, such as 
// a constraint violation.
catch (DataServiceRequestException ex)
{
    throw new ApplicationException(
        "An error occurred when saving changes.", ex);
}

 

참고 URL : http://msdn.microsoft.com/ko-kr/library/dd756369.aspx

입력할떈 명령 프롬프트에서 줄 바꿈 없이 다음 명령을 실행합니다.

 

"%windir%\Microsoft.NET\Framework\v3.5\DataSvcUtil.exe"

 

일반도스창(?) 에서 하면 DataSvcUtil 실행안된다 Path에 안잡혀있다.

image

image

비주얼스튜디오 명령프로프트에서 실행하면됩니다.

 

데이터 바인딩을 지원하는 C# 클래스를 생성하려면

"%windir%\Microsoft.NET\Framework\v3.5\DataSvcUtil.exe" /dataservicecollection 
/version:2.0 /language:CSharp /out:Northwind.cs /uri:http://localhost:12345/Northwind.svc
 

서비스 URI를 기반으로 하여 C# 클래스를 생성하려면

"%windir%\Microsoft.NET\Framework\v3.5\DataSvcUtil.exe" /language:CSharp 
/out:northwind.cs /uri:http://localhost:12345/Northwind.svc
 

image

image

데이터 서비스가 잘 뜨는지 확인했으면 아래처럼 실행

image

 

image

파일이 만들어져 있다. ㅋ

에러:

XML 데이터를 읽는 동안 최대 배열 길이 할당량(16384)을 초과했습니다. XML 판독기를 만들 때 사용되는 XmlDictionaryReaderQuotas 개체에서 MaxArrayLength 속성을 변경하여 이 할당량을 늘릴 수 있습니다.

 

해결방법

WCF 구성편집 클릭

자기가 사용 하고 있는 바인딩  선택

ReaderQuotas  값을 최대값(2147483647)으로 설정해준다.



코드에서 설정방법

            _EndpointAddress = new EndpointAddress(BindingUrl);
            
            _WSHttpBinding = new System.ServiceModel.WSHttpBinding();
            _WSHttpBinding.MaxReceivedMessageSize = 2147483647;
            _WSHttpBinding.MaxBufferPoolSize = 2147483647;
            
            _WSHttpBinding.ReceiveTimeout = TimeSpan.MaxValue;
            _WSHttpBinding.OpenTimeout = TimeSpan.MaxValue;
            _WSHttpBinding.SendTimeout = TimeSpan.MaxValue;
            _WSHttpBinding.CloseTimeout = TimeSpan.MaxValue;
            _WSHttpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
            _WSHttpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
            _WSHttpBinding.ReaderQuotas.MaxArrayLength = 2147483647;


아래 추가 해줘야됨

image

+ Recent posts