https://schwabencode.com/blog/2018/01/30/ASP-NET-Core-ModelState-Validation-Filter

 

ASP.NET Core ModelState Validation Filter

During my code review sessions I see a lot of duplicate for the ModelState validation like public async Task<IActionResult> AddAsync(PersonAddS

schwabencode.com

액션 필터를 직접 등록 하거나.. 속성을 사용해서 부분 적용 하는 부분 또는 입력 모델에 값을 체크 하는 팁까지..

볼만한 내용이 있음. 다만 아직 api 작성시 적극 사용하지는 않음..

(이름이 ModelState.. mvc 용인가?)

Posted by ngcbbs
,

image = new Image();
RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);

음! 이건 버전이나 그런것은 모르겠고 일단 설정하는 모드가 있는듯!

BitmapScalingMode 의 멤버들.. msdn 뽑아옴~

Member nameDescription
UnspecifiedUse the default bitmap scaling mode, which is Linear.
LowQualityUse bilinear bitmap scaling, which is faster than HighQuality mode, but produces lower quality output. The LowQualitymode is the same as the Linear mode.
HighQualityUse high quality bitmap scaling, which is slower than LowQuality mode, but produces higher quality output. TheHighQuality mode is the same as the Fant mode.
LinearUse linear bitmap scaling, which is faster than HighQuality mode, but produces lower quality output.
FantUse very high quality Fant bitmap scaling, which is slower than all other bitmap scaling modes, but produces higher quality output.
NearestNeighborUse nearest-neighbor bitmap scaling, which provides performance benefits over LowQuality mode when the software rasterizer is used. This mode is often used to magnify a bitmap.

Posted by ngcbbs
,

wxWidgets 을 이용해서 만들었던 간단한 이미지 체크툴을 C# WPF 으로 만들어 보기 위해서 구글링을 통해 알아본 해당 코드들... 음 이미지 동일 여부 판단 하는 부분은 빠져 있지만 다른 잡다한 코드가 많이 있던 wxWidgets + C/C++ 보다는.. 간결한 코드가 나온다 ;ㅂ; (.NET 3.5 가 필요하지..) 농담 아니고 정말-ㅅ- 간단하게 처리된다!;;


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace WpfEqMask
{
    /// 
    /// Window1.xaml에 대한 상호 작용 논리
    /// 
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        // 이미지 처리방법 관련 (외국) 글.
        // http://10rem.net/blog/2010/03/24/rotating-and-cropping-an-image-in-wpf

        // http://stackoverflow.com/questions/4402828/wpf-cut-and-save-image
        public void MakeRectImage(BitmapImage srcBitmap, int x, int y, int width, int height, string filename)
        {
            TransformGroup transformGroup = new TransformGroup();
            /*
            RotateTransform rotateTransform = new RotateTransform(angle);
            rotateTransform.CenterX = sourceImage.PixelWidth / 2.0;
            rotateTransform.CenterY = sourceImage.PixelHeight / 2.0;
            transformGroup.Children.Add(rotateTransform);
            */
            TranslateTransform translateTransform = new TranslateTransform();
            translateTransform.X = -x;
            translateTransform.Y = -y;
            transformGroup.Children.Add(translateTransform);

            DrawingVisual vis = new DrawingVisual();
            DrawingContext cont = vis.RenderOpen();
            cont.PushTransform(transformGroup);
            cont.DrawImage(srcBitmap, new Rect(new Size(srcBitmap.PixelWidth, srcBitmap.PixelHeight)));
            cont.Close();

            RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
            rtb.Render(vis);

            FileStream stream = new FileStream(filename, FileMode.Create);
            
            PngBitmapEncoder encoder = new PngBitmapEncoder(); // png 포멧으로 저장.
            encoder.Frames.Add(BitmapFrame.Create(rtb));
            encoder.Save(stream);
            stream.Close();
        }

        private void OnDrop(object sender, DragEventArgs e)
        {
            string[] dropFileList = e.Data.GetData(DataFormats.FileDrop, true) as string[];

            string result = result = "Drop File List\n";
            foreach (string file in dropFileList)
            {
                result += file;
                result += "\n";

                string[] bmpFiles = Directory.GetFiles(file, "*.bmp", SearchOption.AllDirectories);
                if (bmpFiles.Length > 0)
                {
                    result += "---------------------\n";
                    result += "폴더내 bmp 목록.\n";

                    foreach (string bmpFile in bmpFiles)
                    {
                        // MyCanvas 에 추가~
                        Image img = new Image();
                        BitmapImage src = new BitmapImage();
                        src.BeginInit();
                        src.UriSource = new System.Uri(bmpFile, System.UriKind.Relative);
                        src.EndInit();
                        img.Source = src;
                        img.Stretch = Stretch.Uniform;

                        try
                        {
                            string rectname = bmpFile;
                            rectname += ".rect.bmp";
                            MakeRectImage(src, 10, 10, 32, 32, rectname);
                            
                            img.Width = src.Width;
                            img.Height = src.Height;
                            MyCanvas.Children.Add(img);
                        }
                        catch (Exception ec)
                        {
                            MessageBox.Show("예외발생" + ec.ToString());
                        }

                        result += bmpFile;
                        result += "\n";

                        MessageBox.Show("로딩 잘되네");
                    }
                }
            }

            MessageBox.Show(result, "결과");
        }
    }
}


Posted by ngcbbs
,

어제에 이은 C# 공부중 예제들~ 추상메소드, 인터페이스, 보호클래스(상속불가), 모든 클래스들은 c#에 의해서 System.Object 를 상속, 프로퍼티(별칭 프로퍼티를 통해 데이터에 접근할 수 있도록 하는것 읽기/쓰기 제어), 인덱서(객체 자체에 [] 연산자를 지정해 해당 데이터에 접근할 수 있도록하는것. 대략 읽기만 가능?)



using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
 * 추상 메소드! 그리고 인터페이스.
 */
namespace test3
{
    // 추상메소드 : 파생되는 클레스에 특정 메소드를 만들도록 강요할 수 있음.
    abstract class Animal
    {
        abstract public void Walk();
    }

    class Person : Animal
    {
        public override void Walk()
        {
            System.Console.WriteLine("사람 걷다.");
        }
    }

    class Robot : Animal
    {
        override public void Walk() // override 키워드의 순서가 참 거슬렸었음. 이렇게도 되나?(된다)
        {
            System.Console.WriteLine("로봇 걷다.");
        }
    }

    // 인터페이스 : 클래스는 다중상속 불가. 인터페이스를 통해 1개이상 상속이 가능하다고 함.
    interface IAnimal
    {
        void Walk();
    }

    interface IUserSkill
    {
        void Dance();
    }

    class Person2 : IAnimal, IUserSkill // 1개 이상이라고 하는게 요런걸 말하는건가!?
    {
        public void Walk()
        {
            System.Console.WriteLine("사람2 걷다.");
        }

        public void Dance()
        {
            System.Console.WriteLine("사람2 춤춘다.");
        }
    }

    class Person3 : IAnimal
    {
        public void Walk()
        {
            System.Console.WriteLine("사람3 걷다.");
        }
    }

    // 보호클래스 : sealed 키워드가 적용되면 어떤 클래스도 SealAnimal 을 상송받을 수 없다고 하네요.
    sealed class SealAnimal
    {
        public string Name;
        public void Walk()
        {
            System.Console.WriteLine("보호된(?!) 동물 클래스 걷다.");
        }
    }

    // 모든 c# 의 클래스는 System.Object 클래스를 상속 받는다.
    // System.Object 의 주요 메소드.
    // > Equals() : 객체가 같은지 판단.
    // > GetHashCode() : 고유 해시 반환.
    // > GetType() : 타입 반환.
    // > ToString() : 객체 문자열 반환.
    // > Finalize() : 객체 소멸전에 작업할 코드 수행.
    // > MemberwiseClone() : 객체의 복사본을 만듬.

    // 프로퍼티 : 이를 통해서 클래스의 멤버변수에 대해서 읽기/쓰기 속성을 지정할 수 있다.
    // 멤버 변수가 private 로 선언되었을지라도..
    class Ayo
    {
        private int nData;
        private ArrayList aData = new ArrayList();

        public void push_back(int value)
        {
            aData.Add(value);
        }

        public int Data // 이게 프로퍼티라고 한다. 음... 뭔가 타이핑이 더 많아 진거 같기도 하고 생략된거 같기도 하다.
        {
            get { return nData; }
            set { nData = value; }
        }

        // 인덱서 aData[0] 이런식이 된다는것인듯! 좋아 보이긴 한다.
        public int this[int index]
        {
            get { return (int)aData[index]; }
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            // 추상메소드 테스트
            Person p = new Person();
            Robot r = new Robot();

            p.Walk();
            r.Walk();

            // 인터페이스 테스트
            Person2 p2 = new Person2();
            Person3 p3 = new Person3();
            p2.Walk();
            p3.Walk();
            p2.Dance();

            // 배열!
            Person3[] p3array = new Person3[2];
            p3array[0] = p3;
            p3array[1] = new Person3();

            for (int i = 0; i < 2; ++i)
            {
                p3array[i].Walk();
            }

            foreach (Person3 it in p3array) // 익숙해져 보자!~
            {
                it.Walk();
            }

            Ayo aa2 = new Ayo(); // 항상 생성해 줘야하는건 C/C++ 에 비해서 성가신거 같다. 아직까진...
            aa2.Data = 32;
            System.Console.WriteLine("nData 의 값은? " + aa2.Data);

            aa2.push_back(10);
            aa2.push_back(15);
            aa2.push_back(20);

            System.Console.WriteLine("0 = " + aa2[0]);
            System.Console.WriteLine("1 = " + aa2[1]);
            System.Console.WriteLine("2 = " + aa2[2]);
        }
    }
}
Posted by ngcbbs
,

게임코디 연제 강좌로 올라온 온라인 공개 책(문서)를 보면서 작성한것...

위임과 C/C++ 에서의 상속과 C#의 상속이 어떻게 다른지 살펴볼 수 있는 예제 코드... 공개 책(문서)에는 서로 따로 표시하고 있었는데 그다지 나눠서 보지 않아도 너무 간결한게 좋아 보인다. (사실 전에는 뭐여 이상한 키워드가 마구 생겼잖아 했었지..)


using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using System.Text;
using System.IO;

namespace ToolboxTestApp3
{
    class MissileTurret
    {
        public string Name;
        public GameWorld refGameWorld;
        public MissileTurret(GameWorld world)
        {
            refGameWorld = world;
            refGameWorld.dg_object += new GameWorld.dg_FindEnemy(FindEnemy); // 위임(다중)
        }

        public virtual void FindEnemy()
        {
            System.Console.WriteLine("미사일터렛({0}) 적발견!!", Name);
        }

        public virtual void Update()
        {
            System.Console.WriteLine("미사일터렛({0})", Name);
        }
    }

    class JustTurret : MissileTurret
    {
        public JustTurret(GameWorld world)
            : base(world) // C/C++ 에서는 부모 CLASS 의 이름을 써줘야 했지만 base 로 ok.
        {
        }

        public override void FindEnemy()
        {
            System.Console.WriteLine("터렛({0}) 적발견!!", Name);
        }

        public override void Update()
        {
            // 부모의 함수를 호출하고 싶다면 base.Update() 를 호출하면 됨.
            System.Console.WriteLine("터렛({0})", Name);
        }
    }

    class GameWorld
    {
        public ArrayList gameObjects = new ArrayList();

        // 위임 선언
        public delegate void dg_FindEnemy();

        // 위임객체
        public dg_FindEnemy dg_object;

        public void Update()
        {
            int nCount = gameObjects.Count;
            for (int i = 0; i < nCount; ++i)
            {
                ((MissileTurret)gameObjects[i]).Update();
            }

            //////////////////////////////////////////////////////////////////////////
            Random r = new Random();
            int nRet = r.Next(100);
            if (nRet > 50)
            {
                if (dg_object != null)
                {
                    System.Console.WriteLine("Subject 에 연결된 Observer 개수: " + dg_object.GetInvocationList().Length);
                    dg_object();
                }
            }
            else
            {
                System.Console.WriteLine("랜덤숫자~: " + nRet);
            }
        }
    }

    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            GameWorld world = new GameWorld();

            MissileTurret turret1 = new MissileTurret(world);
            turret1.Name = "터렛1";

            JustTurret turret2 = new JustTurret(world);
            turret2.Name = "터렛2";

            MissileTurret turret3 = new MissileTurret(world);
            turret3.Name = "터렛3";

            world.gameObjects.Add(turret1);
            world.gameObjects.Add(turret2);
            world.gameObjects.Add(turret3);

            bool bLoop = true;
            while (bLoop)
            {
                Thread.Sleep(1000);
                System.Console.WriteLine("게임시작~");
                world.Update();
            }
        }
    }
}


Posted by ngcbbs
,

조각코드! C/C++ 에서는 참으로 복잡 시럽게 코딩을 해줘야 했지만.. 이역시 간단하게 처리가 된다. =ㅂ=



using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ToolboxTestApp2
{
    class Program
    {
         static void Main(string[] args)
        {
            DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());
            FileInfo[] filesInfo = dir.GetFiles();
            // for 아 c/c++ 같어~
            for (int i = 0; i < filesInfo.Length; ++i)
            {
                System.Console.WriteLine(filesInfo[i].Name);
            }
            // foreach 사용해서 출력~ 
            foreach (FileInfo each in filesInfo)
            {
                System.Console.WriteLine(each.Name);
            }
        }
    }
}
Posted by ngcbbs
,

간단하게 C/C++ 을 알고 있는 사용자에게 설명하면 함수 포인터 같은녀석! 이라고 이야기 할 수 있겠다.

다만 사용 방법이나 다중 위임의 형태를 C/C++ 에서 구현하기 위해서는 잡다한 코드가 더 추가되어야 하지만 정말 간편하게 다중 위임으로 처리가 가능하다.

delegate 키워드를 사용.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ToolboxTestApp1
{
    class Program
    {
        // 위임이 무엇인고??
        public delegate int Printer(string msg); // 함수 포인터 처럼 함수 바디는 필요 없다.

        public static int Printer_My1(string msg)
        {
            System.Console.WriteLine("Printer_My1 = " + msg);
            return 1;
        }

        public static int Printer_My2(string msg)
        {
            System.Console.WriteLine("Printer_My2 = " + msg);
            return 2;
        }

        static void Main(string[] args)
        {
            Printer _printer = new Printer(Printer_My1);
            _printer += new Printer(Printer_My2); // += 연산자를 통해서 다중 위임 처리.

            _printer("한가한가~"); // _printer 에 위임된 프린터가 동작한다.
        }
    }
}


Posted by ngcbbs
,

아주 기초적인 프레임 생성 코드! wxFromBuilder 등에서 기본적인 배치및 이벤트 헨들러 지정을 해도 app 관련 코드는 생성해 주지 않으므로 일단 기본 코드가 있으면 좋다!...


#include "wx/wx.h"

//////////////////////////////////////////////////////////////////////////
// wxWidgets 최신 버전 다운로드
// http://www.wxwidgets.org/downloads/
// Current Stable Release: 2.9.3
// Previous Stable Release: 2.8.12
// * 다운로드 페이지에는 2.9.3 이 최신버전이 아니지만 2.9.3이 최신버전이 맞음.
//   다음 버전은 2.9.4 일것이고 다음은 2.9.5 혹은 3.0 으로 된것이라고 함.
//   3.0 에서는 윈도우 메트로 ui 도 지원할지도 모르겠음.(이건 추측)

//////////////////////////////////////////////////////////////////////////
// 컴파일 할때 설정해 줘야 하는것들 (비주얼 스튜디오 기준)
// * 추가 include 폴더 지정.
//	[wxWidget폴더]/include
//	[wxWidget폴더]/include/msvc
// * 추가 library 폴더 지정.
//	[wxWidget폴더]/lib/vc_lib			<- static lib 로 링크하는 경우.
//  [wxWidget폴더]/lib/vc_dll			<- dynamic dll 로 링크하는 경우. (해당 dll 을 실행파일 경로에 복사해줘야함)

//////////////////////////////////////////////////////////////////////////
// BaseFrame
class CBaseFrame : public wxFrame
{
public:
	CBaseFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title)
	{
		/*
		자식 윈도우의 이벤트 처리는 아래와 같은 형태로 직접 연결.
		// Connect Events
		mGridSizeCombo->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(NGCEditorFrame::OnSelected), NULL, this);
		mGridSizeCombo->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(NGCEditorFrame::OnEnter), NULL, this);
		*/
	}

	virtual ~CBaseFrame() 
	{
		/*
		자식 윈도우 이벤트 연결이 되었다면 윈도우 삭제시 연결 해제 해주자.
		// Disconnect Events
		mGridSizeCombo->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(NGCEditorFrame::OnSelected), NULL, this);
		mGridSizeCombo->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(NGCEditorFrame::OnEnter), NULL, this);
		*/
	}

	void OnSize(wxSizeEvent& event)
	{
		wxFrame::OnSize(event);
	}

	DECLARE_EVENT_TABLE()
};

// CBaseFrame 이벤트 헨들러 지정
BEGIN_EVENT_TABLE(CBaseFrame, wxFrame)
	EVT_SIZE(CBaseFrame::OnSize)
END_EVENT_TABLE()

//////////////////////////////////////////////////////////////////////////
// BaseApp
class CBaseApp : public wxApp
{
public:
	CBaseApp() : pFrame(0) {}

	virtual ~CBaseApp() {}

	bool OnInit()
	{
		if (!wxApp::OnInit())
			return false;

		pFrame = new CBaseFrame(wxT("기본윈도우"));
		pFrame->SetClientSize(640, 480);
		pFrame->Center();
		pFrame->Show();

		SetTopWindow(pFrame);

		return true;
	}

	int OnRun()
	{
		return wxApp::OnRun();
	}

	int OnExit()
	{
		return wxApp::OnExit();
	}

private:
	CBaseFrame* pFrame;

};

// CBaseApp 구현부
IMPLEMENT_APP(CBaseApp)

Posted by ngcbbs
,

다음과 같은 코드를 통해서 확인할 수 있다.



void ErrorMessageBox(DWORD dwError)
{
	LPVOID lpMsg = NULL;
	DWORD dwFormat = FORMAT_MESSAGE_ALLOCATE_BUFFER |
					 FORMAT_MESSAGE_FROM_SYSTEM |
					 FORMAT_MESSAGE_IGNORE_INSERTS;
	DWORD dwLanguage = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);

	if (!FormatMessage(dwFormat, NULL, dwError, dwLanguage, 
		(LPTSTR)&lpMsg, 0, NULL))
	{
		return;
	}

	MessageBox(NULL, (LPCTSTR)lpMsg, L"Error", MB_OK | MB_ICONINFORMATION);
	
	LocalFree(lpMsg);
}


Posted by ngcbbs
,
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

char szComputerName[17] = {0,};
char szUserName[17] = {0,};

void main()
{
	const char* dat_file = "prebuild.dat";
	const char* build_file = "build.h";
	FILE* fp = NULL;
	fp = fopen( dat_file, "rb" );
	if ( NULL == fp )
	{
		int init_build = 0;
		fp = fopen( dat_file, "wb" );
		fwrite(&init_build, sizeof(int), 1, fp);
		fclose( fp );
		fp = fopen( dat_file, "rb" );
	}

	int new_build = 0;
	fread(&new_build, sizeof(int), 1, fp);
	fclose( fp );

	new_build++;

	fp = fopen( dat_file, "wb" );
	fwrite(&new_build, sizeof(int), 1, fp);
	fclose( fp );

	fp = fopen( build_file, "wt" );
	fprintf(fp, "#define __BUILD_COUNT__ %d\n", new_build);
	DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1;		
	::GetComputerName(szComputerName, &nSize);
	::GetUserName(szUserName, &nSize);
	fprintf(fp, "#define __BUILD_COMPUTER__ L\"%s\"\n", szComputerName);
	fprintf(fp, "#define __BUILD_USER__ L\"%s\"\n", szUserName);
	time_t timer;
	struct tm *t;
	timer = time(NULL);
	t = localtime(&timer);
	fprintf(fp, "#define __BUILD_TIME__ L\"%d월 %d일 %d시 %d분\"\n", t->tm_mon+1, t->tm_mday, t->tm_hour+1, t->tm_min);
	fclose(fp);
}
- 개선할 점 : 옵션처리( ansi / unicode / 추가 텍스트 ).
Posted by ngcbbs
,